Version 2.17.0-282.0.dev

Merge commit '94bc01240cfcd47d645f9e8564561afb5b6b74ee' into 'dev'
diff --git a/DEPS b/DEPS
index db1a550..3c0b60d 100644
--- a/DEPS
+++ b/DEPS
@@ -153,7 +153,7 @@
   "source_map_stack_trace_rev": "8eabd96b1811e30a11d3c54c9b4afae4fb72e98f",
   "source_maps-0.9.4_rev": "38524",
   "source_maps_rev": "6499ee3adac8d469e2953e2e8ba4bdb4c2fbef90",
-  "source_span_rev": "dc189b455d823e2919667f6c5dcb41ab7483bce0",
+  "source_span_rev": "8ae724c3e67f5afaacead44e93ff145bfb8775c7",
   "sse_rev": "9084339389eb441d0c0518cddac211a097e78657",
   "stack_trace_rev": "5220580872625ddee41e9ca9a5f3364789b2f0f6",
   "stream_channel_rev": "3fa3e40c75c210d617b8b943b9b8f580e9866a89",
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
index 8ceaad2..fd5c2d1 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
@@ -110,23 +110,30 @@
     if (fileExtension == '.dart' && !unit.isError) {
       final result = unit.result;
       var performanceOperation = OperationPerformanceImpl('<root>');
-      completionPerformance = CompletionPerformance(
-        operation: performanceOperation,
-        path: result.path,
-        content: result.content,
-        offset: offset,
-      );
-      server.performanceStats.completion.add(completionPerformance);
 
-      serverResultsFuture = _getServerDartItems(
-        clientCapabilities,
-        unit.result,
-        completionPerformance,
-        performanceOperation,
-        offset,
-        triggerCharacter,
-        token,
-        maxResults: maxResults,
+      serverResultsFuture = await performanceOperation.runAsync(
+        'request',
+        (performance) async {
+          final thisPerformance = CompletionPerformance(
+            operation: performance,
+            path: result.path,
+            content: result.content,
+            offset: offset,
+          );
+          completionPerformance = thisPerformance;
+          server.performanceStats.completion.add(thisPerformance);
+
+          return _getServerDartItems(
+            clientCapabilities,
+            unit.result,
+            thisPerformance,
+            performanceOperation,
+            offset,
+            triggerCharacter,
+            token,
+            maxResults: maxResults,
+          );
+        },
       );
     } else if (fileExtension == '.yaml') {
       YamlCompletionGenerator? generator;
@@ -285,7 +292,7 @@
     LspClientCapabilities capabilities,
     ResolvedUnitResult unit,
     CompletionPerformance completionPerformance,
-    OperationPerformanceImpl operationPerformance,
+    OperationPerformanceImpl performance,
     int offset,
     String? triggerCharacter,
     CancellationToken token, {
@@ -294,245 +301,239 @@
     final useSuggestionSets =
         suggestFromUnimportedLibraries && capabilities.applyEdit;
 
-    return await operationPerformance.runAsync(
-      'request',
-      (performance) async {
-        final completionRequest = DartCompletionRequest.forResolvedUnit(
-          resolvedUnit: unit,
-          offset: offset,
-          dartdocDirectiveInfo: server.getDartdocDirectiveInfoFor(unit),
-          completionPreference: CompletionPreference.replace,
+    final completionRequest = DartCompletionRequest.forResolvedUnit(
+      resolvedUnit: unit,
+      offset: offset,
+      dartdocDirectiveInfo: server.getDartdocDirectiveInfoFor(unit),
+      completionPreference: CompletionPreference.replace,
+    );
+    final target = completionRequest.target;
+
+    if (triggerCharacter != null) {
+      if (!_triggerCharacterValid(offset, triggerCharacter, target)) {
+        return success(CompletionList(isIncomplete: false, items: []));
+      }
+    }
+
+    Set<ElementKind>? includedElementKinds;
+    Set<String>? includedElementNames;
+    List<IncludedSuggestionRelevanceTag>? includedSuggestionRelevanceTags;
+    if (useSuggestionSets) {
+      includedElementKinds = <ElementKind>{};
+      includedElementNames = <String>{};
+      includedSuggestionRelevanceTags = <IncludedSuggestionRelevanceTag>[];
+    }
+
+    try {
+      var contributor = DartCompletionManager(
+        budget: CompletionBudget(CompletionBudget.defaultDuration),
+        includedElementKinds: includedElementKinds,
+        includedElementNames: includedElementNames,
+        includedSuggestionRelevanceTags: includedSuggestionRelevanceTags,
+      );
+
+      final serverSuggestions2 = await contributor.computeSuggestions(
+        completionRequest,
+        performance,
+      );
+
+      final serverSuggestions = serverSuggestions2.map((serverSuggestion) {
+        return serverSuggestion.build();
+      }).toList();
+
+      final insertLength = _computeInsertLength(
+        offset,
+        completionRequest.replacementOffset,
+        completionRequest.replacementLength,
+      );
+
+      if (token.isCancellationRequested) {
+        return cancelled();
+      }
+
+      /// completeFunctionCalls should be suppressed if the target is an
+      /// invocation that already has an argument list, otherwise we would
+      /// insert dupes.
+      final completeFunctionCalls = _hasExistingArgList(target.entity)
+          ? false
+          : server.clientConfiguration.global.completeFunctionCalls;
+
+      final results = serverSuggestions.map(
+        (item) {
+          var itemReplacementOffset =
+              item.replacementOffset ?? completionRequest.replacementOffset;
+          var itemReplacementLength =
+              item.replacementLength ?? completionRequest.replacementLength;
+          var itemInsertLength = insertLength;
+
+          // Recompute the insert length if it may be affected by the above.
+          if (item.replacementOffset != null ||
+              item.replacementLength != null) {
+            itemInsertLength = _computeInsertLength(
+                offset, itemReplacementOffset, itemInsertLength);
+          }
+
+          // Convert to LSP ranges using the LineInfo.
+          Range? replacementRange = toRange(
+              unit.lineInfo, itemReplacementOffset, itemReplacementLength);
+          Range? insertionRange =
+              toRange(unit.lineInfo, itemReplacementOffset, itemInsertLength);
+
+          return toCompletionItem(
+            capabilities,
+            unit.lineInfo,
+            item,
+            replacementRange: replacementRange,
+            insertionRange: insertionRange,
+            // TODO(dantup): Move commit characters to the main response
+            // and remove from each individual item (to reduce payload size)
+            // once the following change ships (and the Dart VS Code
+            // extension is updated to use it).
+            // https://github.com/microsoft/vscode-languageserver-node/issues/673
+            includeCommitCharacters:
+                server.clientConfiguration.global.previewCommitCharacters,
+            completeFunctionCalls: completeFunctionCalls,
+          );
+        },
+      ).toList();
+
+      // Now compute items in suggestion sets.
+      var includedSuggestionSets = <IncludedSuggestionSet>[];
+      final declarationsTracker = server.declarationsTracker;
+      if (declarationsTracker != null &&
+          includedElementKinds != null &&
+          includedElementNames != null &&
+          includedSuggestionRelevanceTags != null) {
+        computeIncludedSetList(
+          declarationsTracker,
+          completionRequest,
+          includedSuggestionSets,
+          includedElementNames,
         );
-        final target = completionRequest.target;
 
-        if (triggerCharacter != null) {
-          if (!_triggerCharacterValid(offset, triggerCharacter, target)) {
-            return success(CompletionList(isIncomplete: false, items: []));
-          }
-        }
+        // Build a fast lookup for imported symbols so that we can filter out
+        // duplicates.
+        final alreadyImportedSymbols = _buildLookupOfImportedSymbols(unit);
 
-        Set<ElementKind>? includedElementKinds;
-        Set<String>? includedElementNames;
-        List<IncludedSuggestionRelevanceTag>? includedSuggestionRelevanceTags;
-        if (useSuggestionSets) {
-          includedElementKinds = <ElementKind>{};
-          includedElementNames = <String>{};
-          includedSuggestionRelevanceTags = <IncludedSuggestionRelevanceTag>[];
-        }
-
-        try {
-          var contributor = DartCompletionManager(
-            budget: CompletionBudget(CompletionBudget.defaultDuration),
-            includedElementKinds: includedElementKinds,
-            includedElementNames: includedElementNames,
-            includedSuggestionRelevanceTags: includedSuggestionRelevanceTags,
-          );
-
-          final serverSuggestions2 = await contributor.computeSuggestions(
-            completionRequest,
-            performance,
-          );
-
-          final serverSuggestions = serverSuggestions2.map((serverSuggestion) {
-            return serverSuggestion.build();
-          }).toList();
-
-          final insertLength = _computeInsertLength(
-            offset,
-            completionRequest.replacementOffset,
-            completionRequest.replacementLength,
-          );
-
-          if (token.isCancellationRequested) {
-            return cancelled();
+        includedSuggestionSets.forEach((includedSet) {
+          final library = declarationsTracker.getLibrary(includedSet.id);
+          if (library == null) {
+            return;
           }
 
-          /// completeFunctionCalls should be suppressed if the target is an
-          /// invocation that already has an argument list, otherwise we would
-          /// insert dupes.
-          final completeFunctionCalls = _hasExistingArgList(target.entity)
-              ? false
-              : server.clientConfiguration.global.completeFunctionCalls;
+          // Make a fast lookup for tag relevance.
+          final tagBoosts = <String, int>{};
+          includedSuggestionRelevanceTags!
+              .forEach((t) => tagBoosts[t.tag] = t.relevanceBoost);
 
-          final results = serverSuggestions.map(
-            (item) {
-              var itemReplacementOffset =
-                  item.replacementOffset ?? completionRequest.replacementOffset;
-              var itemReplacementLength =
-                  item.replacementLength ?? completionRequest.replacementLength;
-              var itemInsertLength = insertLength;
+          // Only specific types of child declarations should be included.
+          // This list matches what's in _protocolAvailableSuggestion in
+          // the DAS implementation.
+          bool shouldIncludeChild(Declaration child) =>
+              child.kind == DeclarationKind.CONSTRUCTOR ||
+              child.kind == DeclarationKind.ENUM_CONSTANT ||
+              (child.kind == DeclarationKind.GETTER && child.isStatic) ||
+              (child.kind == DeclarationKind.FIELD && child.isStatic);
 
-              // Recompute the insert length if it may be affected by the above.
-              if (item.replacementOffset != null ||
-                  item.replacementLength != null) {
-                itemInsertLength = _computeInsertLength(
-                    offset, itemReplacementOffset, itemInsertLength);
-              }
-
-              // Convert to LSP ranges using the LineInfo.
-              Range? replacementRange = toRange(
-                  unit.lineInfo, itemReplacementOffset, itemReplacementLength);
-              Range? insertionRange = toRange(
-                  unit.lineInfo, itemReplacementOffset, itemInsertLength);
-
-              return toCompletionItem(
-                capabilities,
-                unit.lineInfo,
-                item,
-                replacementRange: replacementRange,
-                insertionRange: insertionRange,
-                // TODO(dantup): Move commit characters to the main response
-                // and remove from each individual item (to reduce payload size)
-                // once the following change ships (and the Dart VS Code
-                // extension is updated to use it).
-                // https://github.com/microsoft/vscode-languageserver-node/issues/673
-                includeCommitCharacters:
-                    server.clientConfiguration.global.previewCommitCharacters,
-                completeFunctionCalls: completeFunctionCalls,
-              );
-            },
-          ).toList();
-
-          // Now compute items in suggestion sets.
-          var includedSuggestionSets = <IncludedSuggestionSet>[];
-          final declarationsTracker = server.declarationsTracker;
-          if (declarationsTracker != null &&
-              includedElementKinds != null &&
-              includedElementNames != null &&
-              includedSuggestionRelevanceTags != null) {
-            computeIncludedSetList(
-              declarationsTracker,
-              completionRequest,
-              includedSuggestionSets,
-              includedElementNames,
-            );
-
-            // Build a fast lookup for imported symbols so that we can filter out
-            // duplicates.
-            final alreadyImportedSymbols = _buildLookupOfImportedSymbols(unit);
-
-            includedSuggestionSets.forEach((includedSet) {
-              final library = declarationsTracker.getLibrary(includedSet.id);
-              if (library == null) {
-                return;
-              }
-
-              // Make a fast lookup for tag relevance.
-              final tagBoosts = <String, int>{};
-              includedSuggestionRelevanceTags!
-                  .forEach((t) => tagBoosts[t.tag] = t.relevanceBoost);
-
-              // Only specific types of child declarations should be included.
-              // This list matches what's in _protocolAvailableSuggestion in
-              // the DAS implementation.
-              bool shouldIncludeChild(Declaration child) =>
-                  child.kind == DeclarationKind.CONSTRUCTOR ||
-                  child.kind == DeclarationKind.ENUM_CONSTANT ||
-                  (child.kind == DeclarationKind.GETTER && child.isStatic) ||
-                  (child.kind == DeclarationKind.FIELD && child.isStatic);
-
-              // Collect declarations and their children.
-              final allDeclarations = library.declarations
-                  .followedBy(library.declarations.expand(
-                      (decl) => decl.children.where(shouldIncludeChild)))
-                  .toList();
-
-              final setResults = allDeclarations
-                  // Filter to only the kinds we should return.
-                  .where((item) => includedElementKinds!
-                      .contains(protocolElementKind(item.kind)))
-                  .where((item) {
-                // Check existing imports to ensure we don't already import
-                // this element (this exact element from its declaring
-                // library, not just something with the same name). If we do
-                // we'll want to skip it.
-                final declaringUri =
-                    item.parent?.locationLibraryUri ?? item.locationLibraryUri!;
-
-                // For enums and named constructors, only the parent enum/class is in
-                // the list of imported symbols so we use the parents name.
-                final nameKey = item.kind == DeclarationKind.ENUM_CONSTANT ||
-                        item.kind == DeclarationKind.CONSTRUCTOR
-                    ? item.parent!.name
-                    : item.name;
-                final key = _createImportedSymbolKey(nameKey, declaringUri);
-                final importingUris = alreadyImportedSymbols[key];
-
-                // Keep it only if:
-                // - no existing imports include it
-                //     (in which case all libraries will be offered as
-                //     auto-imports)
-                // - this is the first imported URI that includes it
-                //     (we don't want to repeat it for each imported library that
-                //     includes it)
-                return importingUris == null ||
-                    importingUris.first == '${library.uri}';
-              }).map((item) => declarationToCompletionItem(
-                        capabilities,
-                        unit.path,
-                        offset,
-                        includedSet,
-                        library,
-                        tagBoosts,
-                        unit.lineInfo,
-                        item,
-                        completionRequest.replacementOffset,
-                        insertLength,
-                        completionRequest.replacementLength,
-                        // TODO(dantup): Move commit characters to the main response
-                        // and remove from each individual item (to reduce payload size)
-                        // once the following change ships (and the Dart VS Code
-                        // extension is updated to use it).
-                        // https://github.com/microsoft/vscode-languageserver-node/issues/673
-                        includeCommitCharacters: server
-                            .clientConfiguration.global.previewCommitCharacters,
-                        completeFunctionCalls: completeFunctionCalls,
-                      ));
-              results.addAll(setResults);
-            });
-          }
-
-          // Add in any snippets.
-          final snippetsEnabled =
-              server.clientConfiguration.forResource(unit.path).enableSnippets;
-          // We can only produce edits with edit builders for files inside
-          // the root, so skip snippets entirely if not.
-          final isEditableFile =
-              unit.session.analysisContext.contextRoot.isAnalyzed(unit.path);
-          if (capabilities.completionSnippets &&
-              snippetsEnabled &&
-              isEditableFile) {
-            results.addAll(await _getDartSnippetItems(
-              clientCapabilities: capabilities,
-              unit: unit,
-              offset: offset,
-              lineInfo: unit.lineInfo,
-            ));
-          }
-
-          // Perform fuzzy matching based on the identifier in front of the caret to
-          // reduce the size of the payload.
-          final fuzzyPattern = completionRequest.targetPrefix;
-          final fuzzyMatcher =
-              FuzzyMatcher(fuzzyPattern, matchStyle: MatchStyle.TEXT);
-
-          final matchingResults = results
-              .where((e) => fuzzyMatcher.score(e.filterText ?? e.label) > 0)
+          // Collect declarations and their children.
+          final allDeclarations = library.declarations
+              .followedBy(library.declarations
+                  .expand((decl) => decl.children.where(shouldIncludeChild)))
               .toList();
 
-          // Transmitted count will be set after combining with plugins.
-          completionPerformance.computedSuggestionCount =
-              matchingResults.length;
+          final setResults = allDeclarations
+              // Filter to only the kinds we should return.
+              .where((item) => includedElementKinds!
+                  .contains(protocolElementKind(item.kind)))
+              .where((item) {
+            // Check existing imports to ensure we don't already import
+            // this element (this exact element from its declaring
+            // library, not just something with the same name). If we do
+            // we'll want to skip it.
+            final declaringUri =
+                item.parent?.locationLibraryUri ?? item.locationLibraryUri!;
 
-          return success(
-              CompletionList(isIncomplete: false, items: matchingResults));
-        } on AbortCompletion {
-          return success(CompletionList(isIncomplete: false, items: []));
-        } on InconsistentAnalysisException {
-          return success(CompletionList(isIncomplete: false, items: []));
-        }
-      },
-    );
+            // For enums and named constructors, only the parent enum/class is in
+            // the list of imported symbols so we use the parents name.
+            final nameKey = item.kind == DeclarationKind.ENUM_CONSTANT ||
+                    item.kind == DeclarationKind.CONSTRUCTOR
+                ? item.parent!.name
+                : item.name;
+            final key = _createImportedSymbolKey(nameKey, declaringUri);
+            final importingUris = alreadyImportedSymbols[key];
+
+            // Keep it only if:
+            // - no existing imports include it
+            //     (in which case all libraries will be offered as
+            //     auto-imports)
+            // - this is the first imported URI that includes it
+            //     (we don't want to repeat it for each imported library that
+            //     includes it)
+            return importingUris == null ||
+                importingUris.first == '${library.uri}';
+          }).map((item) => declarationToCompletionItem(
+                    capabilities,
+                    unit.path,
+                    offset,
+                    includedSet,
+                    library,
+                    tagBoosts,
+                    unit.lineInfo,
+                    item,
+                    completionRequest.replacementOffset,
+                    insertLength,
+                    completionRequest.replacementLength,
+                    // TODO(dantup): Move commit characters to the main response
+                    // and remove from each individual item (to reduce payload size)
+                    // once the following change ships (and the Dart VS Code
+                    // extension is updated to use it).
+                    // https://github.com/microsoft/vscode-languageserver-node/issues/673
+                    includeCommitCharacters: server
+                        .clientConfiguration.global.previewCommitCharacters,
+                    completeFunctionCalls: completeFunctionCalls,
+                  ));
+          results.addAll(setResults);
+        });
+      }
+
+      // Add in any snippets.
+      final snippetsEnabled =
+          server.clientConfiguration.forResource(unit.path).enableSnippets;
+      // We can only produce edits with edit builders for files inside
+      // the root, so skip snippets entirely if not.
+      final isEditableFile =
+          unit.session.analysisContext.contextRoot.isAnalyzed(unit.path);
+      if (capabilities.completionSnippets &&
+          snippetsEnabled &&
+          isEditableFile) {
+        results.addAll(await _getDartSnippetItems(
+          clientCapabilities: capabilities,
+          unit: unit,
+          offset: offset,
+          lineInfo: unit.lineInfo,
+        ));
+      }
+
+      // Perform fuzzy matching based on the identifier in front of the caret to
+      // reduce the size of the payload.
+      final fuzzyPattern = completionRequest.targetPrefix;
+      final fuzzyMatcher =
+          FuzzyMatcher(fuzzyPattern, matchStyle: MatchStyle.TEXT);
+
+      final matchingResults = results
+          .where((e) => fuzzyMatcher.score(e.filterText ?? e.label) > 0)
+          .toList();
+
+      // Transmitted count will be set after combining with plugins.
+      completionPerformance.computedSuggestionCount = matchingResults.length;
+
+      return success(
+          CompletionList(isIncomplete: false, items: matchingResults));
+    } on AbortCompletion {
+      return success(CompletionList(isIncomplete: false, items: []));
+    } on InconsistentAnalysisException {
+      return success(CompletionList(isIncomplete: false, items: []));
+    }
   }
 
   Future<ErrorOr<CompletionList>> _getServerYamlItems(
diff --git a/pkg/analyzer/lib/src/dart/resolver/invocation_inferrer.dart b/pkg/analyzer/lib/src/dart/resolver/invocation_inferrer.dart
index 2904afc..97dad9b 100644
--- a/pkg/analyzer/lib/src/dart/resolver/invocation_inferrer.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/invocation_inferrer.dart
@@ -173,7 +173,7 @@
     } else if (rawType == null || rawType.typeFormals.isEmpty) {
       typeArgumentTypes = const <DartType>[];
     } else {
-      rawType = getFreshTypeParameters(rawType.typeFormals)
+      this.rawType = rawType = getFreshTypeParameters(rawType.typeFormals)
           .applyToFunctionType(rawType);
 
       inferrer = resolver.typeSystem.setupGenericTypeInference(
@@ -193,7 +193,6 @@
     List<EqualityInfo<PromotableElement, DartType>?>? identicalInfo =
         _isIdentical ? [] : null;
     var deferredClosures = _visitArguments(
-        rawType: rawType,
         identicalInfo: identicalInfo,
         substitution: substitution,
         inferrer: inferrer);
@@ -206,7 +205,6 @@
               rawType!.typeFormals, inferrer.partialInfer());
         }
         _resolveDeferredClosures(
-            rawType: rawType,
             deferredClosures: stage,
             identicalInfo: identicalInfo,
             substitution: substitution,
@@ -382,7 +380,7 @@
   final ResolverVisitor resolver;
   final Node node;
   final ArgumentListImpl argumentList;
-  final FunctionType? rawType;
+  FunctionType? rawType;
   final DartType? contextType;
   final List<WhyNotPromotedGetter> whyNotPromotedList;
 
@@ -403,10 +401,9 @@
 
   /// Performs type inference on the invocation expression.
   void resolveInvocation() {
-    var deferredClosures = _visitArguments(rawType: rawType);
+    var deferredClosures = _visitArguments();
     if (deferredClosures != null) {
-      _resolveDeferredClosures(
-          rawType: rawType, deferredClosures: deferredClosures);
+      _resolveDeferredClosures(deferredClosures: deferredClosures);
     }
   }
 
@@ -429,8 +426,7 @@
 
   /// Resolves any closures that were deferred by [_visitArguments].
   void _resolveDeferredClosures(
-      {required FunctionType? rawType,
-      required Iterable<_DeferredClosure> deferredClosures,
+      {required Iterable<_DeferredClosure> deferredClosures,
       List<EqualityInfo<PromotableElement, DartType>?>? identicalInfo,
       Substitution? substitution,
       GenericInferrer? inferrer}) {
@@ -465,8 +461,7 @@
   /// be deferred due to the `inference-update-1` feature, a list of them is
   /// returned.
   List<_DeferredClosure>? _visitArguments(
-      {required FunctionType? rawType,
-      List<EqualityInfo<PromotableElement, DartType>?>? identicalInfo,
+      {List<EqualityInfo<PromotableElement, DartType>?>? identicalInfo,
       Substitution? substitution,
       GenericInferrer? inferrer}) {
     assert(whyNotPromotedList.isEmpty);
diff --git a/pkg/compiler/lib/src/ir/impact.dart b/pkg/compiler/lib/src/ir/impact.dart
index 609256a..0fb8cf4 100644
--- a/pkg/compiler/lib/src/ir/impact.dart
+++ b/pkg/compiler/lib/src/ir/impact.dart
@@ -182,13 +182,12 @@
   void registerRuntimeTypeUse(ir.Expression node, RuntimeTypeUseKind kind,
       ir.DartType receiverType, ir.DartType argumentType);
 
-  // TODO(johnniwinther): Remove these when CFE provides constants.
   void registerConstructorNode(ir.Constructor node);
   void registerFieldNode(ir.Field node);
   void registerProcedureNode(ir.Procedure node);
   void registerStaticInvocationNode(ir.StaticInvocation node);
   void registerSwitchStatementNode(ir.SwitchStatement node);
-  void registerConstConstructorInvocationNode(ir.ConstructorInvocation node);
+  void registerConstSymbolConstructorInvocationNode();
 }
 
 class ImpactBuilderData {
diff --git a/pkg/compiler/lib/src/ir/impact_data.dart b/pkg/compiler/lib/src/ir/impact_data.dart
index 77d8075..96fe2ed 100644
--- a/pkg/compiler/lib/src/ir/impact_data.dart
+++ b/pkg/compiler/lib/src/ir/impact_data.dart
@@ -9,7 +9,11 @@
 import 'package:kernel/type_environment.dart' as ir;
 
 import '../common.dart';
+import '../common/elements.dart';
+import '../elements/entities.dart';
+import '../elements/types.dart';
 import '../ir/scope.dart';
+import '../kernel/element_map.dart';
 import '../serialization/serialization.dart';
 import '../util/enumset.dart';
 import 'constants.dart';
@@ -21,6 +25,7 @@
 /// Visitor that builds an [ImpactData] object for the world impact.
 class ImpactBuilder extends StaticTypeVisitor implements ImpactRegistry {
   final ImpactData _data = ImpactData();
+  final KernelToElementMap _elementMap;
 
   @override
   final VariableScopeModel variableScopeModel;
@@ -34,12 +39,24 @@
   @override
   final inferEffectivelyFinalVariableTypes;
 
-  ImpactBuilder(this.staticTypeContext, StaticTypeCacheImpl staticTypeCache,
-      ir.ClassHierarchy classHierarchy, this.variableScopeModel,
-      {this.useAsserts = false, this.inferEffectivelyFinalVariableTypes = true})
+  ImpactBuilder(
+      this._elementMap,
+      this.staticTypeContext,
+      StaticTypeCacheImpl staticTypeCache,
+      ir.ClassHierarchy classHierarchy,
+      this.variableScopeModel,
+      {this.useAsserts = false,
+      this.inferEffectivelyFinalVariableTypes = true})
       : super(
             staticTypeContext.typeEnvironment, classHierarchy, staticTypeCache);
 
+  CommonElements get _commonElements => _elementMap.commonElements;
+
+  DiagnosticReporter get _reporter => _elementMap.reporter;
+
+  String _typeToString(DartType type) =>
+      type.toStructuredText(_elementMap.types, _elementMap.options);
+
   /// Return the named arguments names as a list of strings.
   List<String> _getNamedArguments(ir.Arguments arguments) =>
       arguments.named.map((n) => n.name).toList();
@@ -313,6 +330,23 @@
     registerProcedureNode(procedure);
   }
 
+  void _handleConstConstructorInvocation(ir.ConstructorInvocation node) {
+    assert(node.isConst);
+    ConstructorEntity constructor = _elementMap.getConstructor(node.target);
+    if (_commonElements.isSymbolConstructor(constructor)) {
+      DartType argumentType = _elementMap.getDartType(
+          node.arguments.positional.first.getStaticType(staticTypeContext));
+      // TODO(joshualitt): Does the CFE check this for us?
+      if (argumentType != _commonElements.stringType) {
+        // TODO(het): Get the actual span for the Symbol constructor argument
+        _reporter.reportErrorMessage(CURRENT_ELEMENT_SPANNABLE,
+            MessageKind.STRING_EXPECTED, {'type': _typeToString(argumentType)});
+        return;
+      }
+      registerConstSymbolConstructorInvocationNode();
+    }
+  }
+
   @override
   void handleConstructorInvocation(ir.ConstructorInvocation node,
       ArgumentTypes argumentTypes, ir.DartType resultType) {
@@ -325,7 +359,7 @@
         getDeferredImport(node),
         isConst: node.isConst);
     if (node.isConst) {
-      registerConstConstructorInvocationNode(node);
+      _handleConstConstructorInvocation(node);
     }
   }
 
@@ -959,13 +993,15 @@
   }
 
   @override
-  void registerConstConstructorInvocationNode(ir.ConstructorInvocation node) {
-    _data._constConstructorInvocationNodes ??= [];
-    _data._constConstructorInvocationNodes.add(node);
+  void registerConstSymbolConstructorInvocationNode() {
+    _data._hasConstSymbolConstructorInvocation = true;
   }
 }
 
 /// Data object that contains the world impact data derived purely from kernel.
+/// It is critical that all of the data in this class be invariant to changes in
+/// the AST that occur after modular compilation and before deserializing the
+/// impact data.
 class ImpactData {
   static const String tag = 'ImpactData';
 
@@ -1012,7 +1048,7 @@
   List<ir.Procedure> _procedureNodes;
   List<ir.SwitchStatement> _switchStatementNodes;
   List<ir.StaticInvocation> _staticInvocationNodes;
-  List<ir.ConstructorInvocation> _constConstructorInvocationNodes;
+  bool _hasConstSymbolConstructorInvocation = false;
 
   ImpactData();
 
@@ -1109,8 +1145,7 @@
         source.readTreeNodes<ir.SwitchStatement>(emptyAsNull: true);
     _staticInvocationNodes =
         source.readTreeNodes<ir.StaticInvocation>(emptyAsNull: true);
-    _constConstructorInvocationNodes =
-        source.readTreeNodes<ir.ConstructorInvocation>(emptyAsNull: true);
+    _hasConstSymbolConstructorInvocation = source.readBool();
     source.end(tag);
   }
 
@@ -1186,13 +1221,12 @@
     sink.writeList(_runtimeTypeUses, (_RuntimeTypeUse o) => o.toDataSink(sink),
         allowNull: true);
 
-    // TODO(johnniwinther): Remove these when CFE provides constants.
     sink.writeMemberNodes(_constructorNodes, allowNull: true);
     sink.writeMemberNodes(_fieldNodes, allowNull: true);
     sink.writeMemberNodes(_procedureNodes, allowNull: true);
     sink.writeTreeNodes(_switchStatementNodes, allowNull: true);
     sink.writeTreeNodes(_staticInvocationNodes, allowNull: true);
-    sink.writeTreeNodes(_constConstructorInvocationNodes, allowNull: true);
+    sink.writeBool(_hasConstSymbolConstructorInvocation);
 
     sink.end(tag);
   }
@@ -1527,10 +1561,8 @@
         registry.registerStaticInvocationNode(data);
       }
     }
-    if (_constConstructorInvocationNodes != null) {
-      for (ir.ConstructorInvocation data in _constConstructorInvocationNodes) {
-        registry.registerConstConstructorInvocationNode(data);
-      }
+    if (_hasConstSymbolConstructorInvocation) {
+      registry.registerConstSymbolConstructorInvocationNode();
     }
   }
 }
diff --git a/pkg/compiler/lib/src/ir/modular.dart b/pkg/compiler/lib/src/ir/modular.dart
index baa7842..a5da488 100644
--- a/pkg/compiler/lib/src/ir/modular.dart
+++ b/pkg/compiler/lib/src/ir/modular.dart
@@ -5,7 +5,6 @@
 // @dart = 2.10
 
 import 'package:kernel/ast.dart' as ir;
-import 'package:kernel/class_hierarchy.dart' as ir;
 import 'package:kernel/type_environment.dart' as ir;
 
 import 'package:front_end/src/api_unstable/dart2js.dart' as ir
@@ -17,7 +16,7 @@
 import '../ir/impact_data.dart';
 import '../ir/static_type.dart';
 import '../js_backend/annotations.dart';
-import '../options.dart';
+import '../kernel/element_map.dart';
 import '../serialization/serialization.dart';
 import '../util/enumset.dart';
 import 'annotations.dart';
@@ -73,19 +72,20 @@
 }
 
 /// Compute [ModularMemberData] from the IR.
-ModularMemberData computeModularMemberData(ir.Member node,
-    {CompilerOptions options,
-    ir.TypeEnvironment typeEnvironment,
-    ir.ClassHierarchy classHierarchy,
+ModularMemberData computeModularMemberData(
+    KernelToElementMap elementMap,
+    ir.Member node,
     ScopeModel scopeModel,
-    EnumSet<PragmaAnnotation> annotations}) {
+    EnumSet<PragmaAnnotation> annotations) {
   var staticTypeCache = StaticTypeCacheImpl();
   var impactBuilderData = ImpactBuilder(
-          ir.StaticTypeContext(node, typeEnvironment, cache: staticTypeCache),
+          elementMap,
+          ir.StaticTypeContext(node, elementMap.typeEnvironment,
+              cache: staticTypeCache),
           staticTypeCache,
-          classHierarchy,
+          elementMap.classHierarchy,
           scopeModel.variableScopeModel,
-          useAsserts: options.enableUserAssertions,
+          useAsserts: elementMap.options.enableUserAssertions,
           inferEffectivelyFinalVariableTypes:
               !annotations.contains(PragmaAnnotation.disableFinal))
       .computeImpact(node);
diff --git a/pkg/compiler/lib/src/kernel/kernel_impact.dart b/pkg/compiler/lib/src/kernel/kernel_impact.dart
index 6b135bc..3756ddd 100644
--- a/pkg/compiler/lib/src/kernel/kernel_impact.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_impact.dart
@@ -348,22 +348,8 @@
   }
 
   @override
-  void registerConstConstructorInvocationNode(ir.ConstructorInvocation node) {
-    assert(node.isConst);
-    ConstructorEntity constructor = elementMap.getConstructor(node.target);
-    if (commonElements.isSymbolConstructor(constructor)) {
-      ConstantValue value = elementMap.getConstantValue(
-          staticTypeContext, node.arguments.positional.first);
-      if (!value.isString) {
-        // TODO(het): Get the actual span for the Symbol constructor argument
-        reporter.reportErrorMessage(
-            CURRENT_ELEMENT_SPANNABLE,
-            MessageKind.STRING_EXPECTED,
-            {'type': typeToString(value.getType(elementMap.commonElements))});
-        return;
-      }
-      registerBackendImpact(_impacts.constSymbol);
-    }
+  void registerConstSymbolConstructorInvocationNode() {
+    registerBackendImpact(_impacts.constSymbol);
   }
 
   @override
diff --git a/pkg/compiler/lib/src/kernel/kernel_strategy.dart b/pkg/compiler/lib/src/kernel/kernel_strategy.dart
index 137a26c..0a7cda9 100644
--- a/pkg/compiler/lib/src/kernel/kernel_strategy.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_strategy.dart
@@ -440,12 +440,8 @@
     ScopeModel scopeModel = _compilerTask.measureSubtask(
         'closures', () => ScopeModel.from(node, _elementMap.constantEvaluator));
     return _compilerTask.measureSubtask('worldImpact', () {
-      return computeModularMemberData(node,
-          options: _elementMap.options,
-          typeEnvironment: _elementMap.typeEnvironment,
-          classHierarchy: _elementMap.classHierarchy,
-          scopeModel: scopeModel,
-          annotations: annotations);
+      return computeModularMemberData(
+          _elementMap, node, scopeModel, annotations);
     });
   }
 }
diff --git a/pkg/compiler/lib/src/phase/modular_analysis.dart b/pkg/compiler/lib/src/phase/modular_analysis.dart
index 75853c4..748e97c 100644
--- a/pkg/compiler/lib/src/phase/modular_analysis.dart
+++ b/pkg/compiler/lib/src/phase/modular_analysis.dart
@@ -63,13 +63,9 @@
     final scopeModel = ScopeModel.from(member, elementMap.constantEvaluator);
     final annotations = processMemberAnnotations(
         options, reporter, member, computePragmaAnnotationDataFromIr(member));
-    result[member] = computeModularMemberData(member,
-            options: options,
-            typeEnvironment: elementMap.typeEnvironment,
-            classHierarchy: elementMap.classHierarchy,
-            scopeModel: scopeModel,
-            annotations: annotations)
-        .impactBuilderData;
+    result[member] =
+        computeModularMemberData(elementMap, member, scopeModel, annotations)
+            .impactBuilderData;
   }
 
   for (final library in input.component.libraries) {
diff --git a/pkg/dart_internal/CHANGELOG.md b/pkg/dart_internal/CHANGELOG.md
index 868e075..4b8c21c 100644
--- a/pkg/dart_internal/CHANGELOG.md
+++ b/pkg/dart_internal/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.2.5
+
+- Support the latest Dart SDK.
+
 ## 0.2.4
 
 - Support the latest Dart SDK.
diff --git a/pkg/dart_internal/pubspec.yaml b/pkg/dart_internal/pubspec.yaml
index 244171e..51a630d 100644
--- a/pkg/dart_internal/pubspec.yaml
+++ b/pkg/dart_internal/pubspec.yaml
@@ -1,5 +1,5 @@
 name: dart_internal
-version: 0.2.4
+version: 0.2.5
 repository: https://github.com/dart-lang/sdk/tree/master/pkg/dart_internal
 description: >-
   This package is not intended for wide use. It provides a temporary API to
@@ -9,4 +9,4 @@
 environment:
   # Restrict the upper bound so that we can remove support for this in a later
   # version of the SDK without it being a breaking change.
-  sdk: ">=2.12.0 <2.18.0"
+  sdk: ">=2.12.0 <2.19.0"
diff --git a/pkg/front_end/testcases/general/async_function.dart.weak.transformed.expect b/pkg/front_end/testcases/general/async_function.dart.weak.transformed.expect
index aea2b09..373a8d8 100644
--- a/pkg/front_end/testcases/general/async_function.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/async_function.dart.weak.transformed.expect
@@ -121,10 +121,10 @@
             return null;
           else
             [yield] null;
-          :controller.{asy::_AsyncStarStreamController::addStream}(self::asyncStarString2()){(asy::Stream<core::String>) → void};
-          [yield] null;
-          if(_in::unsafeCast<core::bool>(:result_or_exception))
+          if(:controller.{asy::_AsyncStarStreamController::addStream}(self::asyncStarString2()){(asy::Stream<core::String>) → core::bool})
             return null;
+          else
+            [yield] null;
           [yield] let dynamic #t1 = asy::_awaitHelper(self::asyncString(), :async_op_then, :async_op_error) in null;
           if(:controller.{asy::_AsyncStarStreamController::add}(_in::unsafeCast<core::String>(:result_or_exception)){(core::String) → core::bool})
             return null;
diff --git a/pkg/front_end/testcases/general/await_complex.dart.weak.transformed.expect b/pkg/front_end/testcases/general/await_complex.dart.weak.transformed.expect
index 7af3671..d3d1139 100644
--- a/pkg/front_end/testcases/general/await_complex.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/await_complex.dart.weak.transformed.expect
@@ -652,10 +652,10 @@
                       #L16:
                       {
                         [yield] let dynamic #t55 = asy::_awaitHelper(func<asy::Stream<core::int>>(self::intStream()){(asy::Stream<core::int>) → FutureOr<asy::Stream<core::int>>}, :async_op_then, :async_op_error) in null;
-                        :controller.{asy::_AsyncStarStreamController::addStream}(_in::unsafeCast<asy::Stream<core::int>>(:result_or_exception)){(asy::Stream<core::int>) → void};
-                        [yield] null;
-                        if(_in::unsafeCast<core::bool>(:result_or_exception))
+                        if(:controller.{asy::_AsyncStarStreamController::addStream}(_in::unsafeCast<asy::Stream<core::int>>(:result_or_exception)){(asy::Stream<core::int>) → core::bool})
                           return null;
+                        else
+                          [yield] null;
                       }
                       return;
                     }
diff --git a/pkg/front_end/testcases/general/statements.dart.weak.transformed.expect b/pkg/front_end/testcases/general/statements.dart.weak.transformed.expect
index 2db299f..012142b 100644
--- a/pkg/front_end/testcases/general/statements.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/statements.dart.weak.transformed.expect
@@ -44,10 +44,10 @@
                       return null;
                     else
                       [yield] null;
-                    :controller.{asy::_AsyncStarStreamController::addStream}(x as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<dynamic>){(asy::Stream<dynamic>) → void};
-                    [yield] null;
-                    if(_in::unsafeCast<core::bool>(:result_or_exception))
+                    if(:controller.{asy::_AsyncStarStreamController::addStream}(x as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<dynamic>){(asy::Stream<dynamic>) → core::bool})
                       return null;
+                    else
+                      [yield] null;
                   }
                 }
                 else
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.weak.transformed.expect
index 5730a20..2e127fbc 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.weak.transformed.expect
@@ -2,7 +2,6 @@
 import self as self;
 import "dart:async" as asy;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 import "dart:async";
 
