Version 2.13.0-81.0.dev

Merge commit '8c7e873f8f1a8ec83095732f4afab3bda444fb71' into 'dev'
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index cba63c1..a203927 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -11,7 +11,7 @@
     "constraint, update this by running tools/generate_package_config.dart."
   ],
   "configVersion": 2,
-  "generated": "2021-02-24T07:33:35.310314",
+  "generated": "2021-02-25T12:53:17.111860",
   "generator": "tools/generate_package_config.dart",
   "packages": [
     {
@@ -327,7 +327,7 @@
       "name": "http_multi_server",
       "rootUri": "../third_party/pkg/http_multi_server",
       "packageUri": "lib/",
-      "languageVersion": "2.1"
+      "languageVersion": "2.12"
     },
     {
       "name": "http_parser",
diff --git a/DEPS b/DEPS
index b71fa4d..31d2194 100644
--- a/DEPS
+++ b/DEPS
@@ -108,7 +108,7 @@
   "glob_rev": "a62acf590598f458d3198d9f2930c1c9dd4b1379",
   "html_rev": "00cd3c22dac0e68e6ed9e7e4945101aedb1b3109",
   "http_io_rev": "2fa188caf7937e313026557713f7feffedd4978b",
-  "http_multi_server_rev" : "e8c8be7f15b4fb50757ff5bf29766721fbe24fe4",
+  "http_multi_server_rev" : "6bf4b6e5d4d890e6d54559b858ff229d79711171",
   "http_parser_rev": "5dd4d16693242049dfb43b5efa429fedbf932e98",
   "http_retry_tag": "0.1.1",
   "http_rev": "d5c678cd63c3e9c1d779a09acfa95b7e3af84665",
@@ -168,7 +168,7 @@
   "web_components_rev": "8f57dac273412a7172c8ade6f361b407e2e4ed02",
   "web_socket_channel_rev": "76931ea1b81ba71e8319330c35285d3e88566315",
   "WebCore_rev": "fb11e887f77919450e497344da570d780e078bc8",
-  "yaml_rev": "2392d113b0104dd19358f2833a282f19e2d67c01",
+  "yaml_rev": "b4c4411631bda556ce9a45af1ab0eecaf9f3ac53",
   "zlib_rev": "bf44340d1b6be1af8950bbdf664fec0cf5a831cc",
   "crashpad_rev": "bf327d8ceb6a669607b0dbab5a83a275d03f99ed",
   "minichromium_rev": "8d641e30a8b12088649606b912c2bc4947419ccc",
diff --git a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
index b820eb7..f46c760 100644
--- a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
@@ -2388,6 +2388,8 @@
       DemoteViaForEachVariableWrite<Variable, Node> reason);
 
   R visitPropertyNotPromoted(PropertyNotPromoted reason);
+
+  R visitThisNotPromoted(ThisNotPromoted reason);
 }
 
 /// Non-promotion reason describing the situation where an expression was not
@@ -2622,6 +2624,19 @@
   }
 }
 