@@ -26,10 +25,10 @@
             else
               [yield] null;
             asy::Stream<core::double*>* s;
-            :controller.{asy::_AsyncStarStreamController::addStream}(s){(asy::Stream<core::num*>) → void};
-            [yield] null;
-            if(_in::unsafeCast<core::bool>(:result_or_exception))
+            if(:controller.{asy::_AsyncStarStreamController::addStream}(s){(asy::Stream<core::num*>) → core::bool})
               return null;
+            else
+              [yield] null;
           }
           return;
         }
diff --git a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.weak.transformed.expect
index 02bca84..7f9840f 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.weak.transformed.expect
@@ -29,7 +29,6 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
-import "dart:_internal" as _in;
 
 import "dart:async";
 
@@ -110,18 +109,18 @@
             return null;
           else
             [yield] null;
-          :controller.{asy::_AsyncStarStreamController::addStream}(invalid-expression "pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:17:64: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Stream<List<int>>'.
+          if(:controller.{asy::_AsyncStarStreamController::addStream}(invalid-expression "pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:17:64: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Stream<List<int>>'.
  - 'List' is from 'dart:core'.
  - 'Stream' is from 'dart:async'.
   yield* /*error:YIELD_OF_INVALID_TYPE*/ /*@typeArgs=dynamic*/ [];
-                                                               ^" in core::_GrowableList::•<dynamic>(0) as{TypeError} asy::Stream<core::List<core::int*>*>*){(asy::Stream<core::List<core::int*>*>) → void};
-          [yield] null;
-          if(_in::unsafeCast<core::bool>(:result_or_exception))
+                                                               ^" in core::_GrowableList::•<dynamic>(0) as{TypeError} asy::Stream<core::List<core::int*>*>*){(asy::Stream<core::List<core::int*>*>) → core::bool})
             return null;
-          :controller.{asy::_AsyncStarStreamController::addStream}(self::MyStream::•<core::List<core::int*>*>()){(asy::Stream<core::List<core::int*>*>) → void};
-          [yield] null;
-          if(_in::unsafeCast<core::bool>(:result_or_exception))
+          else
+            [yield] null;
+          if(:controller.{asy::_AsyncStarStreamController::addStream}(self::MyStream::•<core::List<core::int*>*>()){(asy::Stream<core::List<core::int*>*>) → core::bool})
             return null;
+          else
+            [yield] null;
         }
         return;
       }
diff --git a/pkg/front_end/testcases/inference/local_return_and_yield.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/local_return_and_yield.dart.weak.transformed.expect
index 251c281..fbcd719 100644
--- a/pkg/front_end/testcases/inference/local_return_and_yield.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/local_return_and_yield.dart.weak.transformed.expect
@@ -10,7 +10,6 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
-import "dart:_internal" as _in;
 
 import "dart:async";
 
@@ -130,10 +129,10 @@
         try {
           #L3:
           {
-            :controller.{asy::_AsyncStarStreamController::addStream}(asy::Stream::fromIterable<(core::int*) →* core::int*>(core::_GrowableList::_literal1<(core::int*) →* core::int*>((core::int* x) → core::int* => x))){(asy::Stream<(core::int*) →* core::int*>) → void};
-            [yield] null;
-            if(_in::unsafeCast<core::bool>(:result_or_exception))
+            if(:controller.{asy::_AsyncStarStreamController::addStream}(asy::Stream::fromIterable<(core::int*) →* core::int*>(core::_GrowableList::_literal1<(core::int*) →* core::int*>((core::int* x) → core::int* => x))){(asy::Stream<(core::int*) →* core::int*>) → core::bool})
               return null;
+            else
+              [yield] null;
           }
           return;
         }
diff --git a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.weak.transformed.expect
index 3d5e979..84ea22c 100644
--- a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.weak.transformed.expect
@@ -10,7 +10,6 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
-import "dart:_internal" as _in;
 
 import "dart:async";
 
@@ -129,10 +128,10 @@
       try {
         #L3:
         {
-          :controller.{asy::_AsyncStarStreamController::addStream}(asy::Stream::fromIterable<(core::int*) →* core::int*>(core::_GrowableList::_literal1<(core::int*) →* core::int*>((core::int* x) → core::int* => x))){(asy::Stream<(core::int*) →* core::int*>) → void};
-          [yield] null;
-          if(_in::unsafeCast<core::bool>(:result_or_exception))
+          if(:controller.{asy::_AsyncStarStreamController::addStream}(asy::Stream::fromIterable<(core::int*) →* core::int*>(core::_GrowableList::_literal1<(core::int*) →* core::int*>((core::int* x) → core::int* => x))){(asy::Stream<(core::int*) →* core::int*>) → core::bool})
             return null;
+          else
+            [yield] null;
         }
         return;
       }
diff --git a/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.transformed.expect
index c8058e6..cfc0b05 100644
--- a/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.transformed.expect
@@ -40,7 +40,6 @@
 import self as self;
 import "dart:async" as asy;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 static method getNull() → dynamic
   return null;
@@ -161,13 +160,13 @@
       try {
         #L4:
         {
-          :controller.{asy::_AsyncStarStreamController::addStream}(invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:21:10: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+          if(:controller.{asy::_AsyncStarStreamController::addStream}(invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:21:10: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
  - 'Stream' is from 'dart:async'.
   yield* getStreamNull(); // error
-         ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>){(asy::Stream<core::bool>) → void};
-          [yield] null;
-          if(_in::unsafeCast<core::bool>(:result_or_exception))
+         ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>){(asy::Stream<core::bool>) → core::bool})
             return null;
+          else
+            [yield] null;
         }
         return;
       }
@@ -204,10 +203,10 @@
       try {
         #L5:
         {
-          :controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamBool()){(asy::Stream<core::bool>) → void};
-          [yield] null;
-          if(_in::unsafeCast<core::bool>(:result_or_exception))
+          if(:controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamBool()){(asy::Stream<core::bool>) → core::bool})
             return null;
+          else
+            [yield] null;
         }
         return;
       }