+/// Non-promotion reason describing the situation where an expression was not
+/// promoted due to the fact that it's a reference to `this`.
+class ThisNotPromoted extends NonPromotionReason {
+  @override
+  String get shortName => 'thisNotPromoted';
+
+  @override
+  R accept<R, Node extends Object, Expression extends Object,
+              Variable extends Object>(
+          NonPromotionReasonVisitor<R, Node, Expression, Variable> visitor) =>
+      visitor.visitThisNotPromoted(this);
+}
+
 /// Enum representing the different classifications of types that can be
 /// returned by [TypeOperations.classifyType].
 enum TypeClassification {
@@ -5099,8 +5114,14 @@
   Map<Type, NonPromotionReason> getNonPromotionReasons(
       Map<Variable?, VariableModel<Variable, Type>> variableInfo,
       TypeOperations<Variable, Type> typeOperations) {
-    // TODO(paulberry): implement.
-    return {};
+    Map<Type, NonPromotionReason> result = <Type, NonPromotionReason>{};
+    List<Type>? promotedTypes = _getInfo(variableInfo)?.promotedTypes;
+    if (promotedTypes != null) {
+      for (Type type in promotedTypes) {
+        result[type] = new ThisNotPromoted();
+      }
+    }
+    return result;
   }
 
   @override
diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
index cb6ab3e..d77d6dc 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
@@ -8928,6 +8928,13 @@
     tip: r"""Try replacing '?.' with '.'""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeThisNotPromoted = messageThisNotPromoted;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageThisNotPromoted = const MessageCode("ThisNotPromoted",
+    message: r"""'this' can't be promoted.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<Message Function(String string)>
     templateThisOrSuperAccessInFieldInitializer =
     const Template<Message Function(String string)>(
diff --git a/pkg/_fe_analyzer_shared/pubspec.yaml b/pkg/_fe_analyzer_shared/pubspec.yaml
index e0c94c5..9d64fc8 100644
--- a/pkg/_fe_analyzer_shared/pubspec.yaml
+++ b/pkg/_fe_analyzer_shared/pubspec.yaml
@@ -1,5 +1,5 @@
 name: _fe_analyzer_shared
-version: 16.0.0
+version: 17.0.0
 description: Logic that is shared between the front_end and analyzer packages.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/_fe_analyzer_shared
 
diff --git a/pkg/analysis_server/lib/src/analysis_server_abstract.dart b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
index f7d620e..5b32212 100644
--- a/pkg/analysis_server/lib/src/analysis_server_abstract.dart
+++ b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
@@ -234,10 +234,13 @@
     if (drivers.isNotEmpty) {
       // Sort the drivers so that more deeply nested contexts will be checked
       // before enclosing contexts.
-      drivers.sort((first, second) =>
-          second.contextRoot.root.length - first.contextRoot.root.length);
+      drivers.sort((first, second) {
+        var firstRoot = first.analysisContext.contextRoot.root.path;
+        var secondRoot = second.analysisContext.contextRoot.root.path;
+        return secondRoot.length - firstRoot.length;
+      });
       var driver = drivers.firstWhere(
-          (driver) => driver.contextRoot.containsFile(path),
+          (driver) => driver.analysisContext.contextRoot.isAnalyzed(path),
           orElse: () => null);
       driver ??= drivers.firstWhere(
           (driver) => driver.knownFiles.contains(path),
diff --git a/pkg/analysis_server/lib/src/domain_analysis.dart b/pkg/analysis_server/lib/src/domain_analysis.dart
index 8f0c867..9785016 100644
--- a/pkg/analysis_server/lib/src/domain_analysis.dart
+++ b/pkg/analysis_server/lib/src/domain_analysis.dart
@@ -156,8 +156,10 @@
       //
       var requestParams =
           plugin.AnalysisGetNavigationParams(file, offset, length);
-      var pluginFutures = server.pluginManager
-          .broadcastRequest(requestParams, contextRoot: driver.contextRoot);
+      var pluginFutures = server.pluginManager.broadcastRequest(
+        requestParams,
+        contextRoot: driver.analysisContext.contextRoot,
+      );
       //
       // Compute navigation data generated by server.
       //
diff --git a/pkg/analysis_server/lib/src/domain_completion.dart b/pkg/analysis_server/lib/src/domain_completion.dart
index c77e04a..a9c9aa1 100644
--- a/pkg/analysis_server/lib/src/domain_completion.dart
+++ b/pkg/analysis_server/lib/src/domain_completion.dart
@@ -84,8 +84,10 @@
     var driver = server.getAnalysisDriver(file);
     if (driver != null) {
       requestParams = plugin.CompletionGetSuggestionsParams(file, offset);
-      pluginFutures = server.pluginManager
-          .broadcastRequest(requestParams, contextRoot: driver.contextRoot);
+      pluginFutures = server.pluginManager.broadcastRequest(
+        requestParams,
+        contextRoot: driver.analysisContext.contextRoot,
+      );
     }
     //
     // Compute completions generated by server.
diff --git a/pkg/analysis_server/lib/src/domain_kythe.dart b/pkg/analysis_server/lib/src/domain_kythe.dart
index a67e02a..26e4788 100644
--- a/pkg/analysis_server/lib/src/domain_kythe.dart
+++ b/pkg/analysis_server/lib/src/domain_kythe.dart
@@ -34,8 +34,10 @@
       // Allow plugins to start computing entries.
       //
       var requestParams = plugin.KytheGetKytheEntriesParams(file);
-      var pluginFutures = server.pluginManager
-          .broadcastRequest(requestParams, contextRoot: driver.contextRoot);
+      var pluginFutures = server.pluginManager.broadcastRequest(
+        requestParams,
+        contextRoot: driver.analysisContext.contextRoot,
+      );
       //
       // Compute entries generated by server.
       //
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index a2849de..9c223e0 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -215,8 +215,10 @@
     if (driver == null) {
       pluginFutures = <PluginInfo, Future<plugin.Response>>{};
     } else {
-      pluginFutures = server.pluginManager
-          .broadcastRequest(requestParams, contextRoot: driver.contextRoot);
+      pluginFutures = server.pluginManager.broadcastRequest(
+        requestParams,
+        contextRoot: driver.analysisContext.contextRoot,
+      );
     }
 
     //
@@ -273,8 +275,10 @@
     if (driver == null) {
       pluginFutures = <PluginInfo, Future<plugin.Response>>{};
     } else {
-      pluginFutures = server.pluginManager
-          .broadcastRequest(requestParams, contextRoot: driver.contextRoot);
+      pluginFutures = server.pluginManager.broadcastRequest(
+        requestParams,
+        contextRoot: driver.analysisContext.contextRoot,
+      );
     }
     //
     // Compute fixes associated with server-generated errors.
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.dart
index 1aac9f8..de9cb07 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.dart
@@ -135,7 +135,7 @@
       // analysis root. We need to register it even if we found a driver, so that if
       // the driver existed only because of another open file, it will not be removed
       // when that file is closed.
-      final analysisRoot = driver?.contextRoot?.root ??
+      final analysisRoot = driver?.analysisContext?.contextRoot?.root?.path ??
           _findProjectFolder(server.resourceProvider, path) ??
           dirname(path);
       if (analysisRoot != null) {
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart b/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
index 96db148..0835da5 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
@@ -99,8 +99,10 @@
     int timeout = 500,
   }) {
     final driver = server.getAnalysisDriver(path);
-    final pluginFutures = server.pluginManager
-        .broadcastRequest(params, contextRoot: driver.contextRoot);
+    final pluginFutures = server.pluginManager.broadcastRequest(
+      params,
+      contextRoot: driver.analysisContext.contextRoot,
+    );
 
     return waitForResponses(pluginFutures,
         requestParameters: params, timeout: timeout);
diff --git a/pkg/analysis_server/lib/src/plugin/plugin_manager.dart b/pkg/analysis_server/lib/src/plugin/plugin_manager.dart
index 2b23663..ccb5df1 100644
--- a/pkg/analysis_server/lib/src/plugin/plugin_manager.dart
+++ b/pkg/analysis_server/lib/src/plugin/plugin_manager.dart
@@ -8,10 +8,10 @@
 import 'dart:io' show Platform, Process;
 
 import 'package:analysis_server/src/plugin/notification_manager.dart';
+import 'package:analyzer/dart/analysis/context_root.dart' as analyzer;
 import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
-import 'package:analyzer/src/context/context_root.dart' as analyzer;
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/util/glob.dart';
@@ -171,7 +171,7 @@
   /// the file with the given [filePath].
   bool isAnalyzing(String filePath) {
     for (var contextRoot in contextRoots) {
-      if (contextRoot.containsFile(filePath)) {
+      if (contextRoot.isAnalyzed(filePath)) {
         return true;
       }
     }
@@ -236,8 +236,8 @@
     if (currentSession != null) {
       var params = AnalysisSetContextRootsParams(contextRoots
           .map((analyzer.ContextRoot contextRoot) => ContextRoot(
-              contextRoot.root, contextRoot.exclude,
-              optionsFile: contextRoot.optionsFilePath))
+              contextRoot.root.path, contextRoot.excludedPaths.toList(),
+              optionsFile: contextRoot.optionsFile?.path))
           .toList());
       currentSession.sendRequest(params);
     }
diff --git a/pkg/analysis_server/lib/src/plugin/plugin_watcher.dart b/pkg/analysis_server/lib/src/plugin/plugin_watcher.dart
index 1b8391c..7eab2f2 100644
--- a/pkg/analysis_server/lib/src/plugin/plugin_watcher.dart
+++ b/pkg/analysis_server/lib/src/plugin/plugin_watcher.dart
@@ -6,8 +6,8 @@
 
 import 'package:analysis_server/src/plugin/plugin_locator.dart';
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
+import 'package:analyzer/dart/analysis/context_root.dart';
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/context/context_root.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/sdk/sdk.dart';
 
@@ -37,9 +37,10 @@
   /// method must be called before the driver has been allowed to perform any
   /// analysis.
   @override
-  void addedDriver(AnalysisDriver driver, ContextRoot contextRoot) {
+  void addedDriver(AnalysisDriver driver) {
+    var contextRoot = driver.analysisContext.contextRoot;
     _driverInfo[driver] = _DriverInfo(
-        contextRoot, <String>[contextRoot.root, _getSdkPath(driver)]);
+        contextRoot, <String>[contextRoot.root.path, _getSdkPath(driver)]);
     var enabledPlugins = driver.analysisOptions.enabledPluginNames;
     for (var hostPackageName in enabledPlugins) {
       //
@@ -64,7 +65,8 @@
           // TODO(brianwilkerson) Do we need to wait for the plugin to be added?
           // If we don't, then tests don't have any way to know when to expect
           // that the list of plugins has been updated.
-          manager.addPluginToContextRoot(contextRoot, pluginPath);
+          manager.addPluginToContextRoot(
+              driver.analysisContext.contextRoot, pluginPath);
         }
       }
     }
@@ -77,7 +79,7 @@
     if (info == null) {
       throw StateError('Cannot remove a driver that was not added');
     }
-    manager.removedContextRoot(info.contextRoot);
+    manager.removedContextRoot(driver.analysisContext.contextRoot);
     _driverInfo.remove(driver);
   }
 
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_if_else_with_conditional.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_if_else_with_conditional.dart
index da0961c..85e9599 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_if_else_with_conditional.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_if_else_with_conditional.dart
@@ -28,52 +28,41 @@
     if (thenStatement == null || elseStatement == null) {
       return;
     }
-    Expression thenExpression;
-    Expression elseExpression;
-    var hasReturnStatements = false;
+
     if (thenStatement is ReturnStatement && elseStatement is ReturnStatement) {
-      hasReturnStatements = true;
-      thenExpression = thenStatement.expression;
-      elseExpression = elseStatement.expression;
-    }
-    var hasExpressionStatements = false;
-    if (thenStatement is ExpressionStatement &&
-        elseStatement is ExpressionStatement) {
-      if (thenStatement.expression is AssignmentExpression &&
-          elseStatement.expression is AssignmentExpression) {
-        hasExpressionStatements = true;
-        thenExpression = thenStatement.expression;
-        elseExpression = elseStatement.expression;
+      var thenExpression = thenStatement.expression;
+      var elseExpression = elseStatement.expression;
+      if (thenExpression != null && elseExpression != null) {
+        await builder.addDartFileEdit(file, (builder) {
+          var conditionSrc = utils.getNodeText(ifStatement.condition);
+          var thenSrc = utils.getNodeText(thenExpression);
+          var elseSrc = utils.getNodeText(elseExpression);
+          builder.addSimpleReplacement(range.node(ifStatement),
+              'return $conditionSrc ? $thenSrc : $elseSrc;');
+        });
       }
     }
 
-    if (hasReturnStatements || hasExpressionStatements) {
-      await builder.addDartFileEdit(file, (builder) {
-        // returns
-        if (hasReturnStatements) {
-          var conditionSrc = utils.getNodeText(ifStatement.condition);
-          var theSrc = utils.getNodeText(thenExpression);
-          var elseSrc = utils.getNodeText(elseExpression);
-          builder.addSimpleReplacement(range.node(ifStatement),
-              'return $conditionSrc ? $theSrc : $elseSrc;');
-        }
-        // assignments -> v = Conditional;
-        if (hasExpressionStatements) {
-          AssignmentExpression thenAssignment = thenExpression;
-          AssignmentExpression elseAssignment = elseExpression;
+    if (thenStatement is ExpressionStatement &&
+        elseStatement is ExpressionStatement) {
+      var thenAssignment = thenStatement.expression;
+      var elseAssignment = elseStatement.expression;
+      if (thenAssignment is AssignmentExpression &&
+          elseAssignment is AssignmentExpression) {
+        await builder.addDartFileEdit(file, (builder) {
           var thenTarget = utils.getNodeText(thenAssignment.leftHandSide);
           var elseTarget = utils.getNodeText(elseAssignment.leftHandSide);
           if (thenAssignment.operator.type == TokenType.EQ &&
               elseAssignment.operator.type == TokenType.EQ &&
               thenTarget == elseTarget) {
             var conditionSrc = utils.getNodeText(ifStatement.condition);
-            var theSrc = utils.getNodeText(thenAssignment.rightHandSide);
+            var thenSrc = utils.getNodeText(thenAssignment.rightHandSide);
             var elseSrc = utils.getNodeText(elseAssignment.rightHandSide);
             builder.addSimpleReplacement(range.node(ifStatement),
-                '$thenTarget = $conditionSrc ? $theSrc : $elseSrc;');
+                '$thenTarget = $conditionSrc ? $thenSrc : $elseSrc;');
           }
-        }
-      });
+        });
+      }
     }
   }
 
diff --git a/pkg/analysis_server/lib/src/services/refactoring/move_file.dart b/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
index 9b8bf70..9e5cf33 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
@@ -40,21 +40,25 @@
 
   @override
   Future<RefactoringStatus> checkFinalConditions() async {
-    final drivers = refactoringWorkspace.driversContaining(oldFile);
-    if (drivers.length != 1) {
-      if (refactoringWorkspace.drivers
-          .any((d) => pathContext.equals(d.contextRoot.root, oldFile))) {
+    for (var driver in refactoringWorkspace.drivers) {
+      var rootPath = driver.analysisContext.contextRoot.root.path;
+      if (pathContext.equals(rootPath, oldFile)) {
         return RefactoringStatus.fatal(
             'Renaming an analysis root is not supported ($oldFile)');
-      } else {
-        return RefactoringStatus.fatal(
-            '$oldFile does not belong to an analysis root.');
       }
     }
+
+    final drivers = refactoringWorkspace.driversContaining(oldFile);
+    if (drivers.length != 1) {
+      return RefactoringStatus.fatal(
+          '$oldFile does not belong to an analysis root.');
+    }
+
     driver = drivers.first;
     if (!driver.resourceProvider.getFile(oldFile).exists) {
       return RefactoringStatus.fatal('$oldFile does not exist.');
     }
+
     return RefactoringStatus();
   }
 
diff --git a/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart b/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
index f3c0136..9d2e00f 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
@@ -304,14 +304,14 @@
   /// Whether the file with the given [path] is in a context root.
   bool containsFile(String path) {
     return drivers.any((driver) {
-      return driver.contextRoot.containsFile(path);
+      return driver.analysisContext.contextRoot.isAnalyzed(path);
     });
   }
 
   /// Returns the drivers that have [path] in a context root.
   Iterable<AnalysisDriver> driversContaining(String path) {
     return drivers.where((driver) {
-      return driver.contextRoot.containsFile(path);
+      return driver.analysisContext.contextRoot.isAnalyzed(path);
     });
   }
 }
diff --git a/pkg/analysis_server/lib/src/status/diagnostics.dart b/pkg/analysis_server/lib/src/status/diagnostics.dart
index 0dee453..da5a030 100644
--- a/pkg/analysis_server/lib/src/status/diagnostics.dart
+++ b/pkg/analysis_server/lib/src/status/diagnostics.dart
@@ -21,7 +21,7 @@
 import 'package:analysis_server/src/status/element_writer.dart';
 import 'package:analysis_server/src/status/pages.dart';
 import 'package:analysis_server/src/utilities/profiling.dart';
-import 'package:analyzer/src/context/context_root.dart';
+import 'package:analyzer/dart/analysis/context_root.dart';
 import 'package:analyzer/src/context/source.dart';
 import 'package:analyzer/src/dart/sdk/sdk.dart';
 import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
@@ -480,8 +480,10 @@
     buf.writeln('</div>');
 
     buf.writeln(writeOption('Context location', escape(contextPath)));
-    buf.writeln(writeOption('Analysis options path',
-        escape(driver.contextRoot.optionsFilePath ?? 'none')));
+    buf.writeln(writeOption(
+        'Analysis options path',
+        escape(
+            driver.analysisContext?.contextRoot?.optionsFile?.path ?? 'none')));
     buf.writeln(
         writeOption('SDK root', escape(driver.analysisContext.sdkRoot?.path)));
 
diff --git a/pkg/analysis_server/lib/src/utilities/mocks.dart b/pkg/analysis_server/lib/src/utilities/mocks.dart
index 97d5420..9775fee 100644
--- a/pkg/analysis_server/lib/src/utilities/mocks.dart
+++ b/pkg/analysis_server/lib/src/utilities/mocks.dart
@@ -9,9 +9,9 @@
 import 'package:analysis_server/src/channel/channel.dart';
 import 'package:analysis_server/src/plugin/notification_manager.dart';
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
+import 'package:analyzer/dart/analysis/context_root.dart' as analyzer;
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
-import 'package:analyzer/src/context/context_root.dart' as analyzer;
 import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
 import 'package:analyzer_plugin/src/protocol/protocol_internal.dart' as plugin;
diff --git a/pkg/analysis_server/test/domain_analysis_test.dart b/pkg/analysis_server/test/domain_analysis_test.dart
index 7849c51..9266e21 100644
--- a/pkg/analysis_server/test/domain_analysis_test.dart
+++ b/pkg/analysis_server/test/domain_analysis_test.dart
@@ -1225,7 +1225,7 @@
     var a_path = '$testPackageLibPath/a.dart';
     var b_path = '$testPackageLibPath/b.dart';
 
-    newOptionsFile(testPackageRootPath, content: '''
+    newAnalysisOptionsYamlFile(testPackageRootPath, content: '''
 analyzer:
   exclude:
     - "**/b.dart"
diff --git a/pkg/analysis_server/test/edit/bulk_fixes_test.dart b/pkg/analysis_server/test/edit/bulk_fixes_test.dart
index 6709373..1c9b46b 100644
--- a/pkg/analysis_server/test/edit/bulk_fixes_test.dart
+++ b/pkg/analysis_server/test/edit/bulk_fixes_test.dart
@@ -92,7 +92,7 @@
 
     // Sub-project.
     var subprojectRoot = '$projectPath/test/data/subproject';
-    newOptionsFile(subprojectRoot, content: '''
+    newAnalysisOptionsYamlFile(subprojectRoot, content: '''
 linter:
   rules:
     - annotate_overrides
@@ -116,7 +116,7 @@
 
   Future<void> test_annotateOverrides_subProject() async {
     var subprojectRoot = '$projectPath/test/data/subproject';
-    newOptionsFile(subprojectRoot, content: '''
+    newAnalysisOptionsYamlFile(subprojectRoot, content: '''
 linter:
   rules:
     - annotate_overrides
diff --git a/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart b/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
index 5a00d64..87241b1 100644
--- a/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
+++ b/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
@@ -8,8 +8,9 @@
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
-import 'package:analyzer/src/context/context_root.dart';
+import 'package:analyzer/src/dart/analysis/context_root.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:analyzer/src/workspace/basic.dart';
 import 'package:analyzer_plugin/channel/channel.dart';
 import 'package:analyzer_plugin/protocol/protocol.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
@@ -31,8 +32,13 @@
   });
 }
 
-ContextRoot _newContextRoot(String root, {List<String> exclude = const []}) {
-  return ContextRoot(root, exclude, pathContext: path.context);
+ContextRootImpl _newContextRoot(String root) {
+  var resourceProvider = PhysicalResourceProvider.INSTANCE;
+  return ContextRootImpl(
+    resourceProvider,
+    resourceProvider.getFolder(root),
+    BasicWorkspace.find(resourceProvider, {}, root),
+  );
 }
 
 @reflectiveTest
@@ -121,7 +127,8 @@
   void test_addContextRoot() {
     var optionsFilePath = '/pkg1/analysis_options.yaml';
     var contextRoot1 = _newContextRoot('/pkg1');
-    contextRoot1.optionsFilePath = optionsFilePath;
+    contextRoot1.optionsFile =
+        contextRoot1.resourceProvider.getFile(optionsFilePath);
     var session = PluginSession(plugin);
     var channel = TestServerCommunicationChannel(session);
     plugin.currentSession = session;
diff --git a/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart b/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
index 7fbb0e6..361cd03 100644
--- a/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
+++ b/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
@@ -7,19 +7,15 @@
 import 'package:analysis_server/src/plugin/plugin_locator.dart';
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
 import 'package:analysis_server/src/plugin/plugin_watcher.dart';
-import 'package:analyzer/dart/analysis/results.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/src/context/context_root.dart';
+import 'package:analyzer/dart/analysis/context_root.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
-import 'package:analyzer/src/dart/analysis/session.dart';
 import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/source/package_map_resolver.dart';
-import 'package:analyzer/src/test_utilities/mock_sdk.dart';
-import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:analyzer/src/test_utilities/package_config_file_builder.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../../abstract_context.dart';
+
 void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(PluginWatcherTest);
@@ -27,29 +23,35 @@
 }
 
 @reflectiveTest
-class PluginWatcherTest with ResourceProviderMixin {
+class PluginWatcherTest extends AbstractContextTest {
   TestPluginManager manager;
   PluginWatcher watcher;
 
+  @override
   void setUp() {
+    super.setUp();
     manager = TestPluginManager();
     watcher = PluginWatcher(resourceProvider, manager);
   }
 
   Future<void> test_addedDriver() async {
-    var pkg1Path = newFolder('/pkg1').path;
-    newFile('/pkg1/lib/test1.dart');
-    newFile('/pkg2/lib/pkg2.dart');
-    newPubspecYamlFile('/pkg2', 'name: pkg2');
+    newPubspecYamlFile('/foo', 'name: foo');
     newFile(
-        '/pkg2/${PluginLocator.toolsFolderName}/${PluginLocator.defaultPluginFolderName}/bin/plugin.dart');
+      join('/foo', PluginLocator.toolsFolderName,
+          PluginLocator.defaultPluginFolderName, 'bin', 'plugin.dart'),
+    );
 
-    var contextRoot =
-        ContextRoot(pkg1Path, [], pathContext: resourceProvider.pathContext);
-    var driver = TestDriver(resourceProvider, contextRoot);
-    driver.analysisOptions.enabledPluginNames = ['pkg2'];
+    writeTestPackageConfig(
+      config: PackageConfigFileBuilder()
+        ..add(name: 'foo', rootPath: convertPath('/foo')),
+    );
+
+    var driver = driverFor(testPackageRootPath);
+    _analysisOptionsImpl(driver).enabledPluginNames = ['foo'];
+
     expect(manager.addedContextRoots, isEmpty);
-    watcher.addedDriver(driver, contextRoot);
+    watcher.addedDriver(driver);
+
     //
     // Test to see whether the listener was configured correctly.
     //
@@ -61,31 +63,19 @@
     // Use a file that imports a package with a plugin.
     //
 //    await driver.computeResult('package:pkg2/pk2.dart');
-    //
-    // Wait until the timer associated with the driver's FileSystemState is
-    // guaranteed to have expired and the list of changed files will have been
-    // delivered.
-    //
-    await Future.delayed(Duration(seconds: 1));
+
+    await _waitForEvents();
     expect(manager.addedContextRoots, hasLength(1));
   }
 
   Future<void> test_addedDriver_missingPackage() async {
-    var pkg1Path = newFolder('/pkg1').path;
-    newFile('/pkg1/lib/test1.dart');
+    var driver = driverFor(testPackageRootPath);
+    _analysisOptionsImpl(driver).enabledPluginNames = ['noSuchPackage'];
 
-    var contextRoot =
-        ContextRoot(pkg1Path, [], pathContext: resourceProvider.pathContext);
-    var driver = TestDriver(resourceProvider, contextRoot);
-    driver.analysisOptions.enabledPluginNames = ['pkg3'];
-    watcher.addedDriver(driver, contextRoot);
+    watcher.addedDriver(driver);
     expect(manager.addedContextRoots, isEmpty);
-    //
-    // Wait until the timer associated with the driver's FileSystemState is
-    // guaranteed to have expired and the list of changed files will have been
-    // delivered.
-    //
-    await Future.delayed(Duration(seconds: 1));
+
+    await _waitForEvents();
     expect(manager.addedContextRoots, isEmpty);
   }
 
@@ -95,53 +85,23 @@
   }
 
   void test_removedDriver() {
-    var pkg1Path = newFolder('/pkg1').path;
-    var contextRoot =
-        ContextRoot(pkg1Path, [], pathContext: resourceProvider.pathContext);
-    var driver = TestDriver(resourceProvider, contextRoot);
-    watcher.addedDriver(driver, contextRoot);
+    var driver = driverFor(testPackageRootPath);
+    var contextRoot = driver.analysisContext.contextRoot;
+    watcher.addedDriver(driver);
     watcher.removedDriver(driver);
     expect(manager.removedContextRoots, equals([contextRoot]));
   }
-}
 
-class TestDriver implements AnalysisDriver {
-  @override
-  final MemoryResourceProvider resourceProvider;
-
-  @override
-  SourceFactory sourceFactory;
-
-  @override
-  AnalysisSessionImpl currentSession;
-
-  @override
-  AnalysisOptionsImpl analysisOptions = AnalysisOptionsImpl();
-
-  final _resultController = StreamController<ResolvedUnitResult>();
-
-  TestDriver(this.resourceProvider, ContextRoot contextRoot) {
-    var pathContext = resourceProvider.pathContext;
-    var sdk = MockSdk(resourceProvider: resourceProvider);
-    var packageName = pathContext.basename(contextRoot.root);
-    var libPath = pathContext.join(contextRoot.root, 'lib');
-    sourceFactory = SourceFactory([
-      DartUriResolver(sdk),
-      PackageMapUriResolver(resourceProvider, {
-        packageName: [resourceProvider.getFolder(libPath)],
-        'pkg2': [
-          resourceProvider.getFolder(resourceProvider.convertPath('/pkg2/lib'))
-        ]
-      })
-    ]);
-    currentSession = AnalysisSessionImpl(this);
+  AnalysisOptionsImpl _analysisOptionsImpl(AnalysisDriver driver) {
+    return driver.analysisOptions as AnalysisOptionsImpl;
   }
 
-  @override
-  Stream<ResolvedUnitResult> get results => _resultController.stream;
-
-  @override
-  dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+  /// Wait until the timer associated with the driver's FileSystemState is
+  /// guaranteed to have expired and the list of changed files will have been
+  /// delivered.
+  Future<void> _waitForEvents() async {
+    await Future.delayed(Duration(seconds: 1));
+  }
 }
 
 class TestPluginManager implements PluginManager {
diff --git a/pkg/analysis_server/test/src/services/correction/assist/replace_if_else_with_conditional_test.dart b/pkg/analysis_server/test/src/services/correction/assist/replace_if_else_with_conditional_test.dart
index 7b8f335..7641070 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/replace_if_else_with_conditional_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/replace_if_else_with_conditional_test.dart
@@ -76,7 +76,7 @@
     await assertNoAssistAt('if (true)');
   }
 
-  Future<void> test_return() async {
+  Future<void> test_return_expression_expression() async {
     await resolveTestCode('''
 main() {
   if (true) {
@@ -92,4 +92,32 @@
 }
 ''');
   }
+
+  Future<void> test_return_expression_nothing() async {
+    verifyNoTestUnitErrors = false;
+    await resolveTestCode('''
+void f(bool c) {
+  if (c) {
+    return 111;
+  } else {
+    return;
+  }
+}
+''');
+    await assertNoAssistAt('if (c)');
+  }
+
+  Future<void> test_return_nothing_expression() async {
+    verifyNoTestUnitErrors = false;
+    await resolveTestCode('''
+void f(bool c) {
+  if (c) {
+    return;
+  } else {
+    return 222;
+  }
+}
+''');
+    await assertNoAssistAt('if (c)');
+  }
 }
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index f64e776..52181fb 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,4 +1,4 @@
-## 1.1.0-dev
+## 1.1.0
 * Deprecated `TypeProvider.futureType2()`, `iterableType2()`, etc.
   Use corresponding `TypeProvider.futureType()`, `iterableType()`, etc.
 * Remove experimental markers from Null Safety APIs.
@@ -8,6 +8,7 @@
 * Added `ContextRoot.workspace`, deprecated `AnalysisContext.workspace`.
 * Deprecated `ElementVisitor.visitFunctionTypeAliasElement()`.
   Override `ElementVisitor.visitTypeAliasElement()` instead.
+* Deprecated `FunctionTypeAliasElement`. Use `TypeAliasElement` instead.
 
 ## 1.0.0
 * Stable null safety release.
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index 77ee797..8dada5e 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -2821,6 +2821,7 @@
 /// Clients may not extend, implement or mix-in this class.
 abstract class FunctionTypeAlias implements TypeAlias {
   @override
+  // ignore: deprecated_member_use_from_same_package
   FunctionTypeAliasElement? get declaredElement;
 
   /// Return the parameters associated with the function type.
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index 91e2155..fb8ce6f 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -1205,12 +1205,14 @@
 /// when non-function type aliases are enabled by default.
 ///
 /// Clients may not extend, implement or mix-in this class.
+@Deprecated('Use TypeAliasElement instead')
 abstract class FunctionTypeAliasElement implements TypeAliasElement {
   /// Return the generic function type element representing the generic function
   /// type on the right side of the equals.
   @Deprecated('Use aliasedElement instead')
   GenericFunctionTypeElement get function;
 
+  @Deprecated('Use TypeAliasElement instead')
   @override
   FunctionType instantiate({
     required List<DartType> typeArguments,
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_root.dart b/pkg/analyzer/lib/src/dart/analysis/context_root.dart
index 830e013..4eecb80 100644
--- a/pkg/analyzer/lib/src/dart/analysis/context_root.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/context_root.dart
@@ -106,10 +106,13 @@
   /// of the [excludedPaths].
   bool _isExcluded(String path) {
     Context context = resourceProvider.pathContext;
-    String name = context.basename(path);
-    if (name.startsWith('.')) {
-      return true;
+
+    for (String pathComponent in context.split(path)) {
+      if (pathComponent.startsWith('.')) {
+        return true;
+      }
     }
+
     for (String excludedPath in excludedPaths) {
       if (context.isAbsolute(excludedPath)) {
         if (path == excludedPath || context.isWithin(excludedPath, path)) {
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 7fa0579..fcaacb9 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -133,6 +133,7 @@
   DeclaredVariables declaredVariables = DeclaredVariables();
 
   /// Information about the context root being analyzed by this driver.
+  @Deprecated('Use analysisContext instead')
   final ContextRoot? contextRoot;
 
   /// The analysis context that created this driver / session.
@@ -326,7 +327,7 @@
   Set<String> get knownFiles => _fsState.knownFilePaths;
 
   /// Return the path of the folder at the root of the context.
-  String get name => contextRoot?.root ?? '';
+  String get name => analysisContext?.contextRoot.root.path ?? '';
 
   /// Return the number of files scheduled for analysis.
   int get numberOfFilesToAnalyze => _fileTracker.numberOfPendingFiles;
@@ -505,6 +506,7 @@
   }) {
     if (analysisContext != null) {
       this.analysisContext = analysisContext;
+      _scheduler.driverWatcher?.addedDriver(this);
     }
     if (analysisOptions != null) {
       _analysisOptions = analysisOptions;
@@ -1903,8 +1905,8 @@
   void add(AnalysisDriverGeneric driver) {
     _drivers.add(driver);
     _hasWork.notify();
-    if (driver is AnalysisDriver) {
-      driverWatcher?.addedDriver(driver, driver.contextRoot);
+    if (driver is AnalysisDriver && driver.analysisContext != null) {
+      driverWatcher?.addedDriver(driver);
     }
   }
 
@@ -2113,7 +2115,7 @@
 abstract class DriverWatcher {
   /// The context manager has just added the given analysis [driver]. This method
   /// must be called before the driver has been allowed to perform any analysis.
-  void addedDriver(AnalysisDriver driver, ContextRoot? contextRoot);
+  void addedDriver(AnalysisDriver driver);
 
   /// The context manager has just removed the given analysis [driver].
   void removedDriver(AnalysisDriver driver);
diff --git a/pkg/analyzer/lib/src/dart/analysis/uri_converter.dart b/pkg/analyzer/lib/src/dart/analysis/uri_converter.dart
index 6a13f86..9e6bf4a 100644
--- a/pkg/analyzer/lib/src/dart/analysis/uri_converter.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/uri_converter.dart
@@ -22,7 +22,7 @@
     ResourceProvider provider = driver.resourceProvider;
     if (containingPath != null) {
       Context context = provider.pathContext;
-      String root = driver.contextRoot!.root;
+      String root = driver.analysisContext!.contextRoot.root.path;
       if (context.isWithin(root, path) &&
           context.isWithin(root, containingPath)) {
         String relativePath =
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 03053ed..b48310d 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -5083,7 +5083,9 @@
     ..add(semicolon);
 
   @override
+  // ignore: deprecated_member_use_from_same_package
   FunctionTypeAliasElement? get declaredElement =>
+      // ignore: deprecated_member_use_from_same_package
       _name.staticElement as FunctionTypeAliasElement?;
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index c8b5796..30e8681 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -4316,6 +4316,7 @@
   T? accept<T>(ElementVisitor<T> visitor) => visitor.visitFunctionElement(this);
 }
 
+@Deprecated('Use TypeAliasElement instead')
 class FunctionTypeAliasElementImpl extends TypeAliasElementImpl
     implements FunctionTypeAliasElement {
   FunctionTypeAliasElementImpl.forLinkedNode(
@@ -4324,6 +4325,7 @@
     TypeAlias linkedNode,
   ) : super.forLinkedNode(enclosingUnit, reference, linkedNode);
 
+  @Deprecated('Use aliasedElement instead')
   @override
   GenericFunctionTypeElementImpl get function {
     return aliasedElement as GenericFunctionTypeElementImpl;
@@ -4336,6 +4338,7 @@
     return visitor.visitTypeAliasElement(this);
   }
 
+  @Deprecated('Use TypeAliasElement instead')
   @override
   FunctionType instantiate({
     required List<DartType> typeArguments,
@@ -6975,12 +6978,14 @@
     TypeAlias linkedNode,
   ) {
     if (linkedNode is FunctionTypeAlias) {
+      // ignore: deprecated_member_use_from_same_package
       return FunctionTypeAliasElementImpl.forLinkedNode(
           enclosingUnit, reference, linkedNode);
     } else {
       var aliasedType = (linkedNode as GenericTypeAlias).type;
       if (aliasedType is GenericFunctionType ||
           !enclosingUnit.isNonFunctionTypeAliasesEnabled) {
+        // ignore: deprecated_member_use_from_same_package
         return FunctionTypeAliasElementImpl.forLinkedNode(
             enclosingUnit, reference, linkedNode);
       } else {
@@ -7575,6 +7580,7 @@
   static final List<ExtensionElement> extensionElement = List.unmodifiable([]);
   static final List<FieldElement> fieldElement = List.unmodifiable([]);
   static final List<FunctionElement> functionElement = List.unmodifiable([]);
+  @Deprecated('Use TypeAliasElement instead')
   static final List<FunctionTypeAliasElement> functionTypeAliasElement =
       List.unmodifiable([]);
   static final List<ImportElement> importElement = List.unmodifiable([]);
diff --git a/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
index 033fd97..250d438 100644
--- a/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
@@ -605,7 +605,7 @@
 
   @override
   void visitFunctionTypeAlias(FunctionTypeAlias node) {
-    var element = _elementWalker!.getTypedef() as FunctionTypeAliasElementImpl;
+    var element = _elementWalker!.getTypedef();
     node.name.staticElement = element;
 
     node.metadata.accept(this);
diff --git a/pkg/analyzer/lib/src/generated/declaration_resolver.dart b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
index acb699c..282bddd 100644
--- a/pkg/analyzer/lib/src/generated/declaration_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
@@ -98,9 +98,10 @@
 
   /// Creates an [ElementWalker] which walks the child elements of a typedef
   /// element.
-  ElementWalker.forTypedef(FunctionTypeAliasElementImpl element)
+  ElementWalker.forTypedef(TypeAliasElement element)
       : element = element,
-        _parameters = element.function.parameters,
+        _parameters =
+            (element.aliasedElement as GenericFunctionTypeElement).parameters,
         _typeParameters = element.typeParameters;
 
   void consumeLocalElements() {
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 9a4d376..14eda22 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -116,12 +116,6 @@
     // See https://github.com/dart-lang/sdk/issues/30314.
     StringToken.canonicalizer.clear();
   }
-
-  /// A utility method that clients can use to process all of the required
-  /// plugins. This method can only be used by clients that do not need to
-  /// process any other plugins.
-  @deprecated
-  void processRequiredPlugins() {}
 }
 
 /// The analysis errors and line information for the errors.
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 1411df8..d65859f 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -3415,6 +3415,15 @@
     }
   }
 
+  @override
+  DiagnosticMessage? visitThisNotPromoted(ThisNotPromoted reason) {
+    return DiagnosticMessageImpl(
+        filePath: source.fullName,
+        message: "'this' can't be promoted.",
+        offset: _receiver.offset,
+        length: _receiver.length);
+  }
+
   DiagnosticMessageImpl _contextMessageForProperty(
       PropertyAccessorElement property, String propertyName) {
     return DiagnosticMessageImpl(
diff --git a/pkg/analyzer/lib/src/services/available_declarations.dart b/pkg/analyzer/lib/src/services/available_declarations.dart
index 6fba2c3..22ddf8d 100644
--- a/pkg/analyzer/lib/src/services/available_declarations.dart
+++ b/pkg/analyzer/lib/src/services/available_declarations.dart
@@ -25,6 +25,7 @@
 import 'package:analyzer/src/summary/link.dart' as graph
     show DependencyWalker, Node;
 import 'package:analyzer/src/util/comment.dart';
+import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 import 'package:collection/collection.dart';
 import 'package:convert/convert.dart';
 import 'package:meta/meta.dart';
@@ -338,25 +339,20 @@
   void _findPackages() {
     var pathContext = _tracker._resourceProvider.pathContext;
     var pubPathPrefixToPathList = <String, List<String>>{};
-    var visitedFolderPaths = <String>{};
 
-    /// TODO(scheglov) Use analyzedFiles() ?
-    void visitFolder(Folder folder) {
-      var canonicalFolderPath = folder.resolveSymbolicLinksSync().path;
-      if (!visitedFolderPaths.add(canonicalFolderPath)) {
-        return;
-      }
-
-      var buildFile = folder.getChildAssumingFile('BUILD');
-      var pubspecFile = folder.getChildAssumingFile('pubspec.yaml');
-      if (buildFile.exists) {
-        _packages.add(_Package(folder));
-      } else if (pubspecFile.exists) {
-        var dependencies = _parsePubspecDependencies(pubspecFile);
+    for (var path in _analysisContext.contextRoot.analyzedFiles()) {
+      if (file_paths.isBazelBuild(pathContext, path)) {
+        var file = _tracker._resourceProvider.getFile(path);
+        var packageFolder = file.parent2;
+        _packages.add(_Package(packageFolder));
+      } else if (file_paths.isPubspecYaml(pathContext, path)) {
+        var file = _tracker._resourceProvider.getFile(path);
+        var dependencies = _parsePubspecDependencies(file);
         var libPaths = _resolvePackageNamesToLibPaths(dependencies.lib);
         var devPaths = _resolvePackageNamesToLibPaths(dependencies.dev);
 
-        var packagePath = folder.path;
+        var packageFolder = file.parent2;
+        var packagePath = packageFolder.path;
         pubPathPrefixToPathList[packagePath] = [
           ...libPaths,
           ...devPaths,
@@ -365,21 +361,10 @@
         var libPath = pathContext.join(packagePath, 'lib');
         pubPathPrefixToPathList[libPath] = libPaths;
 
-        _packages.add(_Package(folder));
-      }
-
-      try {
-        for (var resource in folder.getChildren()) {
-          if (resource is Folder) {
-            visitFolder(resource);
-          }
-        }
-      } on FileSystemException {
-        // ignored
+        _packages.add(_Package(packageFolder));
       }
     }
 
-    visitFolder(_analysisContext.contextRoot.root);
     setDependencies(pubPathPrefixToPathList);
 
     _packages.sort((a, b) {
diff --git a/pkg/analyzer/lib/src/summary2/apply_resolution.dart b/pkg/analyzer/lib/src/summary2/apply_resolution.dart
index 92522a1..9da7646 100644
--- a/pkg/analyzer/lib/src/summary2/apply_resolution.dart
+++ b/pkg/analyzer/lib/src/summary2/apply_resolution.dart
@@ -599,13 +599,15 @@
   void visitFunctionTypeAlias(FunctionTypeAlias node) {
     _assertNoLocalElements();
 
-    var element = node.declaredElement as FunctionTypeAliasElementImpl;
+    var element = node.declaredElement as TypeAliasElementImpl;
     _enclosingElements.add(element);
 
     _expectMarker(MarkerTag.FunctionTypeAlias_typeParameters);
     node.typeParameters?.accept(this);
 
-    _enclosingElements.add(element.function);
+    var function = element.aliasedElement as GenericFunctionTypeElementImpl;
+    _enclosingElements.add(function);
+
     _expectMarker(MarkerTag.FunctionTypeAlias_returnType);
     node.returnType?.accept(this);
     _expectMarker(MarkerTag.FunctionTypeAlias_parameters);
@@ -616,7 +618,7 @@
     _typeAlias(node);
 
     _expectMarker(MarkerTag.FunctionTypeAlias_returnTypeType);
-    element.function.returnType = _nextType()!;
+    function.returnType = _nextType()!;
     _expectMarker(MarkerTag.FunctionTypeAlias_flags);
     element.isSimplyBounded = _resolution.readByte() != 0;
     element.hasSelfReference = _resolution.readByte() != 0;
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
index 84007bd..cbee429 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
@@ -923,9 +923,10 @@
 
     var resolutionSink = _resolutionSink;
     if (resolutionSink != null) {
-      var element = node.declaredElement as FunctionTypeAliasElementImpl;
+      var element = node.declaredElement as TypeAliasElementImpl;
+      var function = element.aliasedElement as GenericFunctionTypeElement;
       _writeMarker(MarkerTag.FunctionTypeAlias_returnTypeType);
-      _writeActualReturnType(resolutionSink, element.function.returnType);
+      _writeActualReturnType(resolutionSink, function.returnType);
       // TODO(scheglov) pack into one byte
       _writeMarker(MarkerTag.FunctionTypeAlias_flags);
       resolutionSink.writeByte(element.isSimplyBounded ? 1 : 0);
diff --git a/pkg/analyzer/lib/src/summary2/reference_resolver.dart b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
index b8e2973..fa6e3a0 100644
--- a/pkg/analyzer/lib/src/summary2/reference_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
@@ -237,7 +237,7 @@
     var outerScope = scope;
     var outerReference = reference;
 
-    var element = node.declaredElement as FunctionTypeAliasElementImpl;
+    var element = node.declaredElement as TypeAliasElementImpl;
     reference = element.reference!;
 
     _createTypeParameterElements(element, node.typeParameters);
@@ -246,9 +246,9 @@
     node.returnType?.accept(this);
     node.typeParameters?.accept(this);
 
-    var functionElement = element.function;
-    reference = functionElement.reference!;
-    functionElement.parameters; // create elements
+    var function = element.aliasedElement as GenericFunctionTypeElementImpl;
+    reference = function.reference!;
+    function.parameters; // create elements
     node.parameters.accept(this);
 
     nodesToBuildType.addDeclaration(node);
diff --git a/pkg/analyzer/lib/src/summary2/types_builder.dart b/pkg/analyzer/lib/src/summary2/types_builder.dart
index cccd41f..d58f96d 100644
--- a/pkg/analyzer/lib/src/summary2/types_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/types_builder.dart
@@ -154,8 +154,9 @@
 
   void _functionTypeAlias(FunctionTypeAlias node) {
     var returnTypeNode = node.returnType;
-    var element = node.declaredElement as FunctionTypeAliasElementImpl;
-    element.function.returnType = returnTypeNode?.type ?? _dynamicType;
+    var element = node.declaredElement as TypeAliasElement;
+    var function = element.aliasedElement as GenericFunctionTypeElementImpl;
+    function.returnType = returnTypeNode?.type ?? _dynamicType;
   }
 
   void _functionTypedFormalParameter(FunctionTypedFormalParameter node) {
diff --git a/pkg/analyzer/lib/src/test_utilities/resource_provider_mixin.dart b/pkg/analyzer/lib/src/test_utilities/resource_provider_mixin.dart
index ea5e130..abf97ef 100644
--- a/pkg/analyzer/lib/src/test_utilities/resource_provider_mixin.dart
+++ b/pkg/analyzer/lib/src/test_utilities/resource_provider_mixin.dart
@@ -50,6 +50,16 @@
     resourceProvider.modifyFile(convertedPath, content);
   }
 
+  File newAnalysisOptionsYamlFile(String directoryPath, {String content = ''}) {
+    String path = join(directoryPath, file_paths.analysisOptionsYaml);
+    return newFile(path, content: content);
+  }
+
+  File newDotPackagesFile(String directoryPath, {String content = ''}) {
+    String path = join(directoryPath, file_paths.dotPackages);
+    return newFile(path, content: content);
+  }
+
   File newFile(String path, {String content = ''}) {
     String convertedPath = convertPath(path);
     return resourceProvider.newFile(convertedPath, content);
@@ -60,16 +70,6 @@
     return resourceProvider.newFolder(convertedPath);
   }
 
-  File newOptionsFile(String directoryPath, {String content = ''}) {
-    String path = join(directoryPath, file_paths.analysisOptionsYaml);
-    return newFile(path, content: content);
-  }
-
-  File newPackagesFile(String directoryPath) {
-    String path = join(directoryPath, file_paths.dotPackages);
-    return newFile(path);
-  }
-
   File newPubspecYamlFile(String directoryPath, String content) {
     String path = join(directoryPath, file_paths.pubspecYaml);
     return newFile(path, content: content);
diff --git a/pkg/analyzer/lib/src/util/file_paths.dart b/pkg/analyzer/lib/src/util/file_paths.dart
index 2a6318c..6f8ade1 100644
--- a/pkg/analyzer/lib/src/util/file_paths.dart
+++ b/pkg/analyzer/lib/src/util/file_paths.dart
@@ -13,6 +13,9 @@
 /// File name of Android manifest files.
 const String androidManifestXml = 'AndroidManifest.xml';
 
+/// File name of Bazel `BUILD` files.
+const String bazelBuild = 'BUILD';
+
 /// The name of the `.dart_tool` directory.
 const String dotDartTool = '.dart_tool';
 
@@ -38,6 +41,11 @@
   return pathContext.basename(path) == androidManifestXml;
 }
 
+/// Return `true` if [path] is a Bazel `BUILD` file.
+bool isBazelBuild(p.Context pathContext, String path) {
+  return pathContext.basename(path) == bazelBuild;
+}
+
 /// Return `true` if [path] is a Dart file.
 bool isDart(p.Context pathContext, String path) {
   return pathContext.extension(path) == '.dart';
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 6e789a4..799dee7 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 1.1.0-dev
+version: 1.1.0
 description: This package provides a library that performs static analysis of Dart code.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
 
@@ -7,7 +7,7 @@
   sdk: '>=2.12.0-0 <3.0.0'
 
 dependencies:
-  _fe_analyzer_shared: ^16.0.0
+  _fe_analyzer_shared: ^17.0.0
   args: ^2.0.0
   cli_util: ^0.3.0
   collection: ^1.15.0
diff --git a/pkg/analyzer/test/src/context/builder_test.dart b/pkg/analyzer/test/src/context/builder_test.dart
index d650f9c..00d5959 100644
--- a/pkg/analyzer/test/src/context/builder_test.dart
+++ b/pkg/analyzer/test/src/context/builder_test.dart
@@ -103,7 +103,7 @@
     ];
 
     String path = convertPath('/some/directory/path');
-    newOptionsFile(path, content: '''
+    newAnalysisOptionsYamlFile(path, content: '''
 linter:
   rules:
     - mock_lint_rule
@@ -127,7 +127,7 @@
     ];
 
     String path = convertPath('/some/directory/path');
-    newOptionsFile(path, content: '''
+    newAnalysisOptionsYamlFile(path, content: '''
 linter:
   rules:
     - mock_lint_rule
@@ -151,7 +151,7 @@
     ];
 
     String path = convertPath('/some/directory/path');
-    newOptionsFile(path, content: '''
+    newAnalysisOptionsYamlFile(path, content: '''
 linter:
   rules:
     - mock_lint_rule
@@ -173,7 +173,7 @@
     expected.lintRules = <LintRule>[];
 
     String path = convertPath('/some/directory/path');
-    newOptionsFile(path, content: '''
+    newAnalysisOptionsYamlFile(path, content: '''
 ''');
 
     var options = _getAnalysisOptions(builder, path);
@@ -532,7 +532,7 @@
     builderOptions.defaultOptions = defaultOptions;
     AnalysisOptionsImpl expected = AnalysisOptionsImpl();
     String path = convertPath('/some/directory/path');
-    newOptionsFile(path, content: '''
+    newAnalysisOptionsYamlFile(path, content: '''
 linter:
   rules:
     - non_existent_lint_rule
@@ -549,7 +549,7 @@
     AnalysisOptionsImpl expected = AnalysisOptionsImpl();
     expected.implicitDynamic = false;
     String path = convertPath('/some/directory/path');
-    newOptionsFile(path, content: '''
+    newAnalysisOptionsYamlFile(path, content: '''
 analyzer:
   strong-mode:
     implicit-dynamic: false
@@ -603,7 +603,7 @@
   rules:
     - mock_lint_rule2
 ''');
-    newOptionsFile(path, content: '''
+    newAnalysisOptionsYamlFile(path, content: '''
 include: bar.yaml
 linter:
   rules:
@@ -616,7 +616,7 @@
 
   void test_getAnalysisOptions_invalid() {
     String path = convertPath('/some/directory/path');
-    newOptionsFile(path, content: ';');
+    newAnalysisOptionsYamlFile(path, content: ';');
 
     AnalysisOptions options = _getAnalysisOptions(builder, path);
     expect(options, isNotNull);
@@ -624,7 +624,7 @@
 
   void test_getAnalysisOptions_noDefault_noOverrides() {
     String path = convertPath('/some/directory/path');
-    newOptionsFile(path, content: '''
+    newAnalysisOptionsYamlFile(path, content: '''
 linter:
   rules:
     - non_existent_lint_rule
@@ -638,7 +638,7 @@
     AnalysisOptionsImpl expected = AnalysisOptionsImpl();
     expected.implicitDynamic = false;
     String path = convertPath('/some/directory/path');
-    newOptionsFile(path, content: '''
+    newAnalysisOptionsYamlFile(path, content: '''
 analyzer:
   strong-mode:
     implicit-dynamic: false
@@ -650,7 +650,7 @@
 
   void test_getAnalysisOptions_optionsPath() {
     String path = convertPath('/some/directory/path');
-    String filePath = newOptionsFile(path, content: '''
+    String filePath = newAnalysisOptionsYamlFile(path, content: '''
 linter:
   rules:
     - empty_constructor_bodies
@@ -693,7 +693,7 @@
   void test_getOptionsFile_inParentOfRoot_new() {
     String parentPath = convertPath('/some/directory');
     String path = join(parentPath, 'path');
-    String filePath = newOptionsFile(path).path;
+    String filePath = newAnalysisOptionsYamlFile(path).path;
 
     var result = builder.getOptionsFile(path)!;
     expect(result, isNotNull);
@@ -702,7 +702,7 @@
 
   void test_getOptionsFile_inRoot_new() {
     String path = convertPath('/some/directory/path');
-    String filePath = newOptionsFile(path).path;
+    String filePath = newAnalysisOptionsYamlFile(path).path;
 
     var result = builder.getOptionsFile(path)!;
     expect(result, isNotNull);
diff --git a/pkg/analyzer/test/src/dart/analysis/analysis_context_collection_test.dart b/pkg/analyzer/test/src/dart/analysis/analysis_context_collection_test.dart
index 2cb3c25..ba7dffe 100644
--- a/pkg/analyzer/test/src/dart/analysis/analysis_context_collection_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/analysis_context_collection_test.dart
@@ -64,7 +64,7 @@
     newFile('/test/outer/lib/outer.dart');
 
     var innerFolder = newFolder('/test/outer/inner');
-    newOptionsFile('/test/outer/inner');
+    newAnalysisOptionsYamlFile('/test/outer/inner');
     newFile('/test/outer/inner/inner.dart');
 
     var collection = _newCollection(includedPaths: [outerFolder.path]);
diff --git a/pkg/analyzer/test/src/dart/analysis/context_locator_test.dart b/pkg/analyzer/test/src/dart/analysis/context_locator_test.dart
index 469a182..a8cab1a 100644
--- a/pkg/analyzer/test/src/dart/analysis/context_locator_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/context_locator_test.dart
@@ -174,8 +174,8 @@
 
   void test_locateRoots_multiple_dirAndNestedDir() {
     Folder outerRootFolder = newFolder('/test/outer');
-    File outerOptionsFile = newOptionsFile('/test/outer');
-    File outerPackagesFile = newPackagesFile('/test/outer');
+    File outerOptionsFile = newAnalysisOptionsYamlFile('/test/outer');
+    File outerPackagesFile = newDotPackagesFile('/test/outer');
     Folder innerRootFolder = newFolder('/test/outer/examples/inner');
 
     List<ContextRoot> roots = contextLocator.locateRoots(
@@ -191,8 +191,8 @@
 
   void test_locateRoots_multiple_dirAndNestedFile() {
     Folder outerRootFolder = newFolder('/test/outer');
-    File outerOptionsFile = newOptionsFile('/test/outer');
-    File outerPackagesFile = newPackagesFile('/test/outer');
+    File outerOptionsFile = newAnalysisOptionsYamlFile('/test/outer');
+    File outerPackagesFile = newDotPackagesFile('/test/outer');
     File testFile = newFile('/test/outer/examples/inner/test.dart');
 
     List<ContextRoot> roots = contextLocator
@@ -208,12 +208,12 @@
 
   void test_locateRoots_multiple_dirAndSiblingDir() {
     Folder outer1RootFolder = newFolder('/test/outer1');
-    File outer1OptionsFile = newOptionsFile('/test/outer1');
-    File outer1PackagesFile = newPackagesFile('/test/outer1');
+    File outer1OptionsFile = newAnalysisOptionsYamlFile('/test/outer1');
+    File outer1PackagesFile = newDotPackagesFile('/test/outer1');
 
     Folder outer2RootFolder = newFolder('/test/outer2');
-    File outer2OptionsFile = newOptionsFile('/test/outer2');
-    File outer2PackagesFile = newPackagesFile('/test/outer2');
+    File outer2OptionsFile = newAnalysisOptionsYamlFile('/test/outer2');
+    File outer2PackagesFile = newDotPackagesFile('/test/outer2');
 
     List<ContextRoot> roots = contextLocator.locateRoots(
         includedPaths: [outer1RootFolder.path, outer2RootFolder.path]);
@@ -234,11 +234,11 @@
 
   void test_locateRoots_multiple_dirAndSiblingFile() {
     Folder outer1RootFolder = newFolder('/test/outer1');
-    File outer1OptionsFile = newOptionsFile('/test/outer1');
-    File outer1PackagesFile = newPackagesFile('/test/outer1');
+    File outer1OptionsFile = newAnalysisOptionsYamlFile('/test/outer1');
+    File outer1PackagesFile = newDotPackagesFile('/test/outer1');
 
-    File outer2OptionsFile = newOptionsFile('/test/outer2');
-    File outer2PackagesFile = newPackagesFile('/test/outer2');
+    File outer2OptionsFile = newAnalysisOptionsYamlFile('/test/outer2');
+    File outer2PackagesFile = newDotPackagesFile('/test/outer2');
     File testFile = newFile('/test/outer2/test.dart');
 
     List<ContextRoot> roots = contextLocator
@@ -278,8 +278,8 @@
       fail(buffer.toString());
     }
 
-    File optionsFile = newOptionsFile('/test/root');
-    File packagesFile = newPackagesFile('/test/root');
+    File optionsFile = newAnalysisOptionsYamlFile('/test/root');
+    File packagesFile = newDotPackagesFile('/test/root');
     File testFile1 = newFile('/test/root/test1.dart');
     File testFile2 = newFile('/test/root/test2.dart');
 
@@ -297,10 +297,10 @@
 
   void test_locateRoots_nested_excluded_dot() {
     Folder outerRootFolder = newFolder('/test/outer');
-    File outerOptionsFile = newOptionsFile('/test/outer');
-    File outerPackagesFile = newPackagesFile('/test/outer');
+    File outerOptionsFile = newAnalysisOptionsYamlFile('/test/outer');
+    File outerPackagesFile = newDotPackagesFile('/test/outer');
     Folder excludedFolder = newFolder('/test/outer/.examples');
-    newOptionsFile('/test/outer/.examples/inner');
+    newAnalysisOptionsYamlFile('/test/outer/.examples/inner');
 
     List<ContextRoot> roots =
         contextLocator.locateRoots(includedPaths: [outerRootFolder.path]);
@@ -315,10 +315,10 @@
 
   void test_locateRoots_nested_excluded_explicit() {
     Folder outerRootFolder = newFolder('/test/outer');
-    File outerOptionsFile = newOptionsFile('/test/outer');
-    File outerPackagesFile = newPackagesFile('/test/outer');
+    File outerOptionsFile = newAnalysisOptionsYamlFile('/test/outer');
+    File outerPackagesFile = newDotPackagesFile('/test/outer');
     Folder excludedFolder = newFolder('/test/outer/examples');
-    newOptionsFile('/test/outer/examples/inner');
+    newAnalysisOptionsYamlFile('/test/outer/examples/inner');
 
     List<ContextRoot> roots = contextLocator.locateRoots(
         includedPaths: [outerRootFolder.path],
@@ -334,12 +334,13 @@
 
   void test_locateRoots_nested_multiple() {
     Folder outerRootFolder = newFolder('/test/outer');
-    File outerOptionsFile = newOptionsFile('/test/outer');
-    File outerPackagesFile = newPackagesFile('/test/outer');
+    File outerOptionsFile = newAnalysisOptionsYamlFile('/test/outer');
+    File outerPackagesFile = newDotPackagesFile('/test/outer');
     Folder inner1RootFolder = newFolder('/test/outer/examples/inner1');
-    File inner1OptionsFile = newOptionsFile('/test/outer/examples/inner1');
+    File inner1OptionsFile =
+        newAnalysisOptionsYamlFile('/test/outer/examples/inner1');
     Folder inner2RootFolder = newFolder('/test/outer/examples/inner2');
-    File inner2PackagesFile = newPackagesFile('/test/outer/examples/inner2');
+    File inner2PackagesFile = newDotPackagesFile('/test/outer/examples/inner2');
 
     List<ContextRoot> roots =
         contextLocator.locateRoots(includedPaths: [outerRootFolder.path]);
@@ -367,10 +368,11 @@
 
   void test_locateRoots_nested_options() {
     Folder outerRootFolder = newFolder('/test/outer');
-    File outerOptionsFile = newOptionsFile('/test/outer');
-    File outerPackagesFile = newPackagesFile('/test/outer');
+    File outerOptionsFile = newAnalysisOptionsYamlFile('/test/outer');
+    File outerPackagesFile = newDotPackagesFile('/test/outer');
     Folder innerRootFolder = newFolder('/test/outer/examples/inner');
-    File innerOptionsFile = newOptionsFile('/test/outer/examples/inner');
+    File innerOptionsFile =
+        newAnalysisOptionsYamlFile('/test/outer/examples/inner');
 
     List<ContextRoot> roots =
         contextLocator.locateRoots(includedPaths: [outerRootFolder.path]);
@@ -391,11 +393,11 @@
 
   void test_locateRoots_nested_options_overriddenOptions() {
     Folder outerRootFolder = newFolder('/test/outer');
-    newOptionsFile('/test/outer');
-    File outerPackagesFile = newPackagesFile('/test/outer');
+    newAnalysisOptionsYamlFile('/test/outer');
+    File outerPackagesFile = newDotPackagesFile('/test/outer');
     newFolder('/test/outer/examples/inner');
-    newOptionsFile('/test/outer/examples/inner');
-    File overrideOptionsFile = newOptionsFile('/test/override');
+    newAnalysisOptionsYamlFile('/test/outer/examples/inner');
+    File overrideOptionsFile = newAnalysisOptionsYamlFile('/test/override');
 
     List<ContextRoot> roots = contextLocator.locateRoots(
         includedPaths: [outerRootFolder.path],
@@ -411,11 +413,12 @@
 
   void test_locateRoots_nested_options_overriddenPackages() {
     Folder outerRootFolder = newFolder('/test/outer');
-    File outerOptionsFile = newOptionsFile('/test/outer');
-    newPackagesFile('/test/outer');
+    File outerOptionsFile = newAnalysisOptionsYamlFile('/test/outer');
+    newDotPackagesFile('/test/outer');
     Folder innerRootFolder = newFolder('/test/outer/examples/inner');
-    File innerOptionsFile = newOptionsFile('/test/outer/examples/inner');
-    File overridePackagesFile = newPackagesFile('/test/override');
+    File innerOptionsFile =
+        newAnalysisOptionsYamlFile('/test/outer/examples/inner');
+    File overridePackagesFile = newDotPackagesFile('/test/override');
 
     List<ContextRoot> roots = contextLocator.locateRoots(
         includedPaths: [outerRootFolder.path],
@@ -437,11 +440,12 @@
 
   void test_locateRoots_nested_optionsAndPackages() {
     Folder outerRootFolder = newFolder('/test/outer');
-    File outerOptionsFile = newOptionsFile('/test/outer');
-    File outerPackagesFile = newPackagesFile('/test/outer');
+    File outerOptionsFile = newAnalysisOptionsYamlFile('/test/outer');
+    File outerPackagesFile = newDotPackagesFile('/test/outer');
     Folder innerRootFolder = newFolder('/test/outer/examples/inner');
-    File innerOptionsFile = newOptionsFile('/test/outer/examples/inner');
-    File innerPackagesFile = newPackagesFile('/test/outer/examples/inner');
+    File innerOptionsFile =
+        newAnalysisOptionsYamlFile('/test/outer/examples/inner');
+    File innerPackagesFile = newDotPackagesFile('/test/outer/examples/inner');
 
     List<ContextRoot> roots =
         contextLocator.locateRoots(includedPaths: [outerRootFolder.path]);
@@ -462,13 +466,13 @@
 
   void test_locateRoots_nested_optionsAndPackages_overriddenBoth() {
     Folder outerRootFolder = newFolder('/test/outer');
-    newOptionsFile('/test/outer');
-    newPackagesFile('/test/outer');
+    newAnalysisOptionsYamlFile('/test/outer');
+    newDotPackagesFile('/test/outer');
     newFolder('/test/outer/examples/inner');
-    newOptionsFile('/test/outer/examples/inner');
-    newPackagesFile('/test/outer/examples/inner');
-    File overrideOptionsFile = newOptionsFile('/test/override');
-    File overridePackagesFile = newPackagesFile('/test/override');
+    newAnalysisOptionsYamlFile('/test/outer/examples/inner');
+    newDotPackagesFile('/test/outer/examples/inner');
+    File overrideOptionsFile = newAnalysisOptionsYamlFile('/test/override');
+    File overridePackagesFile = newDotPackagesFile('/test/override');
 
     List<ContextRoot> roots = contextLocator.locateRoots(
         includedPaths: [outerRootFolder.path],
@@ -485,7 +489,7 @@
 
   void test_locateRoots_nested_packageConfigJson() {
     var outerRootFolder = newFolder('/test/outer');
-    var outerOptionsFile = newOptionsFile('/test/outer');
+    var outerOptionsFile = newAnalysisOptionsYamlFile('/test/outer');
     var outerPackagesFile = _newPackageConfigFile('/test/outer');
     var innerRootFolder = newFolder('/test/outer/examples/inner');
     var innerPackagesFile = _newPackageConfigFile('/test/outer/examples/inner');
@@ -521,10 +525,10 @@
 
   void test_locateRoots_nested_packages() {
     Folder outerRootFolder = newFolder('/test/outer');
-    File outerOptionsFile = newOptionsFile('/test/outer');
-    File outerPackagesFile = newPackagesFile('/test/outer');
+    File outerOptionsFile = newAnalysisOptionsYamlFile('/test/outer');
+    File outerPackagesFile = newDotPackagesFile('/test/outer');
     Folder innerRootFolder = newFolder('/test/outer/examples/inner');
-    File innerPackagesFile = newPackagesFile('/test/outer/examples/inner');
+    File innerPackagesFile = newDotPackagesFile('/test/outer/examples/inner');
 
     List<ContextRoot> roots =
         contextLocator.locateRoots(includedPaths: [outerRootFolder.path]);
@@ -545,11 +549,11 @@
 
   void test_locateRoots_nested_packages_overriddenOptions() {
     Folder outerRootFolder = newFolder('/test/outer');
-    newOptionsFile('/test/outer');
-    File outerPackagesFile = newPackagesFile('/test/outer');
+    newAnalysisOptionsYamlFile('/test/outer');
+    File outerPackagesFile = newDotPackagesFile('/test/outer');
     Folder innerRootFolder = newFolder('/test/outer/examples/inner');
-    File innerPackagesFile = newPackagesFile('/test/outer/examples/inner');
-    File overrideOptionsFile = newOptionsFile('/test/override');
+    File innerPackagesFile = newDotPackagesFile('/test/outer/examples/inner');
+    File overrideOptionsFile = newAnalysisOptionsYamlFile('/test/override');
 
     List<ContextRoot> roots = contextLocator.locateRoots(
         includedPaths: [outerRootFolder.path],
@@ -571,11 +575,11 @@
 
   void test_locateRoots_nested_packages_overriddenPackages() {
     Folder outerRootFolder = newFolder('/test/outer');
-    File outerOptionsFile = newOptionsFile('/test/outer');
-    newPackagesFile('/test/outer');
+    File outerOptionsFile = newAnalysisOptionsYamlFile('/test/outer');
+    newDotPackagesFile('/test/outer');
     newFolder('/test/outer/examples/inner');
-    newPackagesFile('/test/outer/examples/inner');
-    File overridePackagesFile = newPackagesFile('/test/override');
+    newDotPackagesFile('/test/outer/examples/inner');
+    File overridePackagesFile = newDotPackagesFile('/test/override');
 
     List<ContextRoot> roots = contextLocator.locateRoots(
         includedPaths: [outerRootFolder.path],
@@ -591,9 +595,10 @@
 
   void test_locateRoots_nested_packagesDirectory_included() {
     Folder outerRootFolder = newFolder('/test/outer');
-    File outerOptionsFile = newOptionsFile('/test/outer');
-    File outerPackagesFile = newPackagesFile('/test/outer');
-    File innerOptionsFile = newOptionsFile('/test/outer/packages/inner');
+    File outerOptionsFile = newAnalysisOptionsYamlFile('/test/outer');
+    File outerPackagesFile = newDotPackagesFile('/test/outer');
+    File innerOptionsFile =
+        newAnalysisOptionsYamlFile('/test/outer/packages/inner');
 
     List<ContextRoot> roots =
         contextLocator.locateRoots(includedPaths: [outerRootFolder.path]);
@@ -609,12 +614,12 @@
 
   void test_locateRoots_options_withExclude_someFiles() {
     Folder rootFolder = newFolder('/test/root');
-    File optionsFile = newOptionsFile('/test/root', content: '''
+    File optionsFile = newAnalysisOptionsYamlFile('/test/root', content: '''
 analyzer:
   exclude:
     - data/**.g.dart
 ''');
-    File packagesFile = newPackagesFile('/test/root');
+    File packagesFile = newDotPackagesFile('/test/root');
 
     List<ContextRoot> roots =
         contextLocator.locateRoots(includedPaths: [rootFolder.path]);
@@ -642,12 +647,12 @@
 
   void test_locateRoots_options_withExclude_someFolders() {
     Folder rootFolder = newFolder('/test/root');
-    File optionsFile = newOptionsFile('/test/root', content: '''
+    File optionsFile = newAnalysisOptionsYamlFile('/test/root', content: '''
 analyzer:
   exclude:
     - data/**/foo/**
 ''');
-    File packagesFile = newPackagesFile('/test/root');
+    File packagesFile = newDotPackagesFile('/test/root');
 
     List<ContextRoot> roots =
         contextLocator.locateRoots(includedPaths: [rootFolder.path]);
@@ -674,12 +679,12 @@
 
   void test_locateRoots_options_withExclude_wholeFolder() {
     Folder rootFolder = newFolder('/test/root');
-    File optionsFile = newOptionsFile('/test/root', content: '''
+    File optionsFile = newAnalysisOptionsYamlFile('/test/root', content: '''
 analyzer:
   exclude:
     - data/**
 ''');
-    File packagesFile = newPackagesFile('/test/root');
+    File packagesFile = newDotPackagesFile('/test/root');
     Folder dataFolder = newFolder('/test/root/data');
 
     List<ContextRoot> roots =
@@ -704,7 +709,7 @@
 
   void test_locateRoots_options_withExclude_wholeFolder_includedOptions() {
     Folder rootFolder = newFolder('/test/root');
-    File optionsFile = newOptionsFile('/test/root', content: '''
+    File optionsFile = newAnalysisOptionsYamlFile('/test/root', content: '''
 include: has_excludes.yaml
 ''');
     newFile('/test/root/has_excludes.yaml', content: '''
@@ -713,7 +718,7 @@
     - data/**
 ''');
 
-    File packagesFile = newPackagesFile('/test/root');
+    File packagesFile = newDotPackagesFile('/test/root');
     Folder dataFolder = newFolder('/test/root/data');
 
     List<ContextRoot> roots =
@@ -738,7 +743,7 @@
 
   void test_locateRoots_options_withExclude_wholeFolder_includedOptionsMerge() {
     Folder rootFolder = newFolder('/test/root');
-    File optionsFile = newOptionsFile('/test/root', content: '''
+    File optionsFile = newAnalysisOptionsYamlFile('/test/root', content: '''
 include: has_excludes.yaml
 analyzer:
   exclude:
@@ -750,7 +755,7 @@
     - foo/**
 ''');
 
-    File packagesFile = newPackagesFile('/test/root');
+    File packagesFile = newDotPackagesFile('/test/root');
     Folder fooFolder = newFolder('/test/root/foo');
     Folder barFolder = newFolder('/test/root/bar');
 
@@ -782,14 +787,14 @@
 
   void test_locateRoots_options_withExclude_wholeFolder_withItsOptions() {
     Folder rootFolder = newFolder('/test/root');
-    File optionsFile = newOptionsFile('/test/root', content: '''
+    File optionsFile = newAnalysisOptionsYamlFile('/test/root', content: '''
 analyzer:
   exclude:
     - data/**
 ''');
-    File packagesFile = newPackagesFile('/test/root');
+    File packagesFile = newDotPackagesFile('/test/root');
     Folder dataFolder = newFolder('/test/root/data');
-    newOptionsFile('/test/root/data', content: '');
+    newAnalysisOptionsYamlFile('/test/root/data', content: '');
 
     List<ContextRoot> roots =
         contextLocator.locateRoots(includedPaths: [rootFolder.path]);
@@ -813,8 +818,8 @@
 
   void test_locateRoots_single_dir_directOptions_directPackages() {
     Folder rootFolder = newFolder('/test/root');
-    File optionsFile = newOptionsFile('/test/root');
-    File packagesFile = newPackagesFile('/test/root');
+    File optionsFile = newAnalysisOptionsYamlFile('/test/root');
+    File packagesFile = newDotPackagesFile('/test/root');
 
     List<ContextRoot> roots =
         contextLocator.locateRoots(includedPaths: [rootFolder.path]);
@@ -829,8 +834,8 @@
 
   void test_locateRoots_single_dir_directOptions_inheritedPackages() {
     Folder rootFolder = newFolder('/test/root');
-    File optionsFile = newOptionsFile('/test/root');
-    File packagesFile = newPackagesFile('/test');
+    File optionsFile = newAnalysisOptionsYamlFile('/test/root');
+    File packagesFile = newDotPackagesFile('/test');
 
     List<ContextRoot> roots =
         contextLocator.locateRoots(includedPaths: [rootFolder.path]);
@@ -845,8 +850,8 @@
 
   void test_locateRoots_single_dir_inheritedOptions_directPackages() {
     Folder rootFolder = newFolder('/test/root');
-    File optionsFile = newOptionsFile('/test');
-    File packagesFile = newPackagesFile('/test/root');
+    File optionsFile = newAnalysisOptionsYamlFile('/test');
+    File packagesFile = newDotPackagesFile('/test/root');
 
     List<ContextRoot> roots =
         contextLocator.locateRoots(includedPaths: [rootFolder.path]);
@@ -861,8 +866,8 @@
 
   void test_locateRoots_single_dir_inheritedOptions_inheritedPackages() {
     Folder rootFolder = newFolder('/test/root');
-    File optionsFile = newOptionsFile('/test');
-    File packagesFile = newPackagesFile('/test');
+    File optionsFile = newAnalysisOptionsYamlFile('/test');
+    File packagesFile = newDotPackagesFile('/test');
 
     List<ContextRoot> roots =
         contextLocator.locateRoots(includedPaths: [rootFolder.path]);
@@ -877,8 +882,8 @@
 
   void test_locateRoots_single_dir_prefer_packageConfigJson() {
     var rootFolder = newFolder('/test');
-    var optionsFile = newOptionsFile('/test');
-    newPackagesFile('/test'); // the file is not used
+    var optionsFile = newAnalysisOptionsYamlFile('/test');
+    newDotPackagesFile('/test'); // the file is not used
     var packageConfigJsonFile = _newPackageConfigFile('/test');
 
     var roots = contextLocator.locateRoots(includedPaths: [rootFolder.path]);
@@ -897,8 +902,8 @@
   }
 
   void test_locateRoots_single_file_inheritedOptions_directPackages() {
-    File optionsFile = newOptionsFile('/test');
-    File packagesFile = newPackagesFile('/test/root');
+    File optionsFile = newAnalysisOptionsYamlFile('/test');
+    File packagesFile = newDotPackagesFile('/test/root');
     File testFile = newFile('/test/root/test.dart');
 
     List<ContextRoot> roots =
diff --git a/pkg/analyzer/test/src/dart/analysis/context_root_test.dart b/pkg/analyzer/test/src/dart/analysis/context_root_test.dart
index 1094e08..22b64ae 100644
--- a/pkg/analyzer/test/src/dart/analysis/context_root_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/context_root_test.dart
@@ -68,16 +68,26 @@
     expect(contextRoot.isAnalyzed(bPath), isTrue);
   }
 
-  test_isAnalyzed_implicitlyExcluded_dot_analysisOptions() {
-    String filePath = convertPath('/test/root/lib/.analysis_options');
+  test_isAnalyzed_implicitlyExcluded_dotFile() {
+    String filePath = convertPath('/test/root/lib/.aaa');
     expect(contextRoot.isAnalyzed(filePath), isFalse);
   }
 
-  test_isAnalyzed_implicitlyExcluded_dot_packages() {
+  test_isAnalyzed_implicitlyExcluded_dotFile_dotPackages() {
     String filePath = convertPath('/test/root/lib/.packages');
     expect(contextRoot.isAnalyzed(filePath), isFalse);
   }
 
+  test_isAnalyzed_implicitlyExcluded_dotFolder_directParent() {
+    String filePath = convertPath('/test/root/lib/.aaa/a.dart');
+    expect(contextRoot.isAnalyzed(filePath), isFalse);
+  }
+
+  test_isAnalyzed_implicitlyExcluded_dotFolder_indirectParent() {
+    String filePath = convertPath('/test/root/lib/.aaa/bbb/a.dart');
+    expect(contextRoot.isAnalyzed(filePath), isFalse);
+  }
+
   test_isAnalyzed_included() {
     String filePath = convertPath('/test/root/lib/root.dart');
     expect(contextRoot.isAnalyzed(filePath), isTrue);
diff --git a/pkg/analyzer/test/src/dart/analysis/uri_converter_test.dart b/pkg/analyzer/test/src/dart/analysis/uri_converter_test.dart
index 069a4ca..f8d8c23 100644
--- a/pkg/analyzer/test/src/dart/analysis/uri_converter_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/uri_converter_test.dart
@@ -2,14 +2,17 @@
 // 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 'package:analyzer/dart/analysis/analysis_context.dart';
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/context/context_root.dart';
+import 'package:analyzer/src/dart/analysis/context_root.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
 import 'package:analyzer/src/dart/analysis/uri_converter.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/source/package_map_resolver.dart';
 import 'package:analyzer/src/test_utilities/mock_sdk.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:analyzer/src/workspace/basic.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -36,13 +39,14 @@
       ResourceUriResolver(resourceProvider),
     ]);
 
-    ContextRoot contextRoot = ContextRoot(barFolder.path, [],
-        pathContext: resourceProvider.pathContext);
+    var contextRoot = ContextRootImpl(resourceProvider, barFolder,
+        BasicWorkspace.find(resourceProvider, {}, barFolder.path));
 
     MockAnalysisDriver driver = MockAnalysisDriver();
     driver.resourceProvider = resourceProvider;
     driver.sourceFactory = sourceFactory;
-    driver.contextRoot = contextRoot;
+    driver.analysisContext =
+        DriverBasedAnalysisContext(resourceProvider, contextRoot, driver);
 
     uriConverter = DriverBasedUriConverter(driver);
   }
@@ -90,7 +94,7 @@
   late final SourceFactory sourceFactory;
 
   @override
-  late final ContextRoot contextRoot;
+  AnalysisContext? analysisContext;
 
   @override
   dynamic noSuchMethod(Invocation invocation) {
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index 101244f..9a30699 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -380,6 +380,7 @@
     kernel.BinaryPrinter(sink).writeComponentFile(component);
     outFiles.add(sink.flush().then((_) => sink.close()));
   }
+  String fullDillUri;
   if (argResults['experimental-output-compiled-kernel'] as bool) {
     if (outPaths.length > 1) {
       print(
@@ -396,8 +397,8 @@
     if (identical(compilerState, oldCompilerState)) {
       compiledLibraries.unbindCanonicalNames();
     }
-    var sink =
-        File(p.withoutExtension(outPaths.first) + '.full.dill').openWrite();
+    fullDillUri = p.withoutExtension(outPaths.first) + '.full.dill';
+    var sink = File(fullDillUri).openWrite();
     kernel.BinaryPrinter(sink).writeComponentFile(compiledLibraries);
     outFiles.add(sink.flush().then((_) => sink.close()));
   }
@@ -445,6 +446,7 @@
         emitDebugMetadata: options.emitDebugMetadata,
         jsUrl: p.toUri(output).toString(),
         mapUrl: mapUrl,
+        fullDillUri: fullDillUri,
         customScheme: options.multiRootScheme,
         multiRootOutputPath: multiRootOutputPath,
         component: compiledLibraries);
@@ -647,6 +649,7 @@
     bool emitDebugMetadata = false,
     String jsUrl,
     String mapUrl,
+    String fullDillUri,
     String sourceMapBase,
     String customScheme,
     String multiRootOutputPath,
@@ -705,19 +708,20 @@
       SharedCompiler.metricsLocationID, '$compileTimeStatistics');
 
   var debugMetadata = emitDebugMetadata
-      ? _emitMetadata(moduleTree, component, mapUrl, jsUrl)
+      ? _emitMetadata(moduleTree, component, mapUrl, jsUrl, fullDillUri)
       : null;
 
   return JSCode(text, builtMap, metadata: debugMetadata);
 }
 
 ModuleMetadata _emitMetadata(js_ast.Program program, Component component,
-    String sourceMapUri, String moduleUri) {
+    String sourceMapUri, String moduleUri, String fullDillUri) {
   var metadata = ModuleMetadata(
       program.name,
       loadFunctionName(program.name),
       sourceMapUri,
       moduleUri,
+      fullDillUri,
       component.mode == NonNullableByDefaultCompiledMode.Strong);
 
   for (var lib in component.libraries) {
diff --git a/pkg/dev_compiler/lib/src/kernel/module_metadata.dart b/pkg/dev_compiler/lib/src/kernel/module_metadata.dart
index deca70b..5669874 100644
--- a/pkg/dev_compiler/lib/src/kernel/module_metadata.dart
+++ b/pkg/dev_compiler/lib/src/kernel/module_metadata.dart
@@ -29,7 +29,7 @@
   ///
   /// TODO(annagrin): create metadata package, make version the same as the
   /// metadata package version, automate updating with the package update
-  static const ModuleMetadataVersion current = ModuleMetadataVersion(1, 0, 1);
+  static const ModuleMetadataVersion current = ModuleMetadataVersion(1, 0, 2);
 
   /// Current metadata version created by the reader
   String get version => '$majorVersion.$minorVersion.$patchVersion';
@@ -124,6 +124,12 @@
   /// Module uri
   final String moduleUri;
 
+  /// The uri where DDC wrote a full .dill file for this module.
+  ///
+  /// Can be `null` if the module was compiled without the option to output the
+  /// .dill fle.
+  final String fullDillUri;
+
   final Map<String, LibraryMetadata> libraries = {};
 
   /// True if the module corresponding to this metadata was compiled with sound
@@ -131,7 +137,7 @@
   final bool soundNullSafety;
 
   ModuleMetadata(this.name, this.closureName, this.sourceMapUri, this.moduleUri,
-      this.soundNullSafety,
+      this.fullDillUri, this.soundNullSafety,
       {this.version}) {
     version ??= ModuleMetadataVersion.current.version;
   }
@@ -157,6 +163,7 @@
         closureName = json['closureName'] as String,
         sourceMapUri = json['sourceMapUri'] as String,
         moduleUri = json['moduleUri'] as String,
+        fullDillUri = json['fullDillUri'] as String,
         soundNullSafety = json['soundNullSafety'] as bool {
     var fileVersion = json['version'] as String;
     if (!ModuleMetadataVersion.current.isCompatibleWith(version)) {
@@ -175,6 +182,7 @@
       'closureName': closureName,
       'sourceMapUri': sourceMapUri,
       'moduleUri': moduleUri,
+      'fullDillUri': fullDillUri,
       'libraries': [for (var lib in libraries.values) lib.toJson()],
       'soundNullSafety': soundNullSafety
     };
diff --git a/pkg/dev_compiler/test/module_metadata_test.dart b/pkg/dev_compiler/test/module_metadata_test.dart
index 06054cf..9d6c862 100644
--- a/pkg/dev_compiler/test/module_metadata_test.dart
+++ b/pkg/dev_compiler/test/module_metadata_test.dart
@@ -114,7 +114,8 @@
 }
 
 ModuleMetadata createMetadata(String version) => ModuleMetadata(
-    'module', 'closure', 'module.map', 'module.js', true, version: version)
+    'module', 'closure', 'module.map', 'module.js', 'module.full.dill', true,
+    version: version)
   ..addLibrary(LibraryMetadata('library', 'package:library/test.dart',
       'file:///source/library/lib/test.dart', ['src/test2.dart']));
 
@@ -125,6 +126,7 @@
   expect(module.closureName, 'closure');
   expect(module.sourceMapUri, 'module.map');
   expect(module.moduleUri, 'module.js');
+  expect(module.fullDillUri, 'module.full.dill');
   expect(module.soundNullSafety, true);
 
   var libUri = module.libraries.keys.first;
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index 4e08c4e..cb03daa 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -6568,8 +6568,7 @@
     DartType promotedType;
     DartType declaredOrInferredType = variable.lateType ?? variable.type;
     if (isExtensionThis(variable)) {
-      // Don't promote the synthetic variable `#this` that we use to represent
-      // `this` inside extension methods.
+      inferrer.flowAnalysis.thisOrSuper(node);
     } else if (inferrer.isNonNullableByDefault) {
       if (node.forNullGuardedAccess) {
         DartType nonNullableType = inferrer.computeNonNullable(variable.type);
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index 1814e5a..a7282a4 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -5021,4 +5021,9 @@
       return null;
     }
   }
+
+  @override
+  LocatedMessage visitThisNotPromoted(ThisNotPromoted reason) {
+    return messageThisNotPromoted.withoutLocation();
+  }
 }
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 316bc08..8e24091 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -751,6 +751,8 @@
 ThisAccessInFieldInitializer/example: Fail
 ThisAsIdentifier/example: Fail
 ThisInNullAwareReceiver/analyzerCode: Fail
+ThisNotPromoted/analyzerCode: Fail
+ThisNotPromoted/example: Fail
 ThisOrSuperAccessInFieldInitializer/example: Fail
 ThrowingNotAssignableToObjectError/analyzerCode: Fail
 ThrowingNotAssignableToObjectError/example: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 0f96e90..cc8fb0d 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -4569,6 +4569,9 @@
 FieldNotPromoted:
   template: "'#name' refers to a property so it could not be promoted."
 
+ThisNotPromoted:
+  template: "'this' can't be promoted."
+
 NullablePropertyAccessError:
   template: "Property '#name' cannot be accessed on '#type' because it is potentially null."
   tip: "Try accessing using ?. instead."
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 825fabe..28eb94e 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -227,7 +227,7 @@
 
 # Timeout. These tests do not run efficiently on our simulator or low-end
 # devices.
-[ $runtime == vm && ($arch == armv6 || $arch == simarm || $arch == simarm64 || $arch == simarmv6) ]
+[ $runtime == vm && ($arch == simarm || $arch == simarm64 || $arch == simarm64c) ]
 *: Skip
 
 [ $mode == debug || $runtime != vm || $system == android ]
diff --git a/pkg/status_file/test/data/vm.status b/pkg/status_file/test/data/vm.status
index 5db98f2..d04bfc5 100644
--- a/pkg/status_file/test/data/vm.status
+++ b/pkg/status_file/test/data/vm.status
@@ -50,7 +50,7 @@
 # On the simluator stack traces produced by the Profiler do not match
 # up with the real Dart stack trace and hence we don't get correct
 # symbol names.
-[ $arch == simarm || $arch == simarmv6 || $arch == simarm64 ]
+[ $arch == simarm || $arch == simarm64 || $arch == simarm64c]
 cc/Service_Profile: Skip
 cc/Profiler_AllocationSampleTest: Skip
 cc/Profiler_ArrayAllocation: Skip
diff --git a/runtime/observatory/tests/service/service.status b/runtime/observatory/tests/service/service.status
index 62efb1a..de8b15b 100644
--- a/runtime/observatory/tests/service/service.status
+++ b/runtime/observatory/tests/service/service.status
@@ -52,11 +52,11 @@
 [ $mode == debug && $system == windows && $checked ]
 async_scope_test: Pass, Slow
 
-[ $mode == debug && ($arch == simarm || $arch == simarm64) ]
+[ $mode == debug && ($arch == simarm || $arch == simarm64 || $arch == simarm64c) ]
 *: SkipSlow
 
 # These tests are slow on simulators.
-[ $arch == simarm || $arch == simarm64 ]
+[ $arch == simarm || $arch == simarm64 || $arch == simarm64c ]
 *: Pass, Slow
 
 # All tests use dart:io
diff --git a/runtime/observatory/tests/service/service_kernel.status b/runtime/observatory/tests/service/service_kernel.status
index 81cead9..16e2d93 100644
--- a/runtime/observatory/tests/service/service_kernel.status
+++ b/runtime/observatory/tests/service/service_kernel.status
@@ -211,7 +211,7 @@
 [ $arch == ia32 && $compiler == dartk ]
 valid_source_locations_test: Skip # Issue 34736, too slow.
 
-[ $arch != simarm && $arch != simarm64 && $compiler == dartk ]
+[ $arch != simarm && $arch != simarm64 && $arch != simarm64c && $compiler == dartk ]
 complex_reload_test: RuntimeError
 
 [ $compiler == dartk && $mode == debug ]
@@ -270,7 +270,7 @@
 step_through_switch_test: Skip # Times out. Issue 32137.
 step_through_switch_with_continue_test: Skip # Times out. Issue 32137.
 
-[ $compiler == dartk && ($arch == simarm || $arch == simarm64) ]
+[ $compiler == dartk && ($arch == simarm || $arch == simarm64 || $arch == simarm64c) ]
 add_breakpoint_rpc_kernel_test: RuntimeError # Issue #34736
 async_generator_breakpoint_test: SkipByDesign # No incremental compiler available.
 bad_reload_test: Skip # Times out on sim architectures, also RuntimeError.
diff --git a/runtime/observatory_2/tests/service_2/service_2.status b/runtime/observatory_2/tests/service_2/service_2.status
index ea6eaa1..8e5b462 100644
--- a/runtime/observatory_2/tests/service_2/service_2.status
+++ b/runtime/observatory_2/tests/service_2/service_2.status
@@ -54,11 +54,11 @@
 [ $mode == debug && $system == windows && $checked ]
 async_scope_test: Pass, Slow
 
-[ $mode == debug && ($arch == simarm || $arch == simarm64) ]
+[ $mode == debug && ($arch == simarm || $arch == simarm64 || $arch == simarm64c) ]
 *: SkipSlow
 
 # These tests are slow on simulators.
-[ $arch == simarm || $arch == simarm64 ]
+[ $arch == simarm || $arch == simarm64 || $arch == simarm64c ]
 *: Pass, Slow
 
 # All tests use dart:io
diff --git a/runtime/observatory_2/tests/service_2/service_2_kernel.status b/runtime/observatory_2/tests/service_2/service_2_kernel.status
index 470019e..f352aa6 100644
--- a/runtime/observatory_2/tests/service_2/service_2_kernel.status
+++ b/runtime/observatory_2/tests/service_2/service_2_kernel.status
@@ -210,7 +210,7 @@
 [ $arch == ia32 && $compiler == dartk ]
 valid_source_locations_test: Skip # Issue 34736, too slow.
 
-[ $arch != simarm && $arch != simarm64 && $compiler == dartk ]
+[ $arch != simarm && $arch != simarm64 && $arch != simarm64c && $compiler == dartk ]
 complex_reload_test: RuntimeError
 
 [ $compiler == dartk && $mode == debug ]
@@ -269,7 +269,7 @@
 step_through_switch_test: Skip # Times out. Issue 32137.
 step_through_switch_with_continue_test: Skip # Times out. Issue 32137.
 
-[ $compiler == dartk && ($arch == simarm || $arch == simarm64) ]
+[ $compiler == dartk && ($arch == simarm || $arch == simarm64 || $arch == simarm64c) ]
 add_breakpoint_rpc_kernel_test: RuntimeError # Issue #34736
 async_generator_breakpoint_test: SkipByDesign # No incremental compiler available.
 bad_reload_test: Skip # Times out on sim architectures, also RuntimeError.
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 964aafd..28b5073 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -176,7 +176,7 @@
 dart/transferable_test: Skip # This is performance test and somehow debug win ia32 bot's performance is unpredictable
 dart_2/transferable_test: Skip # This is performance test and somehow debug win ia32 bot's performance is unpredictable
 
-[ $arch != simarm && $arch != simarm64 && $compiler == dartk && $hot_reload ]
+[ $arch != simarm && $arch != simarm64 && $arch != simarm64c && $compiler == dartk && $hot_reload ]
 dart/data_uri_import_test/base64: Crash
 dart/data_uri_import_test/nocharset: Crash
 dart/data_uri_import_test/nomime: Crash
@@ -207,7 +207,7 @@
 # Enabling of dartk for sim{arm,arm64} revelaed these test failures, which
 # are to be triaged.  Isolate tests are skipped on purpose due to the usage of
 # batch mode.
-[ $compiler == dartk && $mode == debug && ($arch == simarm || $arch == simarm64) ]
+[ $compiler == dartk && $mode == debug && ($arch == simarm || $arch == simarm64 || $arch == simarm64c) ]
 cc/StackTraceMallocHookLengthTest: Fail # Please triage.
 
 [ $compiler == dartk && $mode == product && $runtime == vm ]
@@ -245,7 +245,7 @@
 dart/redirection_type_shuffling_test/00: Pass # Works in --checked mode but not in --strong mode.
 dart_2/redirection_type_shuffling_test/00: Pass # Works in --checked mode but not in --strong mode.
 
-[ $compiler == dartk && ($arch == simarm || $arch == simarm64) ]
+[ $compiler == dartk && ($arch == simarm || $arch == simarm64 || $arch == simarm64c) ]
 dart/appjit*: SkipSlow # DFE too slow
 dart/b162922506_test: SkipSlow # Generates large input file
 dart/data_uri_spawn_test: Skip # Please triage.
@@ -279,7 +279,7 @@
 dart_2/null_safety_autodetection_in_kernel_compiler_test: SkipByDesign # Test needs to run from source
 dart_2/snapshot_depfile_test: SkipByDesign # Test needs to run from source
 
-[ $compiler == dartkp && ($arch == simarm || $arch == simarm64) ]
+[ $compiler == dartkp && ($arch == simarm || $arch == simarm64 || $arch == simarm64c) ]
 dart/causal_stacks/async_throws_stack_lazy_non_symbolic_test: Pass, Slow
 dart_2/causal_stacks/async_throws_stack_lazy_non_symbolic_test: Pass, Slow
 
@@ -311,14 +311,14 @@
 [ $system != fuchsia && ($arch != x64 || $system != linux) ]
 cc/CodeExecutability: SkipByDesign # --dual-map-code not supported on non-Linux/Fuchsia
 
-[ $arch == arm || $arch == arm64 || $builder_tag == crossword || $builder_tag == crossword_ast || $compiler != dartkp || $system == linux && ($arch == simarm || $arch == simarm64) ]
+[ $arch == arm || $arch == arm64 || $builder_tag == crossword || $builder_tag == crossword_ast || $compiler != dartkp || $system == linux && ($arch == simarm || $arch == simarm64 || $arch == simarm64c) ]
 dart/v8_snapshot_profile_writer_test: SkipByDesign # Only relevant for AOT. Doesn't work in cross-compilation (has to run on the host). On Linux/simarm64 and Linux/simarm this test requires buildtools/clang which is not always available on testing shards.
 dart_2/v8_snapshot_profile_writer_test: SkipByDesign # Only relevant for AOT. Doesn't work in cross-compilation (has to run on the host). On Linux/simarm64 and Linux/simarm this test requires buildtools/clang which is not always available on testing shards.
 
 # On the simluator stack traces produced by the Profiler do not match
 # up with the real Dart stack trace and hence we don't get correct
 # symbol names.
-[ $arch == simarm || $arch == simarm64 ]
+[ $arch == simarm || $arch == simarm64 || $arch == simarm64c ]
 cc/LargeMap: SkipByDesign
 cc/Profiler_AllocationSampleTest: SkipByDesign
 cc/Profiler_ArrayAllocation: SkipByDesign
@@ -360,15 +360,15 @@
 dart_2/unboxed_param_tear_off_test: SkipByDesign # FFI helper not supported on simulator
 dart_2/unboxed_param_test: SkipByDesign # FFI helper not supported on simulator
 
-[ $arch == simarm || $arch == simarm64 || $system != macos ]
+[ $arch == simarm || $arch == simarm64 || $arch == simarm64c || $system != macos ]
 dart/thread_priority_macos_test: SkipByDesign
 dart_2/thread_priority_macos_test: SkipByDesign
 
-[ $arch == simarm || $arch == simarm64 || $system != windows ]
+[ $arch == simarm || $arch == simarm64 || $arch == simarm64c || $system != windows ]
 dart/thread_priority_windows_test: SkipByDesign
 dart_2/thread_priority_windows_test: SkipByDesign
 
-[ $arch == simarm || $arch == simarm64 || $system != android && $system != linux ]
+[ $arch == simarm || $arch == simarm64 || $arch == simarm64c || $system != android && $system != linux ]
 dart/thread_priority_linux_test: SkipByDesign
 dart_2/thread_priority_linux_test: SkipByDesign
 
@@ -410,7 +410,7 @@
 # as that would involve running CFE (the front end) in simulator mode
 # to compile the URI file specified in spawnURI code.
 # These Isolate tests that use spawnURI are hence skipped on purpose.
-[ $runtime == dart_precompiled || $runtime == vm && ($arch == simarm || $arch == simarm64) ]
+[ $runtime == dart_precompiled || $runtime == vm && ($arch == simarm || $arch == simarm64 || $arch == simarm64c) ]
 dart/data_uri_spawn_test: SkipByDesign # Isolate.spawnUri
 dart/issue32950_test: SkipByDesign # uses spawnUri.
 dart_2/data_uri_spawn_test: SkipByDesign # Isolate.spawnUri
diff --git a/runtime/vm/instructions_arm.cc b/runtime/vm/instructions_arm.cc
index 1c45ff9..3a9f84d 100644
--- a/runtime/vm/instructions_arm.cc
+++ b/runtime/vm/instructions_arm.cc
@@ -221,10 +221,7 @@
   Register dst;
   if (IsLoadWithOffset(instr, PP, &offset, &dst)) {
     intptr_t index = ObjectPool::IndexFromOffset(offset);
-    const ObjectPool& pool = ObjectPool::Handle(
-        FLAG_use_bare_instructions
-            ? IsolateGroup::Current()->object_store()->global_object_pool()
-            : code.object_pool());
+    const ObjectPool& pool = ObjectPool::Handle(code.GetObjectPool());
     if (!pool.IsNull() && (index < pool.Length()) &&
         (pool.TypeAt(index) == ObjectPool::EntryType::kTaggedObject)) {
       *obj = pool.ObjectAt(index);
diff --git a/runtime/vm/instructions_arm64.cc b/runtime/vm/instructions_arm64.cc
index d193510..35d0250 100644
--- a/runtime/vm/instructions_arm64.cc
+++ b/runtime/vm/instructions_arm64.cc
@@ -332,10 +332,7 @@
       // PP is untagged on ARM64.
       ASSERT(Utils::IsAligned(offset, 8));
       intptr_t index = ObjectPool::IndexFromOffset(offset - kHeapObjectTag);
-      const ObjectPool& pool = ObjectPool::Handle(
-          FLAG_use_bare_instructions
-              ? IsolateGroup::Current()->object_store()->global_object_pool()
-              : code.object_pool());
+      const ObjectPool& pool = ObjectPool::Handle(code.GetObjectPool());
       if (!pool.IsNull() && (index < pool.Length()) &&
           (pool.TypeAt(index) == ObjectPool::EntryType::kTaggedObject)) {
         *obj = pool.ObjectAt(index);
diff --git a/runtime/vm/instructions_x64.cc b/runtime/vm/instructions_x64.cc
index 7495066f..30d7ed7 100644
--- a/runtime/vm/instructions_x64.cc
+++ b/runtime/vm/instructions_x64.cc
@@ -54,20 +54,12 @@
     return Thread::ObjectAtOffset(offset, obj);
   }
 
-  // A code object may have an object pool attached in bare instructions mode
-  // if the v8 snapshot profile writer is active, but this pool cannot be used
-  // for object loading.
-  if (FLAG_use_bare_instructions) return false;
-
   COMPILE_ASSERT(PP == R15);
   if ((bytes[0] == 0x49) || (bytes[0] == 0x4d)) {
     if ((bytes[1] == 0x8b) || (bytes[1] == 0x3b)) {  // movq, cmpq
       if ((bytes[2] & 0xc7) == (0x80 | (PP & 7))) {  // [r15+disp32]
         intptr_t index = IndexFromPPLoadDisp32(pc + 3);
-        const ObjectPool& pool = ObjectPool::Handle(
-            FLAG_use_bare_instructions
-                ? IsolateGroup::Current()->object_store()->global_object_pool()
-                : code.object_pool());
+        const ObjectPool& pool = ObjectPool::Handle(code.GetObjectPool());
         if (!pool.IsNull() && (index < pool.Length()) &&
             (pool.TypeAt(index) == ObjectPool::EntryType::kTaggedObject)) {
           *obj = pool.ObjectAt(index);
@@ -76,10 +68,7 @@
       }
       if ((bytes[2] & 0xc7) == (0x40 | (PP & 7))) {  // [r15+disp8]
         intptr_t index = IndexFromPPLoadDisp8(pc + 3);
-        const ObjectPool& pool = ObjectPool::Handle(
-            FLAG_use_bare_instructions
-                ? IsolateGroup::Current()->object_store()->global_object_pool()
-                : code.object_pool());
+        const ObjectPool& pool = ObjectPool::Handle(code.GetObjectPool());
         if (!pool.IsNull() && (index < pool.Length()) &&
             (pool.TypeAt(index) == ObjectPool::EntryType::kTaggedObject)) {
           *obj = pool.ObjectAt(index);
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index f371e1b..16333fb 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -685,13 +685,14 @@
   UnscheduleThreadLocked(&ml, thread, is_mutator, bypass_safepoint);
 }
 
-void IsolateGroup::IncreaseMutatorCount(Isolate* mutator) {
+void IsolateGroup::IncreaseMutatorCount(Isolate* mutator,
+                                        bool is_nested_reenter) {
   ASSERT(mutator->group() == this);
 
   // If the mutator was temporarily blocked on a worker thread, we have to
   // unblock the worker thread again.
-  Thread* mutator_thread = mutator->mutator_thread();
-  if (mutator_thread != nullptr && mutator_thread->top_exit_frame_info() != 0) {
+  if (is_nested_reenter) {
+    ASSERT(mutator->mutator_thread() != nullptr);
     thread_pool()->MarkCurrentWorkerAsUnBlocked();
   }
 
@@ -712,15 +713,14 @@
   }
 }
 
-void IsolateGroup::DecreaseMutatorCount(Isolate* mutator) {
+void IsolateGroup::DecreaseMutatorCount(Isolate* mutator, bool is_nested_exit) {
   ASSERT(mutator->group() == this);
 
   // If the mutator thread has an active stack and runs on our thread pool we
   // will mark the worker as blocked, thereby possibly spawning a new worker for
   // pending tasks (if there are any).
-  Thread* mutator_thread = mutator->mutator_thread();
-  ASSERT(mutator_thread != nullptr);
-  if (mutator_thread->top_exit_frame_info() != 0) {
+  ASSERT(mutator->mutator_thread() != nullptr);
+  if (is_nested_exit) {
     thread_pool()->MarkCurrentWorkerAsBlocked();
   }
 
@@ -3608,9 +3608,11 @@
   return thread_registry_->threads_lock();
 }
 
-Thread* Isolate::ScheduleThread(bool is_mutator, bool bypass_safepoint) {
+Thread* Isolate::ScheduleThread(bool is_mutator,
+                                bool is_nested_reenter,
+                                bool bypass_safepoint) {
   if (is_mutator) {
-    group()->IncreaseMutatorCount(this);
+    group()->IncreaseMutatorCount(this, is_nested_reenter);
   }
 
   // We are about to associate the thread with an isolate group and it would
@@ -3656,6 +3658,7 @@
 
 void Isolate::UnscheduleThread(Thread* thread,
                                bool is_mutator,
+                               bool is_nested_exit,
                                bool bypass_safepoint) {
   {
     // Disassociate the 'Thread' structure and unschedule the thread
@@ -3685,7 +3688,7 @@
     group()->UnscheduleThreadLocked(&ml, thread, is_mutator, bypass_safepoint);
   }
   if (is_mutator) {
-    group()->DecreaseMutatorCount(this);
+    group()->DecreaseMutatorCount(this, is_nested_exit);
   }
 }
 
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 96f6908..a32105a 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -597,8 +597,8 @@
                         bool is_mutator,
                         bool bypass_safepoint = false);
 
-  void IncreaseMutatorCount(Isolate* mutator);
-  void DecreaseMutatorCount(Isolate* mutator);
+  void IncreaseMutatorCount(Isolate* mutator, bool is_nested_reenter);
+  void DecreaseMutatorCount(Isolate* mutator, bool is_nested_exit);
 
   bool HasTagHandler() const { return library_tag_handler() != nullptr; }
   ObjectPtr CallTagHandler(Dart_LibraryTag tag,
@@ -1512,10 +1512,13 @@
       const GrowableObjectArray& value);
 #endif  // !defined(PRODUCT)
 
-  Thread* ScheduleThread(bool is_mutator, bool bypass_safepoint = false);
+  Thread* ScheduleThread(bool is_mutator,
+                         bool is_nested_reenter,
+                         bool bypass_safepoint);
   void UnscheduleThread(Thread* thread,
                         bool is_mutator,
-                        bool bypass_safepoint = false);
+                        bool is_nested_exit,
+                        bool bypass_safepoint);
 
   // DEPRECATED: Use Thread's methods instead. During migration, these default
   // to using the mutator thread (which must also be the current thread).
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index 15f07a5..da39430 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -275,9 +275,16 @@
   }
 }
 
-bool Thread::EnterIsolate(Isolate* isolate) {
+bool Thread::EnterIsolate(Isolate* isolate, bool is_nested_reenter) {
   const bool kIsMutatorThread = true;
-  Thread* thread = isolate->ScheduleThread(kIsMutatorThread);
+  const bool kBypassSafepoint = false;
+
+  is_nested_reenter = is_nested_reenter ||
+                      (isolate->mutator_thread() != nullptr &&
+                       isolate->mutator_thread()->top_exit_frame_info() != 0);
+
+  Thread* thread = isolate->ScheduleThread(kIsMutatorThread, is_nested_reenter,
+                                           kBypassSafepoint);
   if (thread != NULL) {
     ASSERT(thread->store_buffer_block_ == NULL);
     ASSERT(thread->isolate() == isolate);
@@ -288,7 +295,7 @@
   return false;
 }
 
-void Thread::ExitIsolate() {
+void Thread::ExitIsolate(bool is_nested_exit) {
   Thread* thread = Thread::Current();
   ASSERT(thread != nullptr);
   ASSERT(thread->IsMutatorThread());
@@ -302,7 +309,12 @@
   thread->set_vm_tag(isolate->is_runnable() ? VMTag::kIdleTagId
                                             : VMTag::kLoadWaitTagId);
   const bool kIsMutatorThread = true;
-  isolate->UnscheduleThread(thread, kIsMutatorThread);
+  const bool kBypassSafepoint = false;
+  is_nested_exit =
+      is_nested_exit || (isolate->mutator_thread() != nullptr &&
+                         isolate->mutator_thread()->top_exit_frame_info() != 0);
+  isolate->UnscheduleThread(thread, kIsMutatorThread, is_nested_exit,
+                            kBypassSafepoint);
 }
 
 bool Thread::EnterIsolateAsHelper(Isolate* isolate,
@@ -310,7 +322,9 @@
                                   bool bypass_safepoint) {
   ASSERT(kind != kMutatorTask);
   const bool kIsMutatorThread = false;
-  Thread* thread = isolate->ScheduleThread(kIsMutatorThread, bypass_safepoint);
+  const bool kIsNestedReenter = false;
+  Thread* thread = isolate->ScheduleThread(kIsMutatorThread, kIsNestedReenter,
+                                           bypass_safepoint);
   if (thread != NULL) {
     ASSERT(!thread->IsMutatorThread());
     ASSERT(thread->isolate() == isolate);
@@ -333,7 +347,9 @@
   Isolate* isolate = thread->isolate();
   ASSERT(isolate != NULL);
   const bool kIsMutatorThread = false;
-  isolate->UnscheduleThread(thread, kIsMutatorThread, bypass_safepoint);
+  const bool kIsNestedExit = false;
+  isolate->UnscheduleThread(thread, kIsMutatorThread, kIsNestedExit,
+                            bypass_safepoint);
 }
 
 bool Thread::EnterIsolateGroupAsHelper(IsolateGroup* isolate_group,
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index 816ec27..40849d6e 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -267,9 +267,9 @@
   }
 
   // Makes the current thread enter 'isolate'.
-  static bool EnterIsolate(Isolate* isolate);
+  static bool EnterIsolate(Isolate* isolate, bool is_nested_reenter = false);
   // Makes the current thread exit its isolate.
-  static void ExitIsolate();
+  static void ExitIsolate(bool is_nested_exit = false);
 
   // A VM thread other than the main mutator thread can enter an isolate as a
   // "helper" to gain limited concurrent access to the isolate. One example is
diff --git a/runtime/vm/virtual_memory_compressed.cc b/runtime/vm/virtual_memory_compressed.cc
new file mode 100644
index 0000000..7d4b882
--- /dev/null
+++ b/runtime/vm/virtual_memory_compressed.cc
@@ -0,0 +1,132 @@
+// Copyright (c) 2021, 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.
+
+#include "vm/virtual_memory_compressed.h"
+
+#include "platform/utils.h"
+
+#if defined(DART_COMPRESSED_HEAP)
+
+namespace dart {
+
+uword VirtualMemoryCompressedHeap::base_ = 0;
+uint8_t* VirtualMemoryCompressedHeap::pages_ = nullptr;
+uword VirtualMemoryCompressedHeap::minimum_free_page_id_ = 0;
+Mutex* VirtualMemoryCompressedHeap::mutex_ = nullptr;
+
+uint8_t PageMask(uword page_id) {
+  return static_cast<uint8_t>(1 << (page_id % 8));
+}
+
+bool VirtualMemoryCompressedHeap::IsPageUsed(uword page_id) {
+  if (page_id >= kCompressedHeapNumPages) return false;
+  return pages_[page_id / 8] & PageMask(page_id);
+}
+
+void VirtualMemoryCompressedHeap::SetPageUsed(uword page_id) {
+  ASSERT(page_id < kCompressedHeapNumPages);
+  pages_[page_id / 8] |= PageMask(page_id);
+}
+
+void VirtualMemoryCompressedHeap::ClearPageUsed(uword page_id) {
+  ASSERT(page_id < kCompressedHeapNumPages);
+  pages_[page_id / 8] &= ~PageMask(page_id);
+}
+
+void VirtualMemoryCompressedHeap::Init(void* compressed_heap_region) {
+  pages_ = new uint8_t[kCompressedHeapBitmapSize];
+  memset(pages_, 0, kCompressedHeapBitmapSize);
+  base_ = reinterpret_cast<uword>(compressed_heap_region);
+  ASSERT(base_ != 0);
+  ASSERT(Utils::IsAligned(base_, kCompressedHeapSize));
+  mutex_ = new Mutex(NOT_IN_PRODUCT("compressed_heap_mutex"));
+}
+
+void VirtualMemoryCompressedHeap::Cleanup() {
+  delete[] pages_;
+  delete mutex_;
+  base_ = 0;
+  pages_ = nullptr;
+  minimum_free_page_id_ = 0;
+  mutex_ = nullptr;
+}
+
+void* VirtualMemoryCompressedHeap::GetRegion() {
+  return reinterpret_cast<void*>(base_);
+}
+
+MemoryRegion VirtualMemoryCompressedHeap::Allocate(intptr_t size,
+                                                   intptr_t alignment) {
+  ASSERT(alignment <= kCompressedHeapAlignment);
+  const intptr_t allocated_size = Utils::RoundUp(size, kCompressedHeapPageSize);
+  uword pages = allocated_size / kCompressedHeapPageSize;
+  uword page_alignment = alignment > kCompressedHeapPageSize
+                             ? alignment / kCompressedHeapPageSize
+                             : 1;
+  MutexLocker ml(mutex_);
+
+  // Find a gap with enough empty pages, using the bitmap. Note that reading
+  // outside the bitmap range always returns 0, so this loop will terminate.
+  uword page_id = Utils::RoundUp(minimum_free_page_id_, page_alignment);
+  for (uword gap = 0;;) {
+    if (IsPageUsed(page_id)) {
+      gap = 0;
+      page_id = Utils::RoundUp(page_id + 1, page_alignment);
+    } else {
+      ++gap;
+      if (gap >= pages) {
+        page_id += 1 - gap;
+        break;
+      }
+      ++page_id;
+    }
+  }
+  ASSERT(page_id % page_alignment == 0);
+
+  // Make sure we're not trying to allocate past the end of the heap.
+  uword end = page_id + pages;
+  if (end > kCompressedHeapSize / kCompressedHeapPageSize) {
+    return MemoryRegion();
+  }
+
+  // Mark all the pages in the bitmap as allocated.
+  for (uword i = page_id; i < end; ++i) {
+    ASSERT(!IsPageUsed(i));
+    SetPageUsed(i);
+  }
+
+  // Find the next free page, to speed up subsequent allocations.
+  while (IsPageUsed(minimum_free_page_id_)) {
+    ++minimum_free_page_id_;
+  }
+
+  uword address = base_ + page_id * kCompressedHeapPageSize;
+  ASSERT(Utils::IsAligned(address, kCompressedHeapPageSize));
+  return MemoryRegion(reinterpret_cast<void*>(address), allocated_size);
+}
+
+void VirtualMemoryCompressedHeap::Free(void* address, intptr_t size) {
+  uword start = reinterpret_cast<uword>(address);
+  ASSERT(Utils::IsAligned(start, kCompressedHeapPageSize));
+  ASSERT(Utils::IsAligned(size, kCompressedHeapPageSize));
+  MutexLocker ml(mutex_);
+  ASSERT(start >= base_);
+  uword page_id = (start - base_) / kCompressedHeapPageSize;
+  uword end = page_id + size / kCompressedHeapPageSize;
+  for (uword i = page_id; i < end; ++i) {
+    ClearPageUsed(i);
+  }
+  if (page_id < minimum_free_page_id_) {
+    minimum_free_page_id_ = page_id;
+  }
+}
+
+bool VirtualMemoryCompressedHeap::Contains(void* address) {
+  return reinterpret_cast<uword>(address) >= base_ &&
+         reinterpret_cast<uword>(address) < base_ + kCompressedHeapSize;
+}
+
+}  // namespace dart
+
+#endif  // defined(DART_COMPRESSED_HEAP)
diff --git a/runtime/vm/virtual_memory_compressed.h b/runtime/vm/virtual_memory_compressed.h
new file mode 100644
index 0000000..9b55243
--- /dev/null
+++ b/runtime/vm/virtual_memory_compressed.h
@@ -0,0 +1,68 @@
+// Copyright (c) 2021, 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.
+
+#ifndef RUNTIME_VM_VIRTUAL_MEMORY_COMPRESSED_H_
+#define RUNTIME_VM_VIRTUAL_MEMORY_COMPRESSED_H_
+
+#if defined(DART_COMPRESSED_POINTERS) && !defined(HOST_OS_FUCHSIA)
+#define DART_COMPRESSED_HEAP
+#endif  // defined(DART_COMPRESSED_POINTERS) && !defined(HOST_OS_FUCHSIA)
+
+#if defined(DART_COMPRESSED_HEAP)
+
+#include "vm/globals.h"
+#include "vm/heap/pages.h"
+#include "vm/memory_region.h"
+
+namespace dart {
+
+static constexpr intptr_t kCompressedHeapSize = 2 * GB;
+static constexpr intptr_t kCompressedHeapAlignment = 4 * GB;
+static constexpr intptr_t kCompressedHeapPageSize = kOldPageSize;
+static constexpr intptr_t kCompressedHeapNumPages =
+    kCompressedHeapSize / kOldPageSize;
+static constexpr intptr_t kCompressedHeapBitmapSize =
+    kCompressedHeapNumPages / 8;
+
+// Utilities for allocating memory within a contiguous region of memory, for use
+// with compressed pointers.
+class VirtualMemoryCompressedHeap : public AllStatic {
+ public:
+  // Initializes the compressed heap. The callee must allocate a region of
+  // kCompressedHeapSize bytes, aligned to kCompressedHeapSize.
+  static void Init(void* compressed_heap_region);
+
+  // Cleans up the compressed heap. The callee is responsible for freeing the
+  // region's memory.
+  static void Cleanup();
+
+  // Allocates a segment of the compressed heap with the given size. Returns a
+  // heap memory region if a large enough free segment can't be found.
+  static MemoryRegion Allocate(intptr_t size, intptr_t alignment);
+
+  // Frees a segment.
+  static void Free(void* address, intptr_t size);
+
+  // Returns whether the address is within the compressed heap.
+  static bool Contains(void* address);
+
+  // Returns a pointer to the compressed heap region.
+  static void* GetRegion();
+
+ private:
+  static bool IsPageUsed(uword page_id);
+  static void SetPageUsed(uword page_id);
+  static void ClearPageUsed(uword page_id);
+
+  static uword base_;
+  static uint8_t* pages_;
+  static uword minimum_free_page_id_;
+  static Mutex* mutex_;
+};
+
+}  // namespace dart
+
+#endif  // defined(DART_COMPRESSED_HEAP)
+
+#endif  // RUNTIME_VM_VIRTUAL_MEMORY_COMPRESSED_H_
diff --git a/runtime/vm/virtual_memory_posix.cc b/runtime/vm/virtual_memory_posix.cc
index 700bc33..9ae49f6 100644
--- a/runtime/vm/virtual_memory_posix.cc
+++ b/runtime/vm/virtual_memory_posix.cc
@@ -18,6 +18,7 @@
 #include "platform/utils.h"
 #include "vm/heap/pages.h"
 #include "vm/isolate.h"
+#include "vm/virtual_memory_compressed.h"
 
 // #define VIRTUAL_MEMORY_LOGGING 1
 #if defined(VIRTUAL_MEMORY_LOGGING)
@@ -45,21 +46,6 @@
 
 static void unmap(uword start, uword end);
 
-#if defined(DART_COMPRESSED_POINTERS)
-static uword compressed_heap_base_ = 0;
-static uint8_t* compressed_heap_pages_ = nullptr;
-static uword compressed_heap_minimum_free_page_id_ = 0;
-static Mutex* compressed_heap_mutex_ = nullptr;
-
-static constexpr intptr_t kCompressedHeapSize = 2 * GB;
-static constexpr intptr_t kCompressedHeapAlignment = 4 * GB;
-static constexpr intptr_t kCompressedHeapPageSize = kOldPageSize;
-static constexpr intptr_t kCompressedHeapNumPages =
-    kCompressedHeapSize / kOldPageSize;
-static constexpr intptr_t kCompressedHeapBitmapSize =
-    kCompressedHeapNumPages / 8;
-#endif  // defined(DART_COMPRESSED_POINTERS)
-
 static void* GenericMapAligned(int prot,
                                intptr_t size,
                                intptr_t alignment,
@@ -89,16 +75,11 @@
 
 void VirtualMemory::Init() {
 #if defined(DART_COMPRESSED_POINTERS)
-  if (compressed_heap_pages_ == nullptr) {
-    compressed_heap_pages_ = new uint8_t[kCompressedHeapBitmapSize];
-    memset(compressed_heap_pages_, 0, kCompressedHeapBitmapSize);
-    compressed_heap_base_ = reinterpret_cast<uword>(GenericMapAligned(
+  if (VirtualMemoryCompressedHeap::GetRegion() == nullptr) {
+    VirtualMemoryCompressedHeap::Init(GenericMapAligned(
         PROT_READ | PROT_WRITE, kCompressedHeapSize, kCompressedHeapAlignment,
         kCompressedHeapSize + kCompressedHeapAlignment,
         MAP_PRIVATE | MAP_ANONYMOUS));
-    ASSERT(compressed_heap_base_ != 0);
-    ASSERT(Utils::IsAligned(compressed_heap_base_, kCompressedHeapAlignment));
-    compressed_heap_mutex_ = new Mutex(NOT_IN_PRODUCT("compressed_heap_mutex"));
   }
 #endif  // defined(DART_COMPRESSED_POINTERS)
 
@@ -168,13 +149,10 @@
 
 void VirtualMemory::Cleanup() {
 #if defined(DART_COMPRESSED_POINTERS)
-  unmap(compressed_heap_base_, compressed_heap_base_ + kCompressedHeapSize);
-  delete[] compressed_heap_pages_;
-  delete compressed_heap_mutex_;
-  compressed_heap_base_ = 0;
-  compressed_heap_pages_ = nullptr;
-  compressed_heap_minimum_free_page_id_ = 0;
-  compressed_heap_mutex_ = nullptr;
+  uword heap_base =
+      reinterpret_cast<uword>(VirtualMemoryCompressedHeap::GetRegion());
+  unmap(heap_base, heap_base + kCompressedHeapSize);
+  VirtualMemoryCompressedHeap::Cleanup();
 #endif  // defined(DART_COMPRESSED_POINTERS)
 }
 
@@ -248,93 +226,6 @@
 }
 #endif  // defined(DUAL_MAPPING_SUPPORTED)
 
-#if defined(DART_COMPRESSED_POINTERS)
-uint8_t PageMask(uword page_id) {
-  return static_cast<uint8_t>(1 << (page_id % 8));
-}
-bool IsCompressedHeapPageUsed(uword page_id) {
-  if (page_id >= kCompressedHeapNumPages) return false;
-  return compressed_heap_pages_[page_id / 8] & PageMask(page_id);
-}
-void SetCompressedHeapPageUsed(uword page_id) {
-  ASSERT(page_id < kCompressedHeapNumPages);
-  compressed_heap_pages_[page_id / 8] |= PageMask(page_id);
-}
-void ClearCompressedHeapPageUsed(uword page_id) {
-  ASSERT(page_id < kCompressedHeapNumPages);
-  compressed_heap_pages_[page_id / 8] &= ~PageMask(page_id);
-}
-static MemoryRegion MapInCompressedHeap(intptr_t size, intptr_t alignment) {
-  ASSERT(alignment <= kCompressedHeapAlignment);
-  const intptr_t allocated_size = Utils::RoundUp(size, kCompressedHeapPageSize);
-  uword pages = allocated_size / kCompressedHeapPageSize;
-  uword page_alignment = alignment > kCompressedHeapPageSize
-                             ? alignment / kCompressedHeapPageSize
-                             : 1;
-  MutexLocker ml(compressed_heap_mutex_);
-
-  // Find a gap with enough empty pages, using the bitmap. Note that reading
-  // outside the bitmap range always returns 0, so this loop will terminate.
-  uword page_id =
-      Utils::RoundUp(compressed_heap_minimum_free_page_id_, page_alignment);
-  for (uword gap = 0;;) {
-    if (IsCompressedHeapPageUsed(page_id)) {
-      gap = 0;
-      page_id = Utils::RoundUp(page_id + 1, page_alignment);
-    } else {
-      ++gap;
-      if (gap >= pages) {
-        page_id += 1 - gap;
-        break;
-      }
-      ++page_id;
-    }
-  }
-  ASSERT(page_id % page_alignment == 0);
-
-  // Make sure we're not trying to allocate past the end of the heap.
-  uword end = page_id + pages;
-  if (end > kCompressedHeapSize / kCompressedHeapPageSize) {
-    return MemoryRegion();
-  }
-
-  // Mark all the pages in the bitmap as allocated.
-  for (uword i = page_id; i < end; ++i) {
-    ASSERT(!IsCompressedHeapPageUsed(i));
-    SetCompressedHeapPageUsed(i);
-  }
-
-  // Find the next free page, to speed up subsequent allocations.
-  while (IsCompressedHeapPageUsed(compressed_heap_minimum_free_page_id_)) {
-    ++compressed_heap_minimum_free_page_id_;
-  }
-
-  uword address = compressed_heap_base_ + page_id * kCompressedHeapPageSize;
-  ASSERT(Utils::IsAligned(address, kCompressedHeapPageSize));
-  return MemoryRegion(reinterpret_cast<void*>(address), allocated_size);
-}
-
-static void UnmapInCompressedHeap(uword start, uword size) {
-  ASSERT(Utils::IsAligned(start, kCompressedHeapPageSize));
-  ASSERT(Utils::IsAligned(size, kCompressedHeapPageSize));
-  MutexLocker ml(compressed_heap_mutex_);
-  ASSERT(start >= compressed_heap_base_);
-  uword page_id = (start - compressed_heap_base_) / kCompressedHeapPageSize;
-  uword end = page_id + size / kCompressedHeapPageSize;
-  for (uword i = page_id; i < end; ++i) {
-    ClearCompressedHeapPageUsed(i);
-  }
-  if (page_id < compressed_heap_minimum_free_page_id_) {
-    compressed_heap_minimum_free_page_id_ = page_id;
-  }
-}
-
-static bool IsInCompressedHeap(uword address) {
-  return address >= compressed_heap_base_ &&
-         address < compressed_heap_base_ + kCompressedHeapSize;
-}
-#endif  // defined(DART_COMPRESSED_POINTERS)
-
 VirtualMemory* VirtualMemory::AllocateAligned(intptr_t size,
                                               intptr_t alignment,
                                               bool is_executable,
@@ -352,7 +243,8 @@
 
 #if defined(DART_COMPRESSED_POINTERS)
   if (!is_executable) {
-    MemoryRegion region = MapInCompressedHeap(size, alignment);
+    MemoryRegion region =
+        VirtualMemoryCompressedHeap::Allocate(size, alignment);
     if (region.pointer() == nullptr) {
       return nullptr;
     }
@@ -446,8 +338,8 @@
 
 VirtualMemory::~VirtualMemory() {
 #if defined(DART_COMPRESSED_POINTERS)
-  if (IsInCompressedHeap(reserved_.start())) {
-    UnmapInCompressedHeap(reserved_.start(), reserved_.size());
+  if (VirtualMemoryCompressedHeap::Contains(reserved_.pointer())) {
+    VirtualMemoryCompressedHeap::Free(reserved_.pointer(), reserved_.size());
     return;
   }
 #endif  // defined(DART_COMPRESSED_POINTERS)
@@ -461,13 +353,13 @@
 }
 
 bool VirtualMemory::FreeSubSegment(void* address, intptr_t size) {
-  const uword start = reinterpret_cast<uword>(address);
 #if defined(DART_COMPRESSED_POINTERS)
   // Don't free the sub segment if it's managed by the compressed pointer heap.
-  if (IsInCompressedHeap(start)) {
+  if (VirtualMemoryCompressedHeap::Contains(address)) {
     return false;
   }
 #endif  // defined(DART_COMPRESSED_POINTERS)
+  const uword start = reinterpret_cast<uword>(address);
   unmap(start, start + size);
   return true;
 }
diff --git a/runtime/vm/virtual_memory_test.cc b/runtime/vm/virtual_memory_test.cc
index e50cb85..471c683 100644
--- a/runtime/vm/virtual_memory_test.cc
+++ b/runtime/vm/virtual_memory_test.cc
@@ -6,6 +6,7 @@
 #include "platform/assert.h"
 #include "vm/heap/heap.h"
 #include "vm/unit_test.h"
+#include "vm/virtual_memory_compressed.h"
 
 namespace dart {
 
@@ -26,8 +27,8 @@
   EXPECT(vm->address() != NULL);
   EXPECT_EQ(vm->start(), reinterpret_cast<uword>(vm->address()));
 #if defined(DART_COMPRESSED_POINTERS)
-  EXPECT_EQ(kOldPageSize, vm->size());
-  EXPECT_EQ(vm->start() + kOldPageSize, vm->end());
+  EXPECT_EQ(kCompressedHeapPageSize, vm->size());
+  EXPECT_EQ(vm->start() + kCompressedHeapPageSize, vm->end());
 #else
   EXPECT_EQ(kVirtualMemoryBlockSize, vm->size());
   EXPECT_EQ(vm->start() + kVirtualMemoryBlockSize, vm->end());
diff --git a/runtime/vm/virtual_memory_win.cc b/runtime/vm/virtual_memory_win.cc
index a220b91..f7322fb 100644
--- a/runtime/vm/virtual_memory_win.cc
+++ b/runtime/vm/virtual_memory_win.cc
@@ -8,9 +8,9 @@
 #include "vm/virtual_memory.h"
 
 #include "platform/assert.h"
-#include "vm/os.h"
-
 #include "vm/isolate.h"
+#include "vm/os.h"
+#include "vm/virtual_memory_compressed.h"
 
 namespace dart {
 
@@ -27,11 +27,46 @@
   return page_size;
 }
 
-void VirtualMemory::Init() {
-  page_size_ = CalculatePageSize();
+static void* AllocateAlignedImpl(intptr_t size,
+                                 intptr_t alignment,
+                                 intptr_t reserved_size,
+                                 int prot,
+                                 void** out_reserved_address) {
+  void* address = VirtualAlloc(nullptr, reserved_size, MEM_RESERVE, prot);
+  if (address == nullptr) {
+    return nullptr;
+  }
+
+  void* aligned_address = reinterpret_cast<void*>(
+      Utils::RoundUp(reinterpret_cast<uword>(address), alignment));
+  if (VirtualAlloc(aligned_address, size, MEM_COMMIT, prot) !=
+      aligned_address) {
+    VirtualFree(address, reserved_size, MEM_RELEASE);
+    return nullptr;
+  }
+
+  if (out_reserved_address != nullptr) {
+    *out_reserved_address = address;
+  }
+  return aligned_address;
 }
 
-void VirtualMemory::Cleanup() {}
+void VirtualMemory::Init() {
+  page_size_ = CalculatePageSize();
+
+#if defined(DART_COMPRESSED_POINTERS)
+  VirtualMemoryCompressedHeap::Init(AllocateAlignedImpl(
+      kCompressedHeapSize, kCompressedHeapAlignment,
+      kCompressedHeapSize + kCompressedHeapAlignment, PAGE_READWRITE, nullptr));
+#endif  // defined(DART_COMPRESSED_POINTERS)
+}
+
+void VirtualMemory::Cleanup() {
+#if defined(DART_COMPRESSED_POINTERS)
+  VirtualFree(VirtualMemoryCompressedHeap::Cleanup(), kCompressedHeapSize,
+              MEM_RELEASE);
+#endif  // defined(DART_COMPRESSED_POINTERS)
+}
 
 bool VirtualMemory::DualMappingEnabled() {
   return false;
@@ -47,25 +82,32 @@
   ASSERT(Utils::IsAligned(size, PageSize()));
   ASSERT(Utils::IsPowerOfTwo(alignment));
   ASSERT(Utils::IsAligned(alignment, PageSize()));
+
+#if defined(DART_COMPRESSED_POINTERS)
+  if (!is_executable) {
+    MemoryRegion region =
+        VirtualMemoryCompressedHeap::Allocate(size, alignment);
+    if (region.pointer() == nullptr) {
+      return nullptr;
+    }
+    return new VirtualMemory(region, region);
+  }
+#endif  // defined(DART_COMPRESSED_POINTERS)
+
   intptr_t reserved_size = size + alignment - PageSize();
   int prot = (is_executable && !FLAG_write_protect_code)
                  ? PAGE_EXECUTE_READWRITE
                  : PAGE_READWRITE;
-  void* address = VirtualAlloc(NULL, reserved_size, MEM_RESERVE, prot);
-  if (address == NULL) {
-    return NULL;
-  }
 
-  void* aligned_address = reinterpret_cast<void*>(
-      Utils::RoundUp(reinterpret_cast<uword>(address), alignment));
-  if (VirtualAlloc(aligned_address, size, MEM_COMMIT, prot) !=
-      aligned_address) {
-    VirtualFree(address, reserved_size, MEM_RELEASE);
-    return NULL;
+  void* reserved_address;
+  void* aligned_address = AllocateAlignedImpl(size, alignment, reserved_size,
+                                              prot, &reserved_address);
+  if (aligned_address == nullptr) {
+    return nullptr;
   }
 
   MemoryRegion region(aligned_address, size);
-  MemoryRegion reserved(address, reserved_size);
+  MemoryRegion reserved(reserved_address, reserved_size);
   return new VirtualMemory(region, reserved);
 }
 
@@ -74,6 +116,12 @@
   // Truncate(0, true) but that does not actually release the mapping
   // itself. The only way to release the mapping is to invoke VirtualFree
   // with original base pointer and MEM_RELEASE.
+#if defined(DART_COMPRESSED_POINTERS)
+  if (VirtualMemoryCompressedHeap::Contains(reserved_.pointer())) {
+    VirtualMemoryCompressedHeap::Free(reserved_.pointer(), reserved_.size());
+    return;
+  }
+#endif  // defined(DART_COMPRESSED_POINTERS)
   if (!vm_owns_region()) {
     return;
   }
@@ -83,6 +131,12 @@
 }
 
 bool VirtualMemory::FreeSubSegment(void* address, intptr_t size) {
+#if defined(DART_COMPRESSED_POINTERS)
+  // Don't free the sub segment if it's managed by the compressed pointer heap.
+  if (VirtualMemoryCompressedHeap::Contains(address)) {
+    return false;
+  }
+#endif  // defined(DART_COMPRESSED_POINTERS)
   if (VirtualFree(address, size, MEM_DECOMMIT) == 0) {
     FATAL1("VirtualFree failed: Error code %d\n", GetLastError());
   }
diff --git a/runtime/vm/vm_sources.gni b/runtime/vm/vm_sources.gni
index 72c9a91..a142449 100644
--- a/runtime/vm/vm_sources.gni
+++ b/runtime/vm/vm_sources.gni
@@ -351,6 +351,8 @@
   "v8_snapshot_writer.h",
   "virtual_memory.cc",
   "virtual_memory.h",
+  "virtual_memory_compressed.cc",
+  "virtual_memory_compressed.h",
   "virtual_memory_fuchsia.cc",
   "virtual_memory_posix.cc",
   "virtual_memory_win.cc",
diff --git a/samples/samples.status b/samples/samples.status
index 2fe1de2..6f471b2 100644
--- a/samples/samples.status
+++ b/samples/samples.status
@@ -20,7 +20,7 @@
 [ $compiler == none && $runtime == vm && $system == fuchsia ]
 *: Skip # Not yet triaged.
 
-[ $arch == simarm || $arch == simarm64 ]
+[ $arch == simarm || $arch == simarm64 || $arch == simarm64c ]
 ffi/*: SkipByDesign # FFI skips, see ffi.status
 
 [ $arch != x64 || $compiler != dartk || $system != linux || $hot_reload || $hot_reload_rollback ]
diff --git a/samples_2/samples_2.status b/samples_2/samples_2.status
index 2fe1de2..6f471b2 100644
--- a/samples_2/samples_2.status
+++ b/samples_2/samples_2.status
@@ -20,7 +20,7 @@
 [ $compiler == none && $runtime == vm && $system == fuchsia ]
 *: Skip # Not yet triaged.
 
-[ $arch == simarm || $arch == simarm64 ]
+[ $arch == simarm || $arch == simarm64 || $arch == simarm64c ]
 ffi/*: SkipByDesign # FFI skips, see ffi.status
 
 [ $arch != x64 || $compiler != dartk || $system != linux || $hot_reload || $hot_reload_rollback ]
diff --git a/tests/co19/co19-kernel.status b/tests/co19/co19-kernel.status
index 82030bb..d8b00ce 100644
--- a/tests/co19/co19-kernel.status
+++ b/tests/co19/co19-kernel.status
@@ -184,10 +184,6 @@
 LanguageFeatures/regression/34803_t01: Crash
 LanguageFeatures/regression/34803_t02: Crash
 
-[ $arch == simarm64 && $runtime == dart_precompiled ]
-LibTest/collection/ListBase/ListBase_class_A01_t01: Skip # Issue 43036
-LibTest/collection/ListMixin/ListMixin_class_A01_t01: Skip # Issue 43036
-
 [ $compiler == dartk && $runtime == vm && $system == linux ]
 LibTest/isolate/Isolate/spawn_A06_t03: Crash
 
@@ -202,9 +198,13 @@
 [ $compiler == dartk && $runtime != vm ]
 Language/Classes/Constructors/Constant_Constructors/potentially_constant_expression_t01: Crash
 
+[ $runtime == dart_precompiled && ($arch == simarm64 || $arch == simarm64c) ]
+LibTest/collection/ListBase/ListBase_class_A01_t01: Skip # Issue 43036
+LibTest/collection/ListMixin/ListMixin_class_A01_t01: Skip # Issue 43036
+
 # It makes no sense to run any test that uses spawnURI under the simulator
 # as that would involve running CFE (the front end) in simulator mode
 # to compile the URI file specified in spawnURI code.
 # These Isolate tests that use spawnURI are hence skipped on purpose.
-[ $runtime == dart_precompiled || $runtime == vm && ($arch == simarm || $arch == simarm64) ]
+[ $runtime == dart_precompiled || $runtime == vm && ($arch == simarm || $arch == simarm64 || $arch == simarm64c) ]
 LibTest/isolate/Isolate/spawnUri*: Skip
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index 7922202..d54175c 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -10,9 +10,6 @@
 LibTest/io/Stdin/readByteSync_A01_t01: Skip # Issue 43645
 LibTest/io/Stdin/readByteSync_A01_t02: Skip # Issue 43645
 
-[ $arch == simarm64 && $runtime == dart_precompiled ]
-LibTest/async/Stream/Stream.periodic_all_t02: Skip # Issue 42898
-
 [ $compiler != dart2js && $runtime != none && $runtime != vm && !$checked ]
 LibTest/async/Future/catchError_A03_t05: RuntimeError
 
@@ -30,7 +27,10 @@
 LibTest/core/List/List_all_t05: SkipSlow # Very slow compilation in debug mode.
 LibTest/core/List/List_all_t06: SkipSlow # Very slow compilation in debug mode.
 
-[ $arch == simarm || $arch == simarm64 ]
+[ $runtime == dart_precompiled && ($arch == simarm64 || $arch == simarm64c) ]
+LibTest/async/Stream/Stream.periodic_all_t02: Skip # Issue 42898
+
+[ $arch == simarm || $arch == simarm64 || $arch == simarm64c ]
 LibTest/collection/ListBase/ListBase_class_A01_t01: SkipSlow # Very slow on sim* architectures.
 LibTest/collection/ListBase/ListBase_class_A01_t04: SkipSlow # Very slow on sim* architectures.
 LibTest/collection/ListBase/ListBase_class_A01_t05: SkipSlow # Very slow on sim* architectures.
diff --git a/tests/co19_2/co19_2-kernel.status b/tests/co19_2/co19_2-kernel.status
index 3a0f103..6af3349 100644
--- a/tests/co19_2/co19_2-kernel.status
+++ b/tests/co19_2/co19_2-kernel.status
@@ -191,5 +191,5 @@
 # as that would involve running CFE (the front end) in simulator mode
 # to compile the URI file specified in spawnURI code.
 # These Isolate tests that use spawnURI are hence skipped on purpose.
-[ $runtime == dart_precompiled || $runtime == vm && ($arch == simarm || $arch == simarm64) ]
+[ $runtime == dart_precompiled || $runtime == vm && ($arch == simarm || $arch == simarm64 || $arch == simarm64c) ]
 LibTest/isolate/Isolate/spawnUri*: Skip
diff --git a/tests/co19_2/co19_2-runtime.status b/tests/co19_2/co19_2-runtime.status
index 4246d55..a09c881 100644
--- a/tests/co19_2/co19_2-runtime.status
+++ b/tests/co19_2/co19_2-runtime.status
@@ -22,7 +22,7 @@
 LibTest/collection/ListMixin/ListMixin_class_A01_t05: SkipSlow # Very slow compilation in debug mode.
 LibTest/collection/ListMixin/ListMixin_class_A01_t06: SkipSlow # Very slow compilation in debug mode.
 
-[ $arch == simarm || $arch == simarm64 ]
+[ $arch == simarm || $arch == simarm64 || $arch == simarm64c ]
 LibTest/collection/ListBase/ListBase_class_A01_t01: SkipSlow # Very slow on sim* architectures.
 LibTest/collection/ListBase/ListBase_class_A01_t04: SkipSlow # Very slow on sim* architectures.
 LibTest/collection/ListBase/ListBase_class_A01_t05: SkipSlow # Very slow on sim* architectures.
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index b02678d..8e3de55 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -36,7 +36,7 @@
 iterable_return_type_int64_test: SkipByDesign # Requires int64 support.
 typed_data_with_limited_ints_test: SkipByDesign # Requires fixed-size int64 support.
 
-[ $arch == simarm || $arch == simarm64 ]
+[ $arch == simarm || $arch == simarm64 || $arch == simarm64c ]
 bigint_parse_radix_test: Skip # Issue 31659
 bigint_test: Skip # Issue 31659
 
diff --git a/tests/corelib_2/corelib_2.status b/tests/corelib_2/corelib_2.status
index a4e1987..8759284 100644
--- a/tests/corelib_2/corelib_2.status
+++ b/tests/corelib_2/corelib_2.status
@@ -47,7 +47,7 @@
 iterable_return_type_int64_test: SkipByDesign # Requires int64 support.
 typed_data_with_limited_ints_test: SkipByDesign # Requires fixed-size int64 support.
 
-[ $arch == simarm || $arch == simarm64 ]
+[ $arch == simarm || $arch == simarm64 || $arch == simarm64c ]
 bigint_parse_radix_test: Skip # Issue 31659
 bigint_test: Skip # Issue 31659
 
diff --git a/tests/ffi/ffi.status b/tests/ffi/ffi.status
index 37ab3e9..f728d98 100644
--- a/tests/ffi/ffi.status
+++ b/tests/ffi/ffi.status
@@ -17,7 +17,7 @@
 [ $system != android && $system != linux && $system != macos && $system != windows ]
 *: Skip # FFI not yet supported on other OSes.
 
-[ $arch == simarm || $arch == simarm64 ]
+[ $arch == simarm || $arch == simarm64 || $arch == simarm64c ]
 *: Skip # FFI not yet supported on the arm simulator.
 
 [ $builder_tag == asan || $builder_tag == msan || $builder_tag == tsan ]
diff --git a/tests/ffi_2/ffi_2.status b/tests/ffi_2/ffi_2.status
index 37ab3e9..f728d98 100644
--- a/tests/ffi_2/ffi_2.status
+++ b/tests/ffi_2/ffi_2.status
@@ -17,7 +17,7 @@
 [ $system != android && $system != linux && $system != macos && $system != windows ]
 *: Skip # FFI not yet supported on other OSes.
 
-[ $arch == simarm || $arch == simarm64 ]
+[ $arch == simarm || $arch == simarm64 || $arch == simarm64c ]
 *: Skip # FFI not yet supported on the arm simulator.
 
 [ $builder_tag == asan || $builder_tag == msan || $builder_tag == tsan ]
diff --git a/tests/language/generic/generic_metadata_test.dart b/tests/language/generic/generic_metadata_test.dart
new file mode 100644
index 0000000..ce15283
--- /dev/null
+++ b/tests/language/generic/generic_metadata_test.dart
@@ -0,0 +1,237 @@
+// Copyright (c) 2021, 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.
+
+// SharedOptions=--enable-experiment=generic-metadata
+
+// Check that metadata constructor invocations can have type arguments.
+
+@A<int>(0)
+library generic_metadata_test;
+
+@A<int>(0)
+import "dart:core";
+
+@A<int>(0)
+export "dart:core";
+
+// The annotation to use.
+class A<T> {
+  final T value;
+
+  const A(this.value);
+}
+
+// Annotations on various declarations.
+
+// Library declarations.
+@A<int>(0)
+const c = 0;
+
+@A<int>(0)
+final f = 0;
+
+@A<int>(0)
+void mp(@A<int>(0) Object x, [@A<int>(0) int y = 0]) {}
+
+@A<int>(0)
+void mn(@A<int>(0) Object x, {@A<int>(0) int y = 0}) {}
+
+@A<int>(0)
+int get g => 0;
+
+@A<int>(0)
+void set s(@A<int>(0) int x) {}
+
+// Class declaration and members.
+@A<int>(0)
+class C<@A<int>(0) T> {
+  final value;
+
+  // Constructor and initializing formal.
+  @A<int>(0)
+  const C(@A<int>(0) this.value);
+
+  @A<int>(0)
+  C.genRed(@A<int>(0) int x) : this(x);
+
+  @A<int>(0)
+  factory C.fac(@A<int>(0) int x) => C(x);
+
+  @A<int>(0)
+  factory C.facRed(@A<int>(0) int x) = C;
+
+  // Instance (virtual) declartions.
+  @A<int>(0)
+  final f = 0;
+
+  @A<int>(0)
+  void mp(@A<int>(0) Object x, [@A<int>(0) int y = 0]) {}
+
+  @A<int>(0)
+  void mn(@A<int>(0) Object x, {@A<int>(0) int y = 0}) {}
+
+  @A<int>(0)
+  int get g => 0;
+
+  @A<int>(0)
+  void set s(@A<int>(0) int x) {}
+
+  @A<int>(0)
+  int operator +(@A<int>(0) int x) => x;
+
+  // Static declartions.
+  @A<int>(0)
+  static const sc = C<int>(0);
+
+  @A<int>(0)
+  static final sf = C<int>(0);
+
+  @A<int>(0)
+  static void smp(@A<int>(0) Object x, [@A<int>(0) int y = 0]) {}
+
+  @A<int>(0)
+  static void smn(@A<int>(0) Object x, {@A<int>(0) int y = 0}) {}
+
+  @A<int>(0)
+  static int get sg => 0;
+
+  @A<int>(0)
+  static void set ss(@A<int>(0) int x) {}
+}
+
+@A<int>(0)
+abstract class AC<@A<int>(0) T> {
+  // Instance (virtual) declartions.
+  @A<int>(0)
+  abstract final f;
+
+  @A<int>(0)
+  void mp(@A<int>(0) Object x, [@A<int>(0) int y = 0]);
+
+  @A<int>(0)
+  void mn(@A<int>(0) Object x, {@A<int>(0) int y = 0});
+
+  @A<int>(0)
+  int get g;
+
+  @A<int>(0)
+  void set s(@A<int>(0) int x);
+
+  @A<int>(0)
+  int operator +(@A<int>(0) int x);
+}
+
+@A<int>(0)
+extension E<@A<int>(0) T> on T {
+  // Instance extension member declartions.
+  @A<int>(0)
+  void mp(@A<int>(0) Object x, [@A<int>(0) int y = 0]) {}
+
+  @A<int>(0)
+  void mn(@A<int>(0) Object x, {@A<int>(0) int y = 0}) {}
+
+  @A<int>(0)
+  int get g => 0;
+
+  @A<int>(0)
+  void set s(@A<int>(0) int x) {}
+
+  @A<int>(0)
+  int operator +(@A<int>(0) int x) => x;
+
+  // Static declartions.
+  @A<int>(0)
+  static const sc = C<int>(0);
+
+  @A<int>(0)
+  static final sf = C<int>(0);
+
+  @A<int>(0)
+  static void smp(@A<int>(0) Object x, [@A<int>(0) int y = 0]) {}
+
+  @A<int>(0)
+  static void smn(@A<int>(0) Object x, {@A<int>(0) int y = 0}) {}
+
+  @A<int>(0)
+  static int get sg => 0;
+
+  @A<int>(0)
+  static void set ss(@A<int>(0) int x) {}
+}
+
+@A<int>(0)
+mixin M<@A<int>(0) T> {
+  // Instance member declartions.
+  @A<int>(0)
+  final f = 0;
+
+  @A<int>(0)
+  void mp(@A<int>(0) Object x, [@A<int>(0) int y = 0]) {}
+
+  @A<int>(0)
+  void mn(@A<int>(0) Object x, {@A<int>(0) int y = 0}) {}
+
+  @A<int>(0)
+  int get g => 0;
+
+  @A<int>(0)
+  void set s(@A<int>(0) int x) {}
+
+  @A<int>(0)
+  int operator +(@A<int>(0) int x) => x;
+
+  // Static declartions.
+  @A<int>(0)
+  static const sc = C<int>(0);
+
+  @A<int>(0)
+  static final sf = C<int>(0);
+
+  @A<int>(0)
+  static void smp(@A<int>(0) Object x, [@A<int>(0) int y = 0]) {}
+
+  @A<int>(0)
+  static void smn(@A<int>(0) Object x, {@A<int>(0) int y = 0}) {}
+
+  @A<int>(0)
+  static int get sg => 0;
+
+  @A<int>(0)
+  static void set ss(@A<int>(0) int x) {}
+}
+
+@A<int>(0)
+enum En {
+ @A<int>(0)
+ foo
+}
+
+@A<int>(0)
+typedef F<@A<int>(0) T> = int Function<@A<int>(0) X>(@A<int>(0) int);
+
+void main() {
+  // Function body declarations.
+  @A<int>(0)
+  const c = 0;
+
+  @A<int>(0)
+  final f = 0;
+
+  @A<int>(0)
+  void mp(@A<int>(0) Object x, [@A<int>(0) int y = 0]) {}
+
+  @A<int>(0)
+  void mn(@A<int>(0) Object x, {@A<int>(0) int y = 0}) {}
+
+  @A<int>(0)
+  void Function<@A<int>(0) X>(@A<int>(0) int y)? fv = null;
+
+  // Recursive annotations.
+  @A<void Function(@A<int>(0) int)?>(null)
+  var x = 0;
+
+  mn(c);
+  mp(f);
+  fv?.call(x);
+}
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index ab707d3..9069e5b 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -4,8 +4,8 @@
 html/cross_frame_test: Skip # Issue 32039, test reloads itself (not by design - investigate)
 wasm/*: Skip # dart:wasm is currently behind a Dart SDK build flag.
 
-[ $arch == simarm64 ]
-convert/utf85_test: Skip # Pass, Slow Issue 20111.
+[ $arch == simarm ]
+convert/utf85_test: Skip # Pass, Slow Issue 12644.
 
 [ $mode == product ]
 developer/timeline_test: Skip # Not supported
@@ -60,8 +60,8 @@
 [ $runtime != dart_precompiled && ($runtime != vm || $compiler != dartk && $compiler != none) ]
 isolate/vm_rehash_test: SkipByDesign
 
-[ $arch == simarm || $arch == simarmv6 ]
-convert/utf85_test: Skip # Pass, Slow Issue 12644.
+[ $arch == simarm64 || $arch == simarm64c ]
+convert/utf85_test: Skip # Pass, Slow Issue 20111.
 
 [ $arch != x64 || $runtime != vm ]
 isolate/int32_length_overflow_test: SkipSlow
@@ -77,7 +77,7 @@
 # as that would involve running CFE (the front end) in simulator mode
 # to compile the URI file specified in spawnURI code.
 # These Isolate tests that use spawnURI are hence skipped on purpose.
-[ $runtime == dart_precompiled || $runtime == vm && ($arch == simarm || $arch == simarm64) ]
+[ $runtime == dart_precompiled || $runtime == vm && ($arch == simarm || $arch == simarm64 || $arch == simarm64c) ]
 isolate/count_test: Skip # Isolate.spawnUri
 isolate/cross_isolate_message_test: Skip # Isolate.spawnUri
 isolate/deferred_in_isolate2_test: Skip # Isolate.spawnUri
diff --git a/tests/lib/lib_vm.status b/tests/lib/lib_vm.status
index c693924..2489080 100644
--- a/tests/lib/lib_vm.status
+++ b/tests/lib/lib_vm.status
@@ -14,11 +14,12 @@
 [ $arch == ia32 && $mode == debug && $runtime == vm && $system == windows ]
 convert/streamed_conversion_json_utf8_decode_test: Skip # Verification OOM.
 
-[ $arch != ia32 && $arch != simarm && $arch != simarmv6 && $arch != x64 && $mode == debug && $runtime == vm ]
+[ $arch != ia32 && $arch != simarm && $arch != x64 && $mode == debug && $runtime == vm ]
 convert/streamed_conversion_json_utf8_decode_test: Skip # Verification not yet implemented.
 
-[ $arch == simarm64 && $runtime == vm ]
-convert/utf85_test: Skip # Pass, Slow Issue 20111.
+[ $arch == simarm && $runtime == vm ]
+convert/chunked_conversion_utf88_test: Skip # Pass, Slow Issue 12644.
+convert/utf85_test: Skip # Pass, Slow Issue 12644.
 
 [ $compiler != app_jitk && $compiler != dartk && $runtime == vm ]
 async/future_or_only_in_async_test/00: MissingCompileTimeError
@@ -78,17 +79,14 @@
 mirrors/library_uri_io_test: RuntimeError
 mirrors/library_uri_package_test: RuntimeError
 
-[ $runtime == vm && ($arch == simarm || $arch == simarmv6) ]
-convert/utf85_test: Skip # Pass, Slow Issue 12644.
+[ $runtime == vm && ($arch == simarm64 || $arch == simarm64c) ]
+convert/utf85_test: Skip # Pass, Slow Issue 20111.
 
-[ $arch == simarm || $arch == simarm64 || $hot_reload || $hot_reload_rollback ]
+[ $arch == simarm || $arch == simarm64 || $arch == simarm64c || $hot_reload || $hot_reload_rollback ]
 convert/chunked_conversion_utf88_test: SkipSlow
 convert/streamed_conversion_json_utf8_decode_test: SkipSlow
 convert/utf85_test: SkipSlow
 
-[ $arch == simarmv6 || $arch == simarm && $runtime == vm ]
-convert/chunked_conversion_utf88_test: Skip # Pass, Slow Issue 12644.
-
 [ $hot_reload || $hot_reload_rollback ]
 isolate/bool_from_environment_default_value_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/capability_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
diff --git a/tests/lib_2/lib_2.status b/tests/lib_2/lib_2.status
index f338b66..5a1d63b 100644
--- a/tests/lib_2/lib_2.status
+++ b/tests/lib_2/lib_2.status
@@ -4,8 +4,8 @@
 html/cross_frame_test: Skip # Issue 32039, test reloads itself (not by design - investigate)
 wasm/*: Skip # dart:wasm is currently behind a Dart SDK build flag.
 
-[ $arch == simarm64 ]
-convert/utf85_test: Skip # Pass, Slow Issue 20111.
+[ $arch == simarm ]
+convert/utf85_test: Skip # Pass, Slow Issue 12644.
 
 [ $mode == product ]
 developer/timeline_test: Skip # Not supported
@@ -60,8 +60,8 @@
 [ $runtime != dart_precompiled && ($runtime != vm || $compiler != dartk && $compiler != none) ]
 isolate/vm_rehash_test: SkipByDesign
 
-[ $arch == simarm || $arch == simarmv6 ]
-convert/utf85_test: Skip # Pass, Slow Issue 12644.
+[ $arch == simarm64 || $arch == simarm64c ]
+convert/utf85_test: Skip # Pass, Slow Issue 20111.
 
 [ $arch != x64 || $runtime != vm ]
 isolate/int32_length_overflow_test: SkipSlow
@@ -77,7 +77,7 @@
 # as that would involve running CFE (the front end) in simulator mode
 # to compile the URI file specified in spawnURI code.
 # These Isolate tests that use spawnURI are hence skipped on purpose.
-[ $runtime == dart_precompiled || $runtime == vm && ($arch == simarm || $arch == simarm64) ]
+[ $runtime == dart_precompiled || $runtime == vm && ($arch == simarm || $arch == simarm64 || $arch == simarm64c) ]
 isolate/count_test: Skip # Isolate.spawnUri
 isolate/cross_isolate_message_test: Skip # Isolate.spawnUri
 isolate/deferred_in_isolate2_test: Skip # Isolate.spawnUri
diff --git a/tests/lib_2/lib_2_vm.status b/tests/lib_2/lib_2_vm.status
index 4820450..0cdb365 100644
--- a/tests/lib_2/lib_2_vm.status
+++ b/tests/lib_2/lib_2_vm.status
@@ -69,7 +69,7 @@
 mirrors/library_uri_io_test: RuntimeError
 mirrors/library_uri_package_test: RuntimeError
 
-[ $arch == simarm || $arch == simarm64 || $hot_reload || $hot_reload_rollback ]
+[ $arch == simarm || $arch == simarm64 || $arch ==simarm64c || $hot_reload || $hot_reload_rollback ]
 convert/chunked_conversion_utf88_test: SkipSlow
 convert/streamed_conversion_json_utf8_decode_test: SkipSlow
 convert/utf85_test: SkipSlow
diff --git a/tests/standalone/standalone_kernel.status b/tests/standalone/standalone_kernel.status
index c444a59..cf3bf1f 100644
--- a/tests/standalone/standalone_kernel.status
+++ b/tests/standalone/standalone_kernel.status
@@ -20,9 +20,6 @@
 [ $arch == ia32 && $builder_tag == optimization_counter_threshold ]
 io/file_lock_test: SkipSlow # Timeout
 
-[ $arch == simarm64 && $compiler == dartk ]
-io/http_bind_test: Slow, Pass
-
 [ $builder_tag == optimization_counter_threshold && $compiler == dartk ]
 map_insert_remove_oom_test: Skip # Heap limit too low.
 
@@ -57,11 +54,14 @@
 # Enabling of dartk for sim{arm,arm64} revealed these test failures, which
 # are to be triaged.  Isolate tests are skipped on purpose due to the usage of
 # batch mode.
-[ $compiler == dartk && ($arch == simarm || $arch == simarm64) ]
+[ $compiler == dartk && ($arch == simarm || $arch == simarm64 || $arch == simarm64c) ]
 io/file_blocking_lock_test: Crash # Please triage.
 io/file_lock_test: Slow, Pass
 map_insert_remove_oom_test: Skip # Heap limit too low.
 
+[ $compiler == dartk && ($arch == simarm64 || $arch == simarm64c) ]
+io/http_bind_test: Slow, Pass
+
 [ $compiler == dartk && ($hot_reload || $hot_reload_rollback) ]
 io/addlatexhash_test: Skip # Timeout
 io/http_advanced_test: Skip # Timeout
diff --git a/tests/standalone/standalone_vm.status b/tests/standalone/standalone_vm.status
index 51fac12..0be969a 100644
--- a/tests/standalone/standalone_vm.status
+++ b/tests/standalone/standalone_vm.status
@@ -63,7 +63,7 @@
 [ $mode == release && $runtime == vm && $system == windows ]
 io/http_server_close_response_after_error_test: Pass, Timeout # Issue 28370: timeout.
 
-[ $runtime == dart_precompiled && $system == linux && ($arch == simarm || $arch == simarm64 || $arch == x64) ]
+[ $runtime == dart_precompiled && $system == linux && ($arch == simarm || $arch == simarm64 || $arch == simarm64c || $arch == x64) ]
 io/stdout_stderr_non_blocking_test: Pass, Timeout # Issue 35192
 
 [ $runtime == vm && ($arch == arm || $arch == arm64) ]
@@ -73,7 +73,7 @@
 io/file_typed_data_test: Skip # Issue 26109
 io/process_sync_test: Timeout, Pass
 
-[ $runtime == vm && ($arch == simarm || $arch == simarm64) ]
+[ $runtime == vm && ($arch == simarm || $arch == simarm64 || $arch == simarm64c) ]
 io/dart_std_io_pipe_test: Timeout, Pass
 io/http_client_stays_alive_test: Skip # Spawns process in Dart2 mode.
 io/process_sync_test: Timeout, Pass
diff --git a/tests/standalone_2/standalone_2_kernel.status b/tests/standalone_2/standalone_2_kernel.status
index eb9edd6..f5fb8ac 100644
--- a/tests/standalone_2/standalone_2_kernel.status
+++ b/tests/standalone_2/standalone_2_kernel.status
@@ -22,9 +22,6 @@
 [ $arch == ia32 && $builder_tag == optimization_counter_threshold ]
 io/file_lock_test: SkipSlow # Timeout
 
-[ $arch == simarm64 && $compiler == dartk ]
-io/http_bind_test: Slow, Pass
-
 [ $builder_tag == optimization_counter_threshold && $compiler == dartk ]
 map_insert_remove_oom_test: Skip # Heap limit too low.
 
@@ -59,11 +56,14 @@
 # Enabling of dartk for sim{arm,arm64} revealed these test failures, which
 # are to be triaged.  Isolate tests are skipped on purpose due to the usage of
 # batch mode.
-[ $compiler == dartk && ($arch == simarm || $arch == simarm64) ]
+[ $compiler == dartk && ($arch == simarm || $arch == simarm64 || $arch == simarm64c) ]
 io/file_blocking_lock_test: Crash # Please triage.
 io/file_lock_test: Slow, Pass
 map_insert_remove_oom_test: Skip # Heap limit too low.
 
+[ $compiler == dartk && ($arch == simarm64 || $arch == simarm64c) ]
+io/http_bind_test: Slow, Pass
+
 [ $compiler == dartk && ($hot_reload || $hot_reload_rollback) ]
 io/addlatexhash_test: Skip # Timeout
 io/http_advanced_test: Skip # Timeout
diff --git a/tests/standalone_2/standalone_2_vm.status b/tests/standalone_2/standalone_2_vm.status
index 8bc68e8..0727563 100644
--- a/tests/standalone_2/standalone_2_vm.status
+++ b/tests/standalone_2/standalone_2_vm.status
@@ -63,7 +63,7 @@
 [ $mode == release && $runtime == vm && $system == windows ]
 io/http_server_close_response_after_error_test: Pass, Timeout # Issue 28370: timeout.
 
-[ $runtime == dart_precompiled && $system == linux && ($arch == simarm || $arch == simarm64 || $arch == x64) ]
+[ $runtime == dart_precompiled && $system == linux && ($arch == simarm || $arch == simarm64 || $arch == simarm64c || $arch == x64) ]
 io/stdout_stderr_non_blocking_test: Pass, Timeout # Issue 35192
 
 [ $runtime == vm && ($arch == arm || $arch == arm64) ]
@@ -73,7 +73,7 @@
 io/file_typed_data_test: Skip # Issue 26109
 io/process_sync_test: Timeout, Pass
 
-[ $runtime == vm && ($arch == simarm || $arch == simarm64) ]
+[ $runtime == vm && ($arch == simarm || $arch == simarm64 || $arch == simarm64c) ]
 io/dart_std_io_pipe_test: Timeout, Pass
 io/http_client_stays_alive_test: Skip # Spawns process in Dart2 mode.
 io/process_sync_test: Timeout, Pass
diff --git a/third_party/pkg_tested/pkg_tested.status b/third_party/pkg_tested/pkg_tested.status
index bf1542c..b80af3e 100644
--- a/third_party/pkg_tested/pkg_tested.status
+++ b/third_party/pkg_tested/pkg_tested.status
@@ -24,7 +24,7 @@
 pub/test/run/app_can_read_from_stdin_test: Fail # Issue 19448
 pub/test/run/forwards_signal_posix_test: SkipByDesign
 
-[ $runtime == vm && ($arch == simarm || $arch == simarm64 || $arch == simarmv6 || $builder_tag == asan || $mode == debug) ]
+[ $runtime == vm && ($arch == simarm || $arch == simarm64 || $arch == simarm64c || $builder_tag == asan || $mode == debug) ]
 dart_style/test/command_line_test: Skip # The test controller does not take into account that tests take much longer in debug mode or on simulators.
 dart_style/test/formatter_test: Skip # The test controller does not take into account that tests take much longer in debug mode or on simulators.
 
diff --git a/tools/VERSION b/tools/VERSION
index afab02a..e4f0ca7 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 13
 PATCH 0
-PRERELEASE 80
+PRERELEASE 81
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/utils/tests/peg/peg.status b/utils/tests/peg/peg.status
index c53547d..3519ff8 100644
--- a/utils/tests/peg/peg.status
+++ b/utils/tests/peg/peg.status
@@ -11,5 +11,8 @@
 [ $arch == simarm64 ]
 *: Skip
 
+[ $arch == simarm64c ]
+*: Skip
+
 [ $arch == x64 ]
 *: Skip