@@ -286,13 +285,13 @@
               try {
                 #L8:
                 {
-                  :controller.{asy::_AsyncStarStreamController::addStream}(invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:38:12: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+                  if(:controller.{asy::_AsyncStarStreamController::addStream}(invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:38:12: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
  - 'Stream' is from 'dart:async'.
     yield* getStreamNull(); // error
-           ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>){(asy::Stream<core::bool>) → void};
-                  [yield] null;
-                  if(_in::unsafeCast<core::bool>(:result_or_exception))
+           ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>){(asy::Stream<core::bool>) → core::bool})
                     return null;
+                  else
+                    [yield] null;
                 }
                 return;
               }
@@ -329,10 +328,10 @@
               try {
                 #L9:
                 {
-                  :controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamBool()){(asy::Stream<core::bool>) → void};
-                  [yield] null;
-                  if(_in::unsafeCast<core::bool>(:result_or_exception))
+                  if(:controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamBool()){(asy::Stream<core::bool>) → core::bool})
                     return null;
+                  else
+                    [yield] null;
                 }
                 return;
               }
@@ -403,10 +402,10 @@
               try {
                 #L11:
                 {
-                  :controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamNull()){(asy::Stream<dynamic>) → void};
-                  [yield] null;
-                  if(_in::unsafeCast<core::bool>(:result_or_exception))
+                  if(:controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamNull()){(asy::Stream<dynamic>) → core::bool})
                     return null;
+                  else
+                    [yield] null;
                 }
                 return;
               }
@@ -441,10 +440,10 @@
               try {
                 #L12:
                 {
-                  :controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamBool()){(asy::Stream<core::bool>) → void};
-                  [yield] null;
-                  if(_in::unsafeCast<core::bool>(:result_or_exception))
+                  if(:controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamBool()){(asy::Stream<core::bool>) → core::bool})
                     return null;
+                  else
+                    [yield] null;
                 }
                 return;
               }
diff --git a/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.transformed.expect
index c8058e6..cfc0b05 100644
--- a/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.transformed.expect
@@ -40,7 +40,6 @@
 import self as self;
 import "dart:async" as asy;
 import "dart:core" as core;
-import "dart:_internal" as _in;
 
 static method getNull() → dynamic
   return null;
@@ -161,13 +160,13 @@
       try {
         #L4:
         {
-          :controller.{asy::_AsyncStarStreamController::addStream}(invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:21:10: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+          if(:controller.{asy::_AsyncStarStreamController::addStream}(invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:21:10: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
  - 'Stream' is from 'dart:async'.
   yield* getStreamNull(); // error
-         ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>){(asy::Stream<core::bool>) → void};
-          [yield] null;
-          if(_in::unsafeCast<core::bool>(:result_or_exception))
+         ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>){(asy::Stream<core::bool>) → core::bool})
             return null;
+          else
+            [yield] null;
         }
         return;
       }
@@ -204,10 +203,10 @@
       try {
         #L5:
         {
-          :controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamBool()){(asy::Stream<core::bool>) → void};
-          [yield] null;
-          if(_in::unsafeCast<core::bool>(:result_or_exception))
+          if(:controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamBool()){(asy::Stream<core::bool>) → core::bool})
             return null;
+          else
+            [yield] null;
         }
         return;
       }
@@ -286,13 +285,13 @@
               try {
                 #L8:
                 {
-                  :controller.{asy::_AsyncStarStreamController::addStream}(invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:38:12: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+                  if(:controller.{asy::_AsyncStarStreamController::addStream}(invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:38:12: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
  - 'Stream' is from 'dart:async'.
     yield* getStreamNull(); // error
-           ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>){(asy::Stream<core::bool>) → void};
-                  [yield] null;
-                  if(_in::unsafeCast<core::bool>(:result_or_exception))
+           ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>){(asy::Stream<core::bool>) → core::bool})
                     return null;
+                  else
+                    [yield] null;
                 }
                 return;
               }
@@ -329,10 +328,10 @@
               try {
                 #L9:
                 {
-                  :controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamBool()){(asy::Stream<core::bool>) → void};
-                  [yield] null;
-                  if(_in::unsafeCast<core::bool>(:result_or_exception))
+                  if(:controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamBool()){(asy::Stream<core::bool>) → core::bool})
                     return null;
+                  else
+                    [yield] null;
                 }
                 return;
               }
@@ -403,10 +402,10 @@
               try {
                 #L11:
                 {
-                  :controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamNull()){(asy::Stream<dynamic>) → void};
-                  [yield] null;
-                  if(_in::unsafeCast<core::bool>(:result_or_exception))
+                  if(:controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamNull()){(asy::Stream<dynamic>) → core::bool})
                     return null;
+                  else
+                    [yield] null;
                 }
                 return;
               }
@@ -441,10 +440,10 @@
               try {
                 #L12:
                 {
-                  :controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamBool()){(asy::Stream<core::bool>) → void};
-                  [yield] null;
-                  if(_in::unsafeCast<core::bool>(:result_or_exception))
+                  if(:controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamBool()){(asy::Stream<core::bool>) → core::bool})
                     return null;
+                  else
+                    [yield] null;
                 }
                 return;
               }
diff --git a/pkg/vm/lib/transformations/continuation.dart b/pkg/vm/lib/transformations/continuation.dart
index fa535fc..b5c3949 100644
--- a/pkg/vm/lib/transformations/continuation.dart
+++ b/pkg/vm/lib/transformations/continuation.dart
@@ -1319,21 +1319,10 @@
         functionType: addMethodFunctionType)
       ..fileOffset = stmt.fileOffset;
 
-    if (stmt.isYieldStar) {
-      statements.add(ExpressionStatement(addExpression));
-      statements.add(createContinuationPoint()..fileOffset = stmt.fileOffset);
-      final wasCancelled = StaticInvocation(
-          helper.unsafeCast,
-          Arguments(<Expression>[VariableGet(expressionRewriter!.asyncResult)],
-              types: <DartType>[helper.coreTypes.boolNonNullableRawType]));
-      statements
-          .add(IfStatement(wasCancelled, ReturnStatement(NullLiteral()), null));
-    } else {
-      statements.add(new IfStatement(
-          addExpression,
-          new ReturnStatement(new NullLiteral()),
-          createContinuationPoint()..fileOffset = stmt.fileOffset));
-    }
+    statements.add(new IfStatement(
+        addExpression,
+        new ReturnStatement(new NullLiteral()),
+        createContinuationPoint()..fileOffset = stmt.fileOffset));
     return removalSentinel ?? EmptyStatement();
   }
 
diff --git a/pkg/vm_service/CHANGELOG.md b/pkg/vm_service/CHANGELOG.md
index 56c3736..52f6a07 100644
--- a/pkg/vm_service/CHANGELOG.md
+++ b/pkg/vm_service/CHANGELOG.md
@@ -1,5 +1,8 @@
 # Changelog
 
+## 8.2.2+1
+- Documentation update for `FieldRef` and `FuncRef`.
+
 ## 8.2.2
 - Updated the following optional fields to be nullable in `SocketStatistic`:
   - `endTime`
diff --git a/pkg/vm_service/lib/src/vm_service.dart b/pkg/vm_service/lib/src/vm_service.dart
index b8b3cb6..0f80275 100644
--- a/pkg/vm_service/lib/src/vm_service.dart
+++ b/pkg/vm_service/lib/src/vm_service.dart
@@ -4302,6 +4302,9 @@
   String? name;
 
   /// The owner of this field, which can be either a Library or a Class.
+  ///
+  /// Note: the location of `owner` may not agree with `location` if this is a
+  /// field from a mixin application, patched class, etc.
   ObjRef? owner;
 
   /// The declared type of this field.
@@ -4320,6 +4323,9 @@
   bool? isStatic;
 
   /// The location of this field in the source code.
+  ///
+  /// Note: this may not agree with the location of `owner` if this is a field
+  /// from a mixin application, patched class, etc.
   @optional
   SourceLocation? location;
 
@@ -4386,6 +4392,9 @@
   String? name;
 
   /// The owner of this field, which can be either a Library or a Class.
+  ///
+  /// Note: the location of `owner` may not agree with `location` if this is a
+  /// field from a mixin application, patched class, etc.
   ObjRef? owner;
 
   /// The declared type of this field.
@@ -4404,6 +4413,9 @@
   bool? isStatic;
 
   /// The location of this field in the source code.
+  ///
+  /// Note: this may not agree with the location of `owner` if this is a field
+  /// from a mixin application, patched class, etc.
   @optional
   SourceLocation? location;
 
@@ -4630,6 +4642,10 @@
 
   /// The owner of this function, which can be a Library, Class, or a Function.
   ///
+  /// Note: the location of `owner` may not agree with `location` if this is a
+  /// function from a mixin application, expression evaluation, patched class,
+  /// etc.
+  ///
   /// [owner] can be one of [LibraryRef], [ClassRef] or [FuncRef].
   dynamic owner;
 
@@ -4643,6 +4659,10 @@
   bool? implicit;
 
   /// The location of this function in the source code.
+  ///
+  /// Note: this may not agree with the location of `owner` if this is a
+  /// function from a mixin application, expression evaluation, patched class,
+  /// etc.
   @optional
   SourceLocation? location;
 
@@ -4706,6 +4726,10 @@
 
   /// The owner of this function, which can be a Library, Class, or a Function.
   ///
+  /// Note: the location of `owner` may not agree with `location` if this is a
+  /// function from a mixin application, expression evaluation, patched class,
+  /// etc.
+  ///
   /// [owner] can be one of [LibraryRef], [ClassRef] or [FuncRef].
   dynamic owner;
 
@@ -4719,6 +4743,10 @@
   bool? implicit;
 
   /// The location of this function in the source code.
+  ///
+  /// Note: this may not agree with the location of `owner` if this is a
+  /// function from a mixin application, expression evaluation, patched class,
+  /// etc.
   @optional
   SourceLocation? location;
 
diff --git a/pkg/vm_service/pubspec.yaml b/pkg/vm_service/pubspec.yaml
index 1f9fc98..7de79cf 100644
--- a/pkg/vm_service/pubspec.yaml
+++ b/pkg/vm_service/pubspec.yaml
@@ -3,7 +3,7 @@
   A library to communicate with a service implementing the Dart VM
   service protocol.
 
-version: 8.2.2
+version: 8.2.2+1
 
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/vm_service
 
diff --git a/pkg/vm_service/test/external_compilation_service_script.dart b/pkg/vm_service/test/external_compilation_service_script.dart
new file mode 100644
index 0000000..0816523
--- /dev/null
+++ b/pkg/vm_service/test/external_compilation_service_script.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:developer';
+
+main() {
+  debugger();
+}
diff --git a/pkg/vm_service/test/external_compilation_service_test.dart b/pkg/vm_service/test/external_compilation_service_test.dart
new file mode 100644
index 0000000..e98c146
--- /dev/null
+++ b/pkg/vm_service/test/external_compilation_service_test.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:test/test.dart';
+import 'package:vm_service/vm_service.dart';
+import 'package:vm_service/vm_service_io.dart';
+
+late Uri remoteVmServiceUri;
+
+Future<Process> spawnDartProcess(String script) async {
+  final executable = Platform.executable;
+  final tmpDir = await Directory.systemTemp.createTemp('dart_service');
+  final serviceInfoUri = tmpDir.uri.resolve('service_info.json');
+  final serviceInfoFile = await File.fromUri(serviceInfoUri).create();
+
+  final arguments = [
+    '--disable-dart-dev',
+    '--observe=0',
+    '--disable-service-auth-codes',
+    '--write-service-info=$serviceInfoUri',
+    ...Platform.executableArguments,
+    Platform.script.resolve(script).toString(),
+  ];
+  final process = await Process.start(executable, arguments);
+  process.stdout
+      .transform(utf8.decoder)
+      .listen((line) => print('TESTEE OUT: $line'));
+  process.stderr
+      .transform(utf8.decoder)
+      .listen((line) => print('TESTEE ERR: $line'));
+  while ((await serviceInfoFile.length()) <= 5) {
+    await Future.delayed(const Duration(milliseconds: 50));
+  }
+  final content = await serviceInfoFile.readAsString();
+  final infoJson = json.decode(content);
+  remoteVmServiceUri =
+      Uri.parse(infoJson['uri']).replace(scheme: 'ws', path: 'ws');
+  return process;
+}
+
+Future<void> waitForRunnableIsolate(VmService service, Isolate isolate) async {
+  bool runnable = isolate.runnable!;
+  while (!runnable) {
+    await Future.delayed(const Duration(milliseconds: 100));
+    runnable = (await service.getIsolate(isolate.id!)).runnable!;
+  }
+}
+
+void main() {
+  group('VM Service', () {
+    late Process process;
+
+    setUp(() async {
+      process =
+          await spawnDartProcess('external_compilation_service_script.dart');
+    });
+
+    tearDown(() async {
+      process.kill();
+    });
+
+    test('evaluate invokes client provided compileExpression RPC', () async {
+      final service = await vmServiceConnectUri(remoteVmServiceUri.toString());
+      await service.registerService(
+        'compileExpression',
+        'Custom Expression Compilation',
+      );
+      bool invokedCompileExpression = false;
+      service.registerServiceCallback('compileExpression', (params) async {
+        invokedCompileExpression = true;
+        throw 'error';
+      });
+      final vm = await service.getVM();
+      final isolate = await service.getIsolate(vm.isolates!.first.id!);
+      await waitForRunnableIsolate(service, isolate);
+      try {
+        await service.evaluate(
+            isolate.id!, isolate.libraries!.first.id!, '1 + 1');
+      } catch (_) {
+        // ignore error
+      }
+      expect(invokedCompileExpression, true);
+    });
+
+    test('evaluateInFrame invokes client provided compileExpression RPC',
+        () async {
+      final service = await vmServiceConnectUri(remoteVmServiceUri.toString());
+      await service.registerService(
+        'compileExpression',
+        'Custom Expression Compilation',
+      );
+      bool invokedCompileExpression = false;
+      service.registerServiceCallback('compileExpression', (params) async {
+        invokedCompileExpression = true;
+        throw 'error';
+      });
+      final vm = await service.getVM();
+      final isolate = await service.getIsolate(vm.isolates!.first.id!);
+      await waitForRunnableIsolate(service, isolate);
+      try {
+        await service.evaluateInFrame(isolate.id!, 0, '1 + 1');
+      } catch (e) {
+        // ignore error
+      }
+      expect(invokedCompileExpression, true);
+    });
+  });
+}
diff --git a/runtime/tests/vm/dart/causal_stacks/flutter_regress_100441_test.dart b/runtime/tests/vm/dart/causal_stacks/flutter_regress_100441_test.dart
deleted file mode 100644
index b5ff8ad..0000000
--- a/runtime/tests/vm/dart/causal_stacks/flutter_regress_100441_test.dart
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-//
-// VMOptions=--lazy-async-stacks
-
-import 'dart:async';
-
-import 'package:expect/expect.dart';
-
-import 'utils.dart' show assertStack;
-
-String effectOrder = '';
-StackTrace? stackAfterYield = null;
-
-void emit(String m) => effectOrder += m;
-
-main() async {
-  emit('1');
-  await for (final value in produce()) {
-    emit('5');
-    Expect.equals('|value|', value);
-  }
-  emit('8');
-  Expect.equals('12345678', effectOrder);
-
-  assertStack(const <String>[
-    r'^#0      produceInner .*$',
-    r'^<asynchronous suspension>$',
-    r'^#1      produce .*$',
-    r'^<asynchronous suspension>$',
-    r'^#2      main .*$',
-    r'^<asynchronous suspension>$',
-  ], stackAfterYield!);
-
-  effectOrder = '';
-
-  emit('1');
-  await for (final value in produceYieldStar()) {
-    emit('5');
-    Expect.equals('|value|', value);
-    break;
-  }
-  emit('6');
-  Expect.equals('123456', effectOrder);
-}
-
-Stream<dynamic> produce() async* {
-  emit('2');
-  await for (String response in produceInner()) {
-    emit('4');
-    yield response;
-  }
-  emit('7');
-}
-
-Stream produceInner() async* {
-  emit('3');
-  yield '|value|';
-  emit('6');
-  stackAfterYield = StackTrace.current;
-}
-
-Stream<dynamic> produceYieldStar() async* {
-  emit('2');
-  await for (String response in produceInner()) {
-    emit('4');
-    yield response;
-  }
-  emit('x');
-}
-
-Stream produceInnerYieldStar() async* {
-  emit('3');
-  yield* Stream.fromIterable(['|value|', '|value2|']);
-  emit('x');
-}
diff --git a/runtime/tests/vm/dart_2/causal_stacks/flutter_regress_100441_test.dart b/runtime/tests/vm/dart_2/causal_stacks/flutter_regress_100441_test.dart
deleted file mode 100644
index 2d4d2ef..0000000
--- a/runtime/tests/vm/dart_2/causal_stacks/flutter_regress_100441_test.dart
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-//
-// VMOptions=--lazy-async-stacks
-
-// @dart = 2.9
-import 'dart:async';
-
-import 'package:expect/expect.dart';
-
-import 'utils.dart' show assertStack;
-
-String effectOrder = '';
-StackTrace stackAfterYield = null;
-
-void emit(String m) => effectOrder += m;
-
-main() async {
-  emit('1');
-  await for (final value in produce()) {
-    emit('5');
-    Expect.equals('|value|', value);
-  }
-  emit('8');
-  Expect.equals('12345678', effectOrder);
-
-  assertStack(const <String>[
-    r'^#0      produceInner .*$',
-    r'^<asynchronous suspension>$',
-    r'^#1      produce .*$',
-    r'^<asynchronous suspension>$',
-    r'^#2      main .*$',
-    r'^<asynchronous suspension>$',
-  ], stackAfterYield);
-
-  effectOrder = '';
-
-  emit('1');
-  await for (final value in produceYieldStar()) {
-    emit('5');
-    Expect.equals('|value|', value);
-    break;
-  }
-  emit('6');
-  Expect.equals('123456', effectOrder);
-}
-
-Stream<dynamic> produce() async* {
-  emit('2');
-  await for (String response in produceInner()) {
-    emit('4');
-    yield response;
-  }
-  emit('7');
-}
-
-Stream produceInner() async* {
-  emit('3');
-  yield '|value|';
-  emit('6');
-  stackAfterYield = StackTrace.current;
-}
-
-Stream<dynamic> produceYieldStar() async* {
-  emit('2');
-  await for (String response in produceInner()) {
-    emit('4');
-    yield response;
-  }
-  emit('x');
-}
-
-Stream produceInnerYieldStar() async* {
-  emit('3');
-  yield* Stream.fromIterable(['|value|', '|value2|']);
-  emit('x');
-}
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index 3ec06a6..eabdbb0 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -3507,25 +3507,23 @@
     return;
   }
 
-#if !defined(TARGET_ARCH_RISCV32) && !defined(TARGET_ARCH_RISCV64)
   // Split moves from stack to stack, none of the architectures provides
-  // memory to memory move instructions. But RISC-V needs to avoid TMP.
+  // memory to memory move instructions.
   if (source.IsStack() && destination.IsStack()) {
-    Register scratch = TMP;
-    if (TMP == kNoRegister) {
-      scratch = temp->AllocateTemporary();
-    }
+    Register scratch = temp->AllocateTemporary();
+    ASSERT(scratch != kNoRegister);
+#if defined(TARGET_ARCH_RISCV32) || defined(TARGET_ARCH_RISCV64)
+    ASSERT(scratch != TMP);   // TMP is an argument register.
+    ASSERT(scratch != TMP2);  // TMP2 is an argument register.
+#endif
     const auto& intermediate =
         *new (zone_) compiler::ffi::NativeRegistersLocation(
             zone_, dst_payload_type, dst_container_type, scratch);
     EmitNativeMove(intermediate, source, temp);
     EmitNativeMove(destination, intermediate, temp);
-    if (TMP == kNoRegister) {
-      temp->ReleaseTemporary();
-    }
+    temp->ReleaseTemporary();
     return;
   }
-#endif
 
   const bool sign_or_zero_extend = dst_container_size > src_container_size;
 
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_riscv.cc b/runtime/vm/compiler/backend/flow_graph_compiler_riscv.cc
index 30d5374..8671e2e 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_riscv.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_riscv.cc
@@ -868,15 +868,6 @@
   }
 }
 
-// See FfiCallInstr::MakeLocationSummary.
-static Register WithIntermediateMarshalling(Register r) {
-  if (r == A2) return T2;  // A2=CODE_REG
-  if (r == A3) return T3;  // A3=TMP
-  if (r == A4) return T4;  // A4=TMP2
-  if (r == A5) return T5;  // A5=PP
-  return r;
-}
-
 void FlowGraphCompiler::EmitNativeMoveArchitecture(
     const compiler::ffi::NativeLocation& destination,
     const compiler::ffi::NativeLocation& source) {
@@ -894,12 +885,12 @@
   if (source.IsRegisters()) {
     const auto& src = source.AsRegisters();
     ASSERT(src.num_regs() == 1);
-    const auto src_reg = WithIntermediateMarshalling(src.reg_at(0));
+    const auto src_reg = src.reg_at(0);
 
     if (destination.IsRegisters()) {
       const auto& dst = destination.AsRegisters();
       ASSERT(dst.num_regs() == 1);
-      const auto dst_reg = WithIntermediateMarshalling(dst.reg_at(0));
+      const auto dst_reg = dst.reg_at(0);
       if (!sign_or_zero_extend) {
 #if XLEN == 32
         __ MoveRegister(dst_reg, src_reg);
@@ -995,7 +986,7 @@
     if (destination.IsRegisters()) {
       const auto& dst = destination.AsRegisters();
       ASSERT(dst.num_regs() == 1);
-      const auto dst_reg = WithIntermediateMarshalling(dst.reg_at(0));
+      const auto dst_reg = dst.reg_at(0);
       ASSERT(!sign_or_zero_extend);
       __ LoadFromOffset(dst_reg, src.base_register(), src.offset_in_bytes(),
                         BytesToOperandSize(dst_size));
@@ -1015,14 +1006,8 @@
         default:
           UNIMPLEMENTED();
       }
-    } else if (destination.IsStack()) {
-      const auto& dst = destination.AsStack();
-      // TMP=A3, here not remapped to T3.
-      __ LoadFromOffset(TMP, src.base_register(), src.offset_in_bytes(),
-                        BytesToOperandSize(src_size));
-      __ StoreToOffset(TMP, dst.base_register(), dst.offset_in_bytes(),
-                       BytesToOperandSize(dst_size));
     } else {
+      ASSERT(destination.IsStack());
       UNREACHABLE();
     }
   }
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 30f6bec..367faf6 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -6532,7 +6532,8 @@
 
 void FfiCallInstr::EmitParamMoves(FlowGraphCompiler* compiler,
                                   const Register saved_fp,
-                                  const Register temp) {
+                                  const Register temp0,
+                                  const Register temp1) {
   if (compiler::Assembler::EmittingComments()) {
     __ Comment("EmitParamMoves");
   }
@@ -6546,7 +6547,7 @@
     const auto& pointer_register =
         pointer_location.IsRegisters()
             ? pointer_location.AsRegisters().reg_at(0)
-            : temp;
+            : temp0;
     __ MoveRegister(pointer_register, SPREG);
     __ AddImmediate(pointer_register, marshaller_.PassByPointerStackOffset(
                                           compiler::ffi::kResultIndex));
@@ -6586,7 +6587,7 @@
               ? arg_target.AsPointerToMemory().pointer_location()
               : /*arg_target.IsStack()*/ arg_target.Split(zone_, num_defs, i);
 
-      ConstantTemporaryAllocator temp_alloc(temp);
+      ConstantTemporaryAllocator temp_alloc(temp0);
       if (origin.IsConstant()) {
         // Can't occur because we currently don't inline FFI trampolines (see
         // http://dartbug.com/45055), which means all incomming arguments
@@ -6610,11 +6611,11 @@
       // TypedData/Pointer data pointed to in temp.
       const auto& dst = compiler::ffi::NativeRegistersLocation(
           zone_, pointer_loc.payload_type(), pointer_loc.container_type(),
-          temp);
+          temp0);
       compiler->EmitNativeMove(dst, pointer_loc, &temp_alloc);
-      __ LoadField(temp,
+      __ LoadField(temp0,
                    compiler::FieldAddress(
-                       temp, compiler::target::PointerBase::data_offset()));
+                       temp0, compiler::target::PointerBase::data_offset()));
 
       // Copy chuncks.
       const intptr_t sp_offset =
@@ -6624,16 +6625,16 @@
       // space on the stack.
       for (intptr_t i = 0; i < arg_target.payload_type().SizeInBytes();
            i += compiler::target::kWordSize) {
-        __ LoadMemoryValue(TMP, temp, i);
-        __ StoreMemoryValue(TMP, SPREG, i + sp_offset);
+        __ LoadMemoryValue(temp1, temp0, i);
+        __ StoreMemoryValue(temp1, SPREG, i + sp_offset);
       }
 
       // Store the stack address in the argument location.
-      __ MoveRegister(temp, SPREG);
-      __ AddImmediate(temp, sp_offset);
+      __ MoveRegister(temp0, SPREG);
+      __ AddImmediate(temp0, sp_offset);
       const auto& src = compiler::ffi::NativeRegistersLocation(
           zone_, pointer_loc.payload_type(), pointer_loc.container_type(),
-          temp);
+          temp0);
       compiler->EmitNativeMove(pointer_loc, src, &temp_alloc);
     }
   }
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index a7dd7aa..08d8f81 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -5307,18 +5307,18 @@
                                                bool is_optimizing,
                                                const RegList temps) const;
 
-  // Clobbers both given registers.
+  // Clobbers the first two given registers.
   // `saved_fp` is used as the frame base to rebase off of.
+  // `temp1` is only used in case of PointerToMemoryLocation.
   void EmitParamMoves(FlowGraphCompiler* compiler,
                       const Register saved_fp,
-                      const Register temp);
+                      const Register temp0,
+                      const Register temp1);
   // Clobbers both given temp registers.
   void EmitReturnMoves(FlowGraphCompiler* compiler,
                        const Register temp0,
                        const Register temp1);
 
-  void EmitCall(FlowGraphCompiler* compiler, Register target);
-
   Zone* const zone_;
   const compiler::ffi::CallMarshaller& marshaller_;
 
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index c04289b..f92d297 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -1446,7 +1446,7 @@
   // Reserve space for the arguments that go on the stack (if any), then align.
   __ ReserveAlignedFrameSpace(marshaller_.RequiredStackSpaceInBytes());
 
-  EmitParamMoves(compiler, is_leaf_ ? FPREG : saved_fp_or_sp, temp1);
+  EmitParamMoves(compiler, is_leaf_ ? FPREG : saved_fp_or_sp, temp1, temp2);
 
   if (compiler::Assembler::EmittingComments()) {
     __ Comment(is_leaf_ ? "Leaf Call" : "Call");
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index 2467df7..3dbb6b0 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -1270,7 +1270,7 @@
   // Reserve space for the arguments that go on the stack (if any), then align.
   __ ReserveAlignedFrameSpace(marshaller_.RequiredStackSpaceInBytes());
 
-  EmitParamMoves(compiler, is_leaf_ ? FPREG : saved_fp_or_sp, temp1);
+  EmitParamMoves(compiler, is_leaf_ ? FPREG : saved_fp_or_sp, temp1, temp2);
 
   if (compiler::Assembler::EmittingComments()) {
     __ Comment(is_leaf_ ? "Leaf Call" : "Call");
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index 0d29e71..4869e16 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -1044,7 +1044,9 @@
   // Reserve space for the arguments that go on the stack (if any), then align.
   __ ReserveAlignedFrameSpace(stack_required);
 
-  EmitParamMoves(compiler, is_leaf_ ? FPREG : saved_fp_or_sp, temp);
+  // No second temp: PointerToMemoryLocation is not used for arguments in ia32.
+  EmitParamMoves(compiler, is_leaf_ ? FPREG : saved_fp_or_sp, temp,
+                 kNoRegister);
 
   if (is_leaf_) {
     // We store the pre-align SP at a fixed offset from the final SP.
diff --git a/runtime/vm/compiler/backend/il_riscv.cc b/runtime/vm/compiler/backend/il_riscv.cc
index 5f31d92..a029815 100644
--- a/runtime/vm/compiler/backend/il_riscv.cc
+++ b/runtime/vm/compiler/backend/il_riscv.cc
@@ -1382,18 +1382,17 @@
       zone, is_optimizing,
       (R(CallingConventions::kSecondNonArgumentRegister) |
        R(CallingConventions::kFfiAnyNonAbiRegister) | R(CALLEE_SAVED_TEMP2)));
-  // A3/A4/A5 are blocked during Dart register allocation because they are
+
+  // A3/A4/A5 are unavailable in normal register allocation because they are
   // assigned to TMP/TMP2/PP. This assignment is important for reducing code
-  // size. To work around this for FFI calls, the FFI argument definitions are
-  // allocated to other registers and moved to the correct register at the last
-  // moment (so there are no conflicting uses of TMP/TMP2/PP).
-  // FfiCallInstr itself sometimes also clobbers A2/CODE_REG.
-  // See also FfiCallInstr::EmitCall.
+  // size. We can't just override the normal blockage of these registers because
+  // they may be used by other instructions between the argument's definition
+  // and its use in FfiCallInstr.
+  // Note that A3/A4/A5 might be not be the 3rd/4th/5th input because of mixed
+  // integer and floating-point arguments.
   for (intptr_t i = 0; i < summary->input_count(); i++) {
     if (!summary->in(i).IsRegister()) continue;
-    if (summary->in(i).reg() == A2) {
-      summary->set_in(i, Location::RegisterLocation(T2));
-    } else if (summary->in(i).reg() == A3) {
+    if (summary->in(i).reg() == A3) {
       summary->set_in(i, Location::RegisterLocation(T3));
     } else if (summary->in(i).reg() == A4) {
       summary->set_in(i, Location::RegisterLocation(T4));
@@ -1407,6 +1406,20 @@
 #undef R
 
 void FfiCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  // Beware! Do not use CODE_REG/TMP/TMP2/PP within FfiCallInstr as they are
+  // assigned to A2/A3/A4/A5, which may be in use as argument registers.
+  __ set_constant_pool_allowed(false);
+  for (intptr_t i = 0; i < locs()->input_count(); i++) {
+    if (!locs()->in(i).IsRegister()) continue;
+    if (locs()->in(i).reg() == T3) {
+      __ mv(A3, T3);
+    } else if (locs()->in(i).reg() == T4) {
+      __ mv(A4, T4);
+    } else if (locs()->in(i).reg() == T5) {
+      __ mv(A5, T5);
+    }
+  }
+
   const Register target = locs()->in(TargetAddressIndex()).reg();
 
   // The temps are indexed according to their register number.
@@ -1431,17 +1444,27 @@
   __ mv(saved_fp_or_sp, is_leaf_ ? SPREG : FPREG);
 
   if (!is_leaf_) {
-    // We need to create a dummy "exit frame". It will share the same pool
-    // pointer but have a null code object.
-    __ LoadObject(CODE_REG, Object::null_object());
-    __ set_constant_pool_allowed(false);
-    __ EnterDartFrame(0, PP);
+    // We need to create a dummy "exit frame".
+    // This is EnterDartFrame without accessing A2=CODE_REG or A5=PP.
+    if (FLAG_precompiled_mode) {
+      __ subi(SP, SP, 2 * compiler::target::kWordSize);
+      __ sx(RA, compiler::Address(SP, 1 * compiler::target::kWordSize));
+      __ sx(FP, compiler::Address(SP, 0 * compiler::target::kWordSize));
+      __ addi(FP, SP, 2 * compiler::target::kWordSize);
+    } else {
+      __ subi(SP, SP, 4 * compiler::target::kWordSize);
+      __ sx(RA, compiler::Address(SP, 3 * compiler::target::kWordSize));
+      __ sx(FP, compiler::Address(SP, 2 * compiler::target::kWordSize));
+      __ sx(NULL_REG, compiler::Address(SP, 1 * compiler::target::kWordSize));
+      __ sx(NULL_REG, compiler::Address(SP, 0 * compiler::target::kWordSize));
+      __ addi(FP, SP, 4 * compiler::target::kWordSize);
+    }
   }
 
   // Reserve space for the arguments that go on the stack (if any), then align.
   __ ReserveAlignedFrameSpace(marshaller_.RequiredStackSpaceInBytes());
 
-  EmitParamMoves(compiler, is_leaf_ ? FPREG : saved_fp_or_sp, temp1);
+  EmitParamMoves(compiler, is_leaf_ ? FPREG : saved_fp_or_sp, temp1, temp2);
 
   if (compiler::Assembler::EmittingComments()) {
     __ Comment(is_leaf_ ? "Leaf Call" : "Call");
@@ -1456,10 +1479,7 @@
     __ StoreToOffset(target, THR, compiler::target::Thread::vm_tag_offset());
 #endif
 
-    EmitCall(compiler, target);
-
-    ASSERT(!IsCalleeSavedRegister(PP));
-    __ RestorePoolPointer();
+    __ jalr(target);
 
 #if !defined(PRODUCT)
     __ LoadImmediate(temp1, compiler::target::Thread::vm_tag_dart_id());
@@ -1484,7 +1504,7 @@
       __ TransitionGeneratedToNative(target, FPREG, temp1,
                                      /*enter_safepoint=*/true);
 
-      EmitCall(compiler, target);
+      __ jalr(target);
 
       // Update information in the thread object and leave the safepoint.
       __ TransitionNativeToGenerated(temp1, /*leave_safepoint=*/true);
@@ -1500,7 +1520,7 @@
 
       // Calls T0 and clobbers R19 (along with volatile registers).
       ASSERT(target == T0);
-      EmitCall(compiler, temp1);
+      __ jalr(temp1);
     }
 
     // Refresh pinned registers values (inc. write barrier mask and null
@@ -1514,27 +1534,18 @@
     // Restore the pre-aligned SP.
     __ mv(SPREG, saved_fp_or_sp);
   } else {
-    // Although PP is a callee-saved register, it may have been moved by the GC.
-    __ LeaveDartFrame(compiler::kRestoreCallerPP);
+    __ LeaveDartFrame();
 
     // Restore the global object pool after returning from runtime (old space is
     // moving, so the GOP could have been relocated).
     if (FLAG_precompiled_mode) {
       __ SetupGlobalPoolAndDispatchTable();
     }
-
-    __ set_constant_pool_allowed(true);
   }
-}
 
-void FfiCallInstr::EmitCall(FlowGraphCompiler* compiler, Register target) {
-  // Marshall certain argument registers at the last possible moment.
-  // See FfiCallInstr::MakeLocationSummary for the details.
-  if (InputCount() > 2) __ mv(A2, T2);  // A2=CODE_REG
-  if (InputCount() > 3) __ mv(A3, T3);  // A3=TMP
-  if (InputCount() > 4) __ mv(A4, T4);  // A4=TMP2
-  if (InputCount() > 5) __ mv(A5, T5);  // A5=PP
-  __ jalr(target);
+  // PP is a volatile register, so it must be restored even for leaf FFI calls.
+  __ RestorePoolPointer();
+  __ set_constant_pool_allowed(true);
 }
 
 // Keep in sync with NativeEntryInstr::EmitNativeCode.
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index f461761..023874d 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -1226,9 +1226,9 @@
   __ ReserveAlignedFrameSpace(marshaller_.RequiredStackSpaceInBytes());
 
   if (is_leaf_) {
-    EmitParamMoves(compiler, FPREG, saved_fp);
+    EmitParamMoves(compiler, FPREG, saved_fp, TMP);
   } else {
-    EmitParamMoves(compiler, saved_fp, saved_sp);
+    EmitParamMoves(compiler, saved_fp, saved_sp, TMP);
   }
 
   if (compiler::Assembler::EmittingComments()) {
diff --git a/runtime/vm/instructions_riscv.cc b/runtime/vm/instructions_riscv.cc
index 161db93..cabe480 100644
--- a/runtime/vm/instructions_riscv.cc
+++ b/runtime/vm/instructions_riscv.cc
@@ -227,7 +227,9 @@
 #endif
       if (instr.rs1p() == PP) {
         // PP is untagged on RISC-V.
-        ASSERT(Utils::IsAligned(offset, kWordSize));
+        if (!Utils::IsAligned(offset, kWordSize)) {
+          return false;  // Being used as argument register A5.
+        }
         intptr_t index = ObjectPool::IndexFromOffset(offset - kHeapObjectTag);
         const ObjectPool& pool = ObjectPool::Handle(code.GetObjectPool());
         if (!pool.IsNull() && (index < pool.Length()) &&
@@ -249,7 +251,9 @@
       intptr_t offset = instr.itype_imm();
       if (instr.rs1() == PP) {
         // PP is untagged on RISC-V.
-        ASSERT(Utils::IsAligned(offset, kWordSize));
+        if (!Utils::IsAligned(offset, kWordSize)) {
+          return false;  // Being used as argument register A5.
+        }
         intptr_t index = ObjectPool::IndexFromOffset(offset - kHeapObjectTag);
         const ObjectPool& pool = ObjectPool::Handle(code.GetObjectPool());
         if (!pool.IsNull() && (index < pool.Length()) &&
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index 368f70b..90ebf99 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -2446,6 +2446,9 @@
 
   // The owner of this field, which can be either a Library or a
   // Class.
+  //
+  // Note: the location of `owner` may not agree with `location` if this is a field
+  // from a mixin application, patched class, etc.
   @Object owner;
 
   // The declared type of this field.
@@ -2464,6 +2467,9 @@
   bool static;
 
   // The location of this field in the source code.
+  //
+  // Note: this may not agree with the location of `owner` if this is a field
+  // from a mixin application, patched class, etc.
   SourceLocation location [optional];
 }
 ```
@@ -2477,6 +2483,9 @@
 
   // The owner of this field, which can be either a Library or a
   // Class.
+  //
+  // Note: the location of `owner` may not agree with `location` if this is a field
+  // from a mixin application, patched class, etc.
   @Object owner;
 
   // The declared type of this field.
@@ -2495,6 +2504,9 @@
   bool static;
 
   // The location of this field in the source code.
+  //
+  // Note: this may not agree with the location of `owner` if this is a field
+  // from a mixin application, patched class, etc.
   SourceLocation location [optional];
 
   // The value of this field, if the field is static. If uninitialized,
@@ -2561,6 +2573,10 @@
   string name;
 
   // The owner of this function, which can be a Library, Class, or a Function.
+  //
+  // Note: the location of `owner` may not agree with `location` if this is a
+  // function from a mixin application, expression evaluation, patched class,
+  // etc.
   @Library|@Class|@Function owner;
 
   // Is this function static?
@@ -2573,6 +2589,9 @@
   bool implicit;
 
   // The location of this function in the source code.
+  //
+  // Note: this may not agree with the location of `owner` if this is a function
+  // from a mixin application, expression evaluation, patched class, etc.
   SourceLocation location [optional];
 }
 ```
@@ -2586,6 +2605,10 @@
   string name;
 
   // The owner of this function, which can be a Library, Class, or a Function.
+  //
+  // Note: the location of `owner` may not agree with `location` if this is a
+  // function from a mixin application, expression evaluation, patched class,
+  // etc.
   @Library|@Class|@Function owner;
 
   // Is this function static?
@@ -2598,6 +2621,9 @@
   bool implicit;
 
   // The location of this function in the source code.
+  //
+  // Note: this may not agree with the location of `owner` if this is a function
+  // from a mixin application, expression evaluation, patched class, etc.
   SourceLocation location [optional];
 
   // The signature of the function.
diff --git a/runtime/vm/stack_trace.cc b/runtime/vm/stack_trace.cc
index eee21f8..4c7cbcf 100644
--- a/runtime/vm/stack_trace.cc
+++ b/runtime/vm/stack_trace.cc
@@ -71,7 +71,7 @@
       future_listener_class(Class::Handle(zone)),
       async_start_stream_controller_class(Class::Handle(zone)),
       stream_controller_class(Class::Handle(zone)),
-      sync_stream_controller_class(Class::Handle(zone)),
+      async_stream_controller_class(Class::Handle(zone)),
       controller_subscription_class(Class::Handle(zone)),
       buffering_stream_subscription_class(Class::Handle(zone)),
       stream_iterator_class(Class::Handle(zone)),
@@ -100,9 +100,9 @@
   stream_controller_class =
       async_lib.LookupClassAllowPrivate(Symbols::_StreamController());
   ASSERT(!stream_controller_class.IsNull());
-  sync_stream_controller_class =
-      async_lib.LookupClassAllowPrivate(Symbols::_SyncStreamController());
-  ASSERT(!sync_stream_controller_class.IsNull());
+  async_stream_controller_class =
+      async_lib.LookupClassAllowPrivate(Symbols::_AsyncStreamController());
+  ASSERT(!async_stream_controller_class.IsNull());
   controller_subscription_class =
       async_lib.LookupClassAllowPrivate(Symbols::_ControllerSubscription());
   ASSERT(!controller_subscription_class.IsNull());
@@ -171,7 +171,7 @@
   const Instance& controller = Instance::Cast(context_entry_);
   controller_ = controller.GetField(controller_controller_field);
   ASSERT(!controller_.IsNull());
-  ASSERT(controller_.GetClassId() == sync_stream_controller_class.id());
+  ASSERT(controller_.GetClassId() == async_stream_controller_class.id());
 
   // Get the _StreamController._state field.
   state_ = Instance::Cast(controller_).GetField(state_field);
@@ -209,7 +209,7 @@
     // contains the iterator's value. In that case we cannot unwind anymore.
     //
     // Notice: With correct async* semantics this may never be true: The async*
-    // generator should only be invoked to produce a value if there's an
+    // generator should only be invoked to produce a vaue if there's an
     // in-progress `await streamIterator.moveNext()` call. Once such call has
     // finished the async* generator should be paused/yielded until the next
     // such call - and being paused/yielded means it should not appear in stack
diff --git a/runtime/vm/stack_trace.h b/runtime/vm/stack_trace.h
index 58a4cba..0683cf7 100644
--- a/runtime/vm/stack_trace.h
+++ b/runtime/vm/stack_trace.h
@@ -78,7 +78,7 @@
   Class& future_listener_class;
   Class& async_start_stream_controller_class;
   Class& stream_controller_class;
-  Class& sync_stream_controller_class;
+  Class& async_stream_controller_class;
   Class& controller_subscription_class;
   Class& buffering_stream_subscription_class;
   Class& stream_iterator_class;
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index f96d8d3..52ec048 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -278,6 +278,7 @@
   V(Values, "values")                                                          \
   V(WeakSerializationReference, "WeakSerializationReference")                  \
   V(_AsyncStarStreamController, "_AsyncStarStreamController")                  \
+  V(_AsyncStreamController, "_AsyncStreamController")                          \
   V(_BufferingStreamSubscription, "_BufferingStreamSubscription")              \
   V(_ByteBuffer, "_ByteBuffer")                                                \
   V(_ByteBufferDot_New, "_ByteBuffer._New")                                    \
@@ -380,7 +381,6 @@
   V(_StreamIterator, "_StreamIterator")                                        \
   V(_String, "String")                                                         \
   V(_SyncIterator, "_SyncIterator")                                            \
-  V(_SyncStreamController, "_SyncStreamController")                            \
   V(_TransferableTypedDataImpl, "_TransferableTypedDataImpl")                  \
   V(_Type, "_Type")                                                            \
   V(_FunctionType, "_FunctionType")                                            \
diff --git a/sdk/lib/_internal/vm/lib/async_patch.dart b/sdk/lib/_internal/vm/lib/async_patch.dart
index 9fddad2..2e322f1 100644
--- a/sdk/lib/_internal/vm/lib/async_patch.dart
+++ b/sdk/lib/_internal/vm/lib/async_patch.dart
@@ -117,13 +117,6 @@
   bool isSuspendedAtYield = false;
   _Future? cancellationFuture = null;
 
-  /// Argument passed to the generator when it is resumed after an addStream.
-  ///
-  /// `true` if the generator should exit after `yield*` resumes.
-  /// `false` if the generator should continue after `yield*` resumes.
-  /// `null` otherwies.
-  bool? continuationArgument = null;
-
   Stream<T> get stream {
     final Stream<T> local = controller.stream;
     if (local is _StreamImpl<T>) {
@@ -135,8 +128,7 @@
   void runBody() {
     isScheduled = false;
     isSuspendedAtYield = false;
-    asyncStarBody(continuationArgument, null);
-    continuationArgument = null;
+    asyncStarBody(null, null);
   }
 
   void scheduleGenerator() {
@@ -160,11 +152,11 @@
   bool add(T event) {
     if (!onListenReceived) _fatal("yield before stream is listened to");
     if (isSuspendedAtYield) _fatal("unexpected yield");
-    controller.add(event);
+    // If stream is cancelled, tell caller to exit the async generator.
     if (!controller.hasListener) {
       return true;
     }
-
+    controller.add(event);
     scheduleGenerator();
     isSuspendedAtYield = true;
     return false;
@@ -173,41 +165,22 @@
   // Adds the elements of stream into this controller's stream.
   // The generator will be scheduled again when all of the
   // elements of the added stream have been consumed.
-  void addStream(Stream<T> stream) {
+  // Returns true if the caller should terminate
+  // execution of the generator.
+  bool addStream(Stream<T> stream) {
     if (!onListenReceived) _fatal("yield before stream is listened to");
-
-    if (exitAfterYieldStarIfCancelled()) return;
-
+    // If stream is cancelled, tell caller to exit the async generator.
+    if (!controller.hasListener) return true;
     isAdding = true;
-    final whenDoneAdding = controller.addStream(stream, cancelOnError: false);
+    var whenDoneAdding = controller.addStream(stream, cancelOnError: false);
     whenDoneAdding.then((_) {
       isAdding = false;
-      if (exitAfterYieldStarIfCancelled()) return;
-      resumeNormallyAfterYieldStar();
-    });
-  }
-
-  /// Schedules the generator to exit after `yield*` if stream was cancelled.
-  ///
-  /// Returns `true` if generator is told to exit and `false` otherwise.
-  bool exitAfterYieldStarIfCancelled() {
-    // If consumer cancelled subscription we should tell async* generator to
-    // finish (i.e. run finally clauses and return).
-    if (!controller.hasListener) {
-      continuationArgument = true;
       scheduleGenerator();
-      return true;
-    }
+      if (!isScheduled) isSuspendedAtYield = true;
+    });
     return false;
   }
 
-  /// Schedules the generator to resume normally after `yield*`.
-  void resumeNormallyAfterYieldStar() {
-    continuationArgument = false;
-    scheduleGenerator();
-    if (!isScheduled) isSuspendedAtYield = true;
-  }
-
   void addError(Object error, StackTrace stackTrace) {
     // TODO(40614): Remove once non-nullability is sound.
     ArgumentError.checkNotNull(error, "error");
@@ -238,7 +211,7 @@
   }
 
   _AsyncStarStreamController(this.asyncStarBody)
-      : controller = new StreamController(sync: true) {
+      : controller = new StreamController() {
     controller.onListen = this.onListen;
     controller.onResume = this.onResume;
     controller.onCancel = this.onCancel;
diff --git a/tests/language/async_star/pause2_test.dart b/tests/language/async_star/pause2_test.dart
index 3df0223..a240d3d 100644
--- a/tests/language/async_star/pause2_test.dart
+++ b/tests/language/async_star/pause2_test.dart
@@ -72,8 +72,8 @@
     f() async* {
       int i = 0;
       while (true) {
-        list.add(i);
         yield i;
+        list.add(i);
         i++;
       }
     }
diff --git a/tests/language/async_star/throw_in_catch_test.dart b/tests/language/async_star/throw_in_catch_test.dart
index 7509a00..88982e5 100644
--- a/tests/language/async_star/throw_in_catch_test.dart
+++ b/tests/language/async_star/throw_in_catch_test.dart
@@ -115,7 +115,7 @@
 test() async {
   // TODO(sigurdm): These tests are too dependent on scheduling, and buffering
   // behavior.
-  await runTest(foo1, "abcYgC", null, true);
+  await runTest(foo1, "abcYdgC", null, true);
   await runTest(foo2, "abcX", "Error", false);
   await runTest(foo3, "abcYX", "Error", false);
   await runTest(foo4, "abcYdYefX", "Error2", false);
diff --git a/tests/language_2/async_star/pause2_test.dart b/tests/language_2/async_star/pause2_test.dart
index f6e8d5f..11e0429 100644
--- a/tests/language_2/async_star/pause2_test.dart
+++ b/tests/language_2/async_star/pause2_test.dart
@@ -74,8 +74,8 @@
     f() async* {
       int i = 0;
       while (true) {
-        list.add(i);
         yield i;
+        list.add(i);
         i++;
       }
     }
diff --git a/tests/language_2/async_star/throw_in_catch_test.dart b/tests/language_2/async_star/throw_in_catch_test.dart
index 6a26245..57b6b0e 100644
--- a/tests/language_2/async_star/throw_in_catch_test.dart
+++ b/tests/language_2/async_star/throw_in_catch_test.dart
@@ -118,7 +118,7 @@
 test() async {
   // TODO(sigurdm): These tests are too dependent on scheduling, and buffering
   // behavior.
-  await runTest(foo1, "abcYgC", null, true);
+  await runTest(foo1, "abcYdgC", null, true);
   await runTest(foo2, "abcX", "Error", false);
   await runTest(foo3, "abcYX", "Error", false);
   await runTest(foo4, "abcYdYefX", "Error2", false);
diff --git a/tools/VERSION b/tools/VERSION
index f29c189..a082332 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 17
 PATCH 0
-PRERELEASE 281
+PRERELEASE 282
 PRERELEASE_PATCH 0
\ No newline at end of file