Version 2.12.0-285.0.dev

Merge commit '950234803ba8a9636db187bfe5c13e2b531151bd' into 'dev'
diff --git a/pkg/analysis_server/benchmark/perf/memory_tests.dart b/pkg/analysis_server/benchmark/perf/memory_tests.dart
index 651763f..5806745 100644
--- a/pkg/analysis_server/benchmark/perf/memory_tests.dart
+++ b/pkg/analysis_server/benchmark/perf/memory_tests.dart
@@ -10,6 +10,7 @@
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_completion.dart';
 import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:test/test.dart';
 
 import '../../test/integration/lsp_server/integration_tests.dart';
@@ -69,8 +70,11 @@
   Future<int> getMemoryUsage() => _test.getMemoryUsage();
 
   @override
-  Future<void> openFile(String filePath, String contents) =>
-      _test.sendAnalysisUpdateContent({filePath: AddContentOverlay(contents)});
+  Future<void> openFile(String filePath, String contents) async {
+    await _test
+        .sendAnalysisUpdateContent({filePath: AddContentOverlay(contents)});
+    await _test.sendAnalysisSetPriorityFiles([filePath]);
+  }
 
   @override
   Future<void> setUp(List<String> roots) async {
@@ -135,6 +139,7 @@
 class LspAnalysisServerBenchmarkTest extends AbstractBenchmarkTest
     with ClientCapabilitiesHelperMixin {
   final _test = LspAnalysisServerMemoryUsageTest();
+  final PrintableLogger _logger = PrintableLogger();
 
   /// Track the file contents so we can easily convert offsets (used in
   /// the interface) to Positions required by LSP without having to keep
@@ -159,7 +164,7 @@
   }
 
   @override
-  void debugStdio() {}
+  void debugStdio() => _logger.debugStdio();
 
   @override
   Future<int> getMemoryUsage() => _test.getMemoryUsage();
@@ -167,11 +172,13 @@
   @override
   Future<void> openFile(String filePath, String contents) {
     _fileContents[filePath] = contents;
-    return _test.openFile(Uri.file(filePath), contents);
+    return _test.openFile(Uri.file(filePath), contents,
+        version: _fileVersion++);
   }
 
   @override
   Future<void> setUp(List<String> roots) async {
+    _test.instrumentationService = InstrumentationLogAdapter(_logger);
     await _test.setUp();
     _test.projectFolderPath = roots.single;
     _test.projectFolderUri = Uri.file(_test.projectFolderPath);
@@ -194,7 +201,10 @@
   }
 
   @override
-  Future<void> shutdown() async => _test.tearDown();
+  Future<void> shutdown() async {
+    _test.tearDown();
+    _logger.shutdown();
+  }
 
   @override
   Future<void> updateFile(String filePath, String contents) {
diff --git a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
index 1165746..0adfd67 100644
--- a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
+++ b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
@@ -121,6 +121,12 @@
   /// A progress reporter for analysis status.
   ProgressReporter analyzingProgressReporter;
 
+  /// The last paths that were set as included analysis roots.
+  Set<String> _lastIncludedRootPaths;
+
+  /// The last paths that were set as excluded analysis roots.
+  Set<String> _lastExcludedRootPaths;
+
   /// Initialize a newly created server to send and receive messages to the
   /// given [channel].
   LspAnalysisServer(
@@ -671,9 +677,8 @@
 
   void _refreshAnalysisRoots() {
     // Always include any temporary analysis roots for open files.
-    final includedPaths = HashSet<String>.of(_explicitAnalysisRoots)
-      ..addAll(_temporaryAnalysisRoots.values)
-      ..toList();
+    final includedPaths = _explicitAnalysisRoots.toSet()
+      ..addAll(_temporaryAnalysisRoots.values);
 
     final excludedPaths = clientConfiguration.analysisExcludedFolders
         .expand((excludePath) => isAbsolute(excludePath)
@@ -683,11 +688,27 @@
             // calling workspace/configuration whenever workspace folders change
             // and caching the config for each one.
             : _explicitAnalysisRoots.map((root) => join(root, excludePath)))
-        .toList();
+        .toSet();
+
+    // If the roots didn't actually change from the last time they were set
+    // (this can happen a lot as temporary roots are collected for open files)
+    // we can avoid doing expensive work like discarding/re-scanning the
+    // declarations.
+    final rootsChanged =
+        includedPaths.length != _lastIncludedRootPaths?.length ||
+            !includedPaths.every(_lastIncludedRootPaths.contains) ||
+            excludedPaths.length != _lastExcludedRootPaths?.length ||
+            !excludedPaths.every(_lastExcludedRootPaths.contains);
+
+    if (!rootsChanged) return;
+
+    _lastIncludedRootPaths = includedPaths;
+    _lastExcludedRootPaths = excludedPaths;
 
     declarationsTracker?.discardContexts();
-    notificationManager.setAnalysisRoots(includedPaths.toList(), excludedPaths);
-    contextManager.setRoots(includedPaths.toList(), excludedPaths);
+    notificationManager.setAnalysisRoots(
+        includedPaths.toList(), excludedPaths.toList());
+    contextManager.setRoots(includedPaths.toList(), excludedPaths.toList());
     addContextsToDeclarationsTracker();
   }
 
diff --git a/pkg/analysis_server/lib/src/services/correction/util.dart b/pkg/analysis_server/lib/src/services/correction/util.dart
index b9a8e93..9914359 100644
--- a/pkg/analysis_server/lib/src/services/correction/util.dart
+++ b/pkg/analysis_server/lib/src/services/correction/util.dart
@@ -24,6 +24,7 @@
     show SourceChange, SourceEdit;
 import 'package:analyzer_plugin/src/utilities/string_utilities.dart';
 import 'package:analyzer_plugin/utilities/range_factory.dart';
+import 'package:meta/meta.dart';
 import 'package:path/path.dart' as pathos;
 
 /// Adds edits to the given [change] that ensure that all the [libraries] are
@@ -813,23 +814,19 @@
   /// used by the generated source, but not imported.
   String getTypeSource(DartType type, Set<Source> librariesToImport,
       {StringBuffer parametersBuffer}) {
-    var sb = StringBuffer();
-    // type parameter
-    if (!_isTypeVisible(type)) {
+    if (type.aliasElement != null) {
+      return _getTypeCodeElementArguments(
+        librariesToImport: librariesToImport,
+        element: type.aliasElement,
+        typeArguments: type.aliasArguments,
+      );
+    }
+
+    if (type is DynamicType) {
       return 'dynamic';
     }
 
-    var element = type.element;
-
-    // Typedef(s) are represented as FunctionTypeAliasElement(s).
-    if (element is GenericFunctionTypeElement &&
-        element.typeParameters.isEmpty &&
-        element.enclosingElement is FunctionTypeAliasElement) {
-      element = element.enclosingElement;
-    }
-
-    // just a Function, not FunctionTypeAliasElement
-    if (type is FunctionType && element is! FunctionTypeAliasElement) {
+    if (type is FunctionType) {
       if (parametersBuffer == null) {
         return 'Function';
       }
@@ -846,68 +843,33 @@
       parametersBuffer.write(')');
       return getTypeSource(type.returnType, librariesToImport);
     }
-    // <Bottom>, Null
-    if (type.isBottom || type.isDartCoreNull) {
-      return 'dynamic';
+
+    if (type is InterfaceType) {
+      return _getTypeCodeElementArguments(
+        librariesToImport: librariesToImport,
+        element: type.element,
+        typeArguments: type.typeArguments,
+      );
     }
-    // prepare element
-    if (element == null) {
-      var source = type.toString();
-      source = source.replaceAll('<dynamic>', '');
-      source = source.replaceAll('<dynamic, dynamic>', '');
-      return source;
+
+    if (type is NeverType) {
+      return 'Never';
     }
-    // check if imported
-    var library = element.library;
-    if (library != null && library != _library) {
-      // no source, if private
-      if (element.isPrivate) {
-        return null;
-      }
-      // ensure import
-      var importElement = _getImportElement(element);
-      if (importElement != null) {
-        if (importElement.prefix != null) {
-          sb.write(importElement.prefix.displayName);
-          sb.write('.');
-        }
+
+    if (type is TypeParameterType) {
+      var element = type.element;
+      if (_isTypeParameterVisible(element)) {
+        return element.name;
       } else {
-        librariesToImport.add(library.source);
+        return 'dynamic';
       }
     }
-    // append simple name
-    var name = element.displayName;
-    sb.write(name);
-    // may be type arguments
-    if (type is ParameterizedType) {
-      var arguments = type.typeArguments;
-      // check if has arguments
-      var hasArguments = false;
-      var allArgumentsVisible = true;
-      for (var argument in arguments) {
-        hasArguments = hasArguments || !argument.isDynamic;
-        allArgumentsVisible = allArgumentsVisible && _isTypeVisible(argument);
-      }
-      // append type arguments
-      if (hasArguments && allArgumentsVisible) {
-        sb.write('<');
-        for (var i = 0; i < arguments.length; i++) {
-          var argument = arguments[i];
-          if (i != 0) {
-            sb.write(', ');
-          }
-          var argumentSrc = getTypeSource(argument, librariesToImport);
-          if (argumentSrc != null) {
-            sb.write(argumentSrc);
-          } else {
-            return null;
-          }
-        }
-        sb.write('>');
-      }
+
+    if (type is VoidType) {
+      return 'void';
     }
-    // done
-    return sb.toString();
+
+    throw UnimplementedError('(${type.runtimeType}) $type');
   }
 
   /// Indents given source left or right.
@@ -1145,6 +1107,58 @@
     return null;
   }
 
+  String _getTypeCodeElementArguments({
+    @required Set<Source> librariesToImport,
+    @required Element element,
+    @required List<DartType> typeArguments,
+  }) {
+    var sb = StringBuffer();
+
+    // check if imported
+    var library = element.library;
+    if (library != null && library != _library) {
+      // no source, if private
+      if (element.isPrivate) {
+        return null;
+      }
+      // ensure import
+      var importElement = _getImportElement(element);
+      if (importElement != null) {
+        if (importElement.prefix != null) {
+          sb.write(importElement.prefix.displayName);
+          sb.write('.');
+        }
+      } else {
+        librariesToImport.add(library.source);
+      }
+    }
+
+    // append simple name
+    var name = element.displayName;
+    sb.write(name);
+
+    // append type arguments
+    if (typeArguments.isNotEmpty) {
+      sb.write('<');
+      for (var i = 0; i < typeArguments.length; i++) {
+        var argument = typeArguments[i];
+        if (i != 0) {
+          sb.write(', ');
+        }
+        var argumentSrc = getTypeSource(argument, librariesToImport);
+        if (argumentSrc != null) {
+          sb.write(argumentSrc);
+        } else {
+          return null;
+        }
+      }
+      sb.write('>');
+    }
+
+    // done
+    return sb.toString();
+  }
+
   /// @return the [InvertedCondition] for the given logical expression.
   _InvertedCondition _invertCondition0(Expression expression) {
     if (expression is BooleanLiteral) {
@@ -1213,16 +1227,12 @@
     return _InvertedCondition._simple(getNodeText(expression));
   }
 
-  /// Checks if [type] is visible in [targetExecutableElement] or
+  /// Checks if [element] is visible in [targetExecutableElement] or
   /// [targetClassElement].
-  bool _isTypeVisible(DartType type) {
-    if (type is TypeParameterType) {
-      var parameterElement = type.element;
-      var parameterClassElement = parameterElement.enclosingElement;
-      return identical(parameterClassElement, targetExecutableElement) ||
-          identical(parameterClassElement, targetClassElement);
-    }
-    return true;
+  bool _isTypeParameterVisible(TypeParameterElement element) {
+    var enclosing = element.enclosingElement;
+    return identical(enclosing, targetExecutableElement) ||
+        identical(enclosing, targetClassElement);
   }
 
   /// Return `true` if [selection] covers [range] and there are any
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
index 4370af4..1201756 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
@@ -762,7 +762,8 @@
     } else if (_returnType == null) {
       variableType = null;
       if (_hasAwait) {
-        returnType = _getTypeCode(typeProvider.futureDynamicType);
+        var futureVoid = typeProvider.futureType2(typeProvider.voidType);
+        returnType = _getTypeCode(futureVoid);
       } else {
         returnType = 'void';
       }
diff --git a/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart b/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart
index c07285d..bd8a64f 100644
--- a/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart
@@ -17,6 +17,7 @@
     with ClientCapabilitiesHelperMixin, LspAnalysisServerTestMixin {
   final List<String> vmArgs = [];
   LspServerClient client;
+  InstrumentationService instrumentationService;
 
   final Map<int, Completer<ResponseMessage>> _completers = {};
 
@@ -79,7 +80,7 @@
     analysisOptionsPath = join(projectFolderPath, 'analysis_options.yaml');
     analysisOptionsUri = Uri.file(analysisOptionsPath);
 
-    client = LspServerClient();
+    client = LspServerClient(instrumentationService);
     await client.start(vmArgs: vmArgs);
     client.serverToClient.listen((message) {
       if (message is ResponseMessage) {
@@ -104,11 +105,14 @@
 }
 
 class LspServerClient {
+  final InstrumentationService instrumentationService;
   Process _process;
   LspByteStreamServerChannel channel;
   final StreamController<Message> _serverToClient =
       StreamController<Message>.broadcast();
 
+  LspServerClient(this.instrumentationService);
+
   Future<int> get exitCode => _process.exitCode;
 
   Stream<Message> get serverToClient => _serverToClient.stream;
@@ -172,8 +176,35 @@
       throw 'Analysis Server wrote to stderr:\n\n$message';
     });
 
-    channel = LspByteStreamServerChannel(
-        _process.stdout, _process.stdin, InstrumentationService.NULL_SERVICE);
+    channel = LspByteStreamServerChannel(_process.stdout, _process.stdin,
+        instrumentationService ?? InstrumentationService.NULL_SERVICE);
     channel.listen(_serverToClient.add);
   }
 }
+
+/// An [InstrumentationLogger] that buffers logs until [debugStdio()] is called.
+class PrintableLogger extends InstrumentationLogger {
+  bool _printLogs = false;
+  final _buffer = StringBuffer();
+
+  void debugStdio() {
+    print(_buffer.toString());
+    _buffer.clear();
+    _printLogs = true;
+  }
+
+  @override
+  void log(String message) {
+    if (_printLogs) {
+      print(message);
+    } else {
+      _buffer.writeln(message);
+    }
+  }
+
+  @override
+  Future<void> shutdown() async {
+    _printLogs = false;
+    _buffer.clear();
+  }
+}
diff --git a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart b/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
index 2396564..71155fe 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
@@ -2334,7 +2334,7 @@
   print(v);
 }
 
-Future res() async {
+Future<dynamic> res() async {
   var v = await getValue();
   return v;
 }
@@ -2431,7 +2431,7 @@
 // end
 }
 
-Future res() async {
+Future<void> res() async {
   int v = await getValue();
   print(v);
 }
@@ -2812,7 +2812,7 @@
 // end
 }
 
-List res(bool b) {
+List<dynamic> res(bool b) {
   if (b) {
     print(true);
     return <int>[];
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_function_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_function_test.dart
index dff3ac4..fd2fea7 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_function_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_function_test.dart
@@ -7,6 +7,7 @@
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../../../../abstract_context.dart';
 import 'fix_processor.dart';
 
 void main() {
@@ -16,21 +17,20 @@
 }
 
 @reflectiveTest
-class CreateFunctionTest extends FixProcessorTest {
+class CreateFunctionTest extends FixProcessorTest
+    with WithNonFunctionTypeAliasesMixin {
   @override
   FixKind get kind => DartFixKind.CREATE_FUNCTION;
 
   Future<void> assert_returnType_bool(String lineWithTest) async {
     await resolveTestCode('''
-main() {
-  bool b = true;
+void f(bool b) {
   $lineWithTest
   print(b);
 }
 ''');
     await assertHasFix('''
-main() {
-  bool b = true;
+void f(bool b) {
   $lineWithTest
   print(b);
 }
@@ -59,7 +59,7 @@
   Future<void> test_duplicateArgumentNames() async {
     await resolveTestCode('''
 class C {
-  int x;
+  int x = 0;
 }
 
 foo(C c1, C c2) {
@@ -68,7 +68,7 @@
 ''');
     await assertHasFix('''
 class C {
-  int x;
+  int x = 0;
 }
 
 foo(C c1, C c2) {
@@ -159,7 +159,7 @@
   Future<void> test_functionType_cascadeSecond() async {
     await resolveTestCode('''
 class A {
-  B ma() => null;
+  B ma() => throw 0;
 }
 class B {
   useFunction(int g(double a, String b)) {}
@@ -172,7 +172,7 @@
 ''');
     await assertHasFix('''
 class A {
-  B ma() => null;
+  B ma() => throw 0;
 }
 class B {
   useFunction(int g(double a, String b)) {}
@@ -193,13 +193,13 @@
 main() {
   useFunction(g: test);
 }
-useFunction({Function g}) {}
+useFunction({Function? g}) {}
 ''');
     await assertHasFix('''
 main() {
   useFunction(g: test);
 }
-useFunction({Function g}) {}
+useFunction({Function? g}) {}
 
 test() {
 }
@@ -247,13 +247,13 @@
 main() {
   useFunction(g: test);
 }
-useFunction({int g(double a, String b)}) {}
+useFunction({int g(double a, String b)?}) {}
 ''');
     await assertHasFix('''
 main() {
   useFunction(g: test);
 }
-useFunction({int g(double a, String b)}) {}
+useFunction({int g(double a, String b)?}) {}
 
 int test(double a, String b) {
 }
@@ -291,7 +291,7 @@
 
   Future<void> test_functionType_notFunctionType() async {
     await resolveTestCode('''
-main(A a) {
+void f(A a) {
   useFunction(a.test);
 }
 typedef A();
@@ -303,7 +303,7 @@
   Future<void> test_generic_type() async {
     await resolveTestCode('''
 class A {
-  List<int> items;
+  List<int> items = [];
   main() {
     process(items);
   }
@@ -311,7 +311,7 @@
 ''');
     await assertHasFix('''
 class A {
-  List<int> items;
+  List<int> items = [];
   main() {
     process(items);
   }
@@ -330,7 +330,7 @@
   Future<void> test_generic_typeParameter() async {
     await resolveTestCode('''
 class A<T> {
-  Map<int, T> items;
+  Map<int, T> items = {};
   main() {
     process(items);
   }
@@ -338,7 +338,7 @@
 ''');
     await assertHasFix('''
 class A<T> {
-  Map<int, T> items;
+  Map<int, T> items = {};
   main() {
     process(items);
   }
@@ -471,14 +471,14 @@
   Future<void> test_returnType_fromAssignment_plusEq() async {
     await resolveTestCode('''
 main() {
-  int v;
+  num v = 0;
   v += myUndefinedFunction();
   print(v);
 }
 ''');
     await assertHasFix('''
 main() {
-  int v;
+  num v = 0;
   v += myUndefinedFunction();
   print(v);
 }
@@ -556,6 +556,30 @@
 ''');
   }
 
+  Future<void> test_returnType_typeAlias_function() async {
+    await resolveTestCode('''
+typedef A<T> = void Function(T a);
+
+void f(A<int> Function() a) {}
+
+void g() {
+  f(test);
+}
+''');
+    await assertHasFix('''
+typedef A<T> = void Function(T a);
+
+void f(A<int> Function() a) {}
+
+void g() {
+  f(test);
+}
+
+A<int> test() {
+}
+''');
+  }
+
   Future<void> test_returnType_void() async {
     await resolveTestCode('''
 main() {
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 51bfd9e..278145e 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -7,6 +7,7 @@
   Use `CompilationUnitElement.typeAliases` instead.
 * Added `AnalysisContext.sdkRoot`.
 * Removed `NullSafetyUnderstandingFlag`.
+* Removed `functionTypeAliasElement` from `TypeSystem.instantiateToBounds2`.
 
 ## 0.41.1
 * Updated `PackageBuildWorkspace` that supports `package:build` to stop
diff --git a/pkg/analyzer/lib/dart/element/type_provider.dart b/pkg/analyzer/lib/dart/element/type_provider.dart
index f263c27..17b4101 100644
--- a/pkg/analyzer/lib/dart/element/type_provider.dart
+++ b/pkg/analyzer/lib/dart/element/type_provider.dart
@@ -10,159 +10,157 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class TypeProvider {
-  /// Return the element representing the built-in class 'bool'.
+  /// Return the element representing the built-in class `bool`.
   ClassElement get boolElement;
 
-  /// Return the type representing the built-in type 'bool'.
+  /// Return the type representing the built-in type `bool`.
   InterfaceType get boolType;
 
-  /// Return the type representing the type 'bottom'.
+  /// Return the type representing the type `bottom`.
   DartType get bottomType;
 
-  /// Return the type representing the built-in type 'Deprecated'.
+  /// Return the type representing the built-in type `Deprecated`.
   InterfaceType get deprecatedType;
 
-  /// Return the element representing the built-in class 'double'.
+  /// Return the element representing the built-in class `double`.
   ClassElement get doubleElement;
 
-  /// Return the type representing the built-in type 'double'.
+  /// Return the type representing the built-in type `double`.
   InterfaceType get doubleType;
 
-  /// Return the type representing the built-in type 'dynamic'.
+  /// Return the type representing the built-in type `dynamic`.
   DartType get dynamicType;
 
-  /// Return the type representing the built-in type 'Function'.
+  /// Return the type representing the built-in type `Function`.
   InterfaceType get functionType;
 
-  /// Return the type representing 'Future<dynamic>'.
+  /// Return the type representing `Future<dynamic>`.
   InterfaceType get futureDynamicType;
 
-  /// Return the element representing the built-in class 'Future'.
+  /// Return the element representing the built-in class `Future`.
   ClassElement get futureElement;
 
-  /// Return the type representing 'Future<Null>'.
+  /// Return the type representing `Future<Null>`.
   InterfaceType get futureNullType;
 
-  /// Return the element representing the built-in class 'FutureOr'.
+  /// Return the element representing the built-in class `FutureOr`.
   ClassElement get futureOrElement;
 
-  /// Return the type representing 'FutureOr<Null>'.
+  /// Return the type representing `FutureOr<Null>`.
   InterfaceType get futureOrNullType;
 
-  /// Return the element representing the built-in class 'int'.
+  /// Return the element representing the built-in class `int`.
   ClassElement get intElement;
 
-  /// Return the type representing the built-in type 'int'.
+  /// Return the type representing the built-in type `int`.
   InterfaceType get intType;
 
-  /// Return the type representing the type 'Iterable<dynamic>'.
+  /// Return the type representing the type `Iterable<dynamic>`.
   InterfaceType get iterableDynamicType;
 
-  /// Return the element representing the built-in class 'Iterable'.
+  /// Return the element representing the built-in class `Iterable`.
   ClassElement get iterableElement;
 
-  /// Return the type representing the type 'Iterable<Object>'.
+  /// Return the type representing the type `Iterable<Object>`.
   InterfaceType get iterableObjectType;
 
-  /// Return the element representing the built-in class 'List'.
+  /// Return the element representing the built-in class `List`.
   ClassElement get listElement;
 
-  /// Return the element representing the built-in class 'Map'.
+  /// Return the element representing the built-in class `Map`.
   ClassElement get mapElement;
 
-  /// Return the type representing 'Map<Object, Object>'.
+  /// Return the type representing `Map<Object, Object>`.
   InterfaceType get mapObjectObjectType;
 
-  /// Return the type representing the built-in type 'Never'.
+  /// Return the type representing the built-in type `Never`.
   DartType get neverType;
 
   /// Return a list containing all of the types that cannot be either extended
   /// or implemented.
   Set<ClassElement> get nonSubtypableClasses;
 
-  /// Return the element representing the built-in class 'null'.
+  /// Return the element representing the built-in class `Null`.
   ClassElement get nullElement;
 
-  /// Return the type representing the built-in type 'Null'.
+  /// Return the type representing the built-in type `Null`.
   InterfaceType get nullType;
 
-  /// Return the element representing the built-in class 'num'.
+  /// Return the element representing the built-in class `num`.
   ClassElement get numElement;
 
-  /// Return the type representing the built-in type 'num'.
+  /// Return the type representing the built-in type `num`.
   InterfaceType get numType;
 
-  /// Return the type representing the built-in type 'Object'.
+  /// Return the type representing the built-in type `Object`.
   InterfaceType get objectType;
 
-  /// Return the element representing the built-in class 'Set'.
+  /// Return the element representing the built-in class `Set`.
   ClassElement get setElement;
 
-  /// Return the type representing the built-in type 'StackTrace'.
+  /// Return the type representing the built-in type `StackTrace`.
   InterfaceType get stackTraceType;
 
-  /// Return the type representing 'Stream<dynamic>'.
+  /// Return the type representing `Stream<dynamic>`.
   InterfaceType get streamDynamicType;
 
-  /// Return the element representing the built-in class 'Stream'.
+  /// Return the element representing the built-in class `Stream`.
   ClassElement get streamElement;
 
-  /// Return the element representing the built-in class 'String'.
+  /// Return the element representing the built-in class `String`.
   ClassElement get stringElement;
 
-  /// Return the type representing the built-in type 'String'.
+  /// Return the type representing the built-in type `String`.
   InterfaceType get stringType;
 
-  /// Return the element representing the built-in class 'Symbol'.
+  /// Return the element representing the built-in class `Symbol`.
   ClassElement get symbolElement;
 
-  /// Return the type representing the built-in type 'Symbol'.
+  /// Return the type representing the built-in type `Symbol`.
   InterfaceType get symbolType;
 
-  /// Return the type representing the built-in type 'Type'.
+  /// Return the type representing the built-in type `Type`.
   InterfaceType get typeType;
 
   /// Return the type representing the built-in type `void`.
   VoidType get voidType;
 
-  /// Return the instantiation of the built-in class 'FutureOr' with the
+  /// Return the instantiation of the built-in class `FutureOr` with the
   /// given [valueType]. The type has the nullability suffix of this provider.
   InterfaceType futureOrType2(DartType valueType);
 
-  /// Return the instantiation of the built-in class 'Future' with the
+  /// Return the instantiation of the built-in class `Future` with the
   /// given [valueType]. The type has the nullability suffix of this provider.
   InterfaceType futureType2(DartType valueType);
 
-  /// Return 'true' if [id] is the name of a getter on
-  /// the Object type.
+  /// Return 'true' if [id] is the name of a getter on the Object type.
   bool isObjectGetter(String id);
 
-  /// Return 'true' if [id] is the name of a method or getter on
-  /// the Object type.
+  /// Return 'true' if [id] is the name of a method or getter on the Object
+  /// type.
   bool isObjectMember(String id);
 
-  /// Return 'true' if [id] is the name of a method on
-  /// the Object type.
+  /// Return 'true' if [id] is the name of a method on the Object type.
   bool isObjectMethod(String id);
 
-  /// Return the instantiation of the built-in class 'Iterable' with the
+  /// Return the instantiation of the built-in class `Iterable` with the
   /// given [elementType]. The type has the nullability suffix of this provider.
   InterfaceType iterableType2(DartType elementType);
 
-  /// Return the instantiation of the built-in class 'List' with the
+  /// Return the instantiation of the built-in class `List` with the
   /// given [elementType]. The type has the nullability suffix of this provider.
   InterfaceType listType2(DartType elementType);
 
-  /// Return the instantiation of the built-in class 'List' with the
+  /// Return the instantiation of the built-in class `List` with the
   /// given [keyType] and [valueType]. The type has the nullability suffix of
   /// this provider.
   InterfaceType mapType2(DartType keyType, DartType valueType);
 
-  /// Return the instantiation of the built-in class 'Set' with the
+  /// Return the instantiation of the built-in class `Set` with the
   /// given [elementType]. The type has the nullability suffix of this provider.
   InterfaceType setType2(DartType elementType);
 
-  /// Return the instantiation of the built-in class 'Stream' with the
+  /// Return the instantiation of the built-in class `Stream` with the
   /// given [elementType]. The type has the nullability suffix of this provider.
   InterfaceType streamType2(DartType elementType);
 }
diff --git a/pkg/analyzer/lib/dart/element/type_system.dart b/pkg/analyzer/lib/dart/element/type_system.dart
index 8e3d4db..e8c7158 100644
--- a/pkg/analyzer/lib/dart/element/type_system.dart
+++ b/pkg/analyzer/lib/dart/element/type_system.dart
@@ -42,8 +42,6 @@
   /// be provided.
   DartType instantiateToBounds2({
     ClassElement? classElement,
-    @Deprecated("Use 'typeAliasElement' instead")
-        FunctionTypeAliasElement? functionTypeAliasElement,
     TypeAliasElement? typeAliasElement,
     required NullabilitySuffix nullabilitySuffix,
   });
diff --git a/pkg/analyzer/lib/src/dart/element/type_system.dart b/pkg/analyzer/lib/src/dart/element/type_system.dart
index beb67a5..b79502d 100644
--- a/pkg/analyzer/lib/src/dart/element/type_system.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_system.dart
@@ -527,12 +527,9 @@
   @override
   DartType instantiateToBounds2({
     ClassElement? classElement,
-    @Deprecated("Use 'typeAliasElement' instead")
-        FunctionTypeAliasElement? functionTypeAliasElement,
     TypeAliasElement? typeAliasElement,
     required NullabilitySuffix nullabilitySuffix,
   }) {
-    typeAliasElement ??= functionTypeAliasElement;
     if (classElement != null) {
       var typeParameters = classElement.typeParameters;
       var typeArguments = _defaultTypeArguments(typeParameters);
diff --git a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
index 58e5bf1..719f8d7 100644
--- a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
@@ -125,12 +125,6 @@
       if (element is ClassElement) {
         _resolveReceiverTypeLiteral(node, element, nameNode, name);
         return;
-      } else if (element is FunctionTypeAliasElement) {
-        _reportUndefinedMethod(
-          node,
-          name,
-          _resolver.typeProvider.typeType.element,
-        );
       } else if (element is TypeAliasElement) {
         var aliasedType = element.aliasedType;
         if (aliasedType is InterfaceType) {
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 148ef98..b1db9af 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -1718,7 +1718,6 @@
           CompileTimeErrorCode.ASSIGNMENT_TO_METHOD, expression);
     } else if (element is ClassElement ||
         element is DynamicElementImpl ||
-        element is FunctionTypeAliasElement ||
         element is TypeParameterElement) {
       _errorReporter.reportErrorForNode(
           CompileTimeErrorCode.ASSIGNMENT_TO_TYPE, expression);
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_method_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_method_test.dart
index 8767c86..0114920 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_method_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_method_test.dart
@@ -14,7 +14,8 @@
 }
 
 @reflectiveTest
-class UndefinedMethodTest extends PubPackageResolutionTest {
+class UndefinedMethodTest extends PubPackageResolutionTest
+    with WithNonFunctionTypeAliasesMixin {
   test_constructor_defined() async {
     await assertNoErrorsInCode(r'''
 class C {
@@ -97,9 +98,10 @@
 
   test_leastUpperBoundWithNull() async {
     await assertErrorsInCode('''
+// @dart = 2.9
 f(bool b, int i) => (b ? null : i).foo();
 ''', [
-      error(CompileTimeErrorCode.UNDEFINED_METHOD, 35, 3),
+      error(CompileTimeErrorCode.UNDEFINED_METHOD, 50, 3),
     ]);
   }
 
@@ -159,12 +161,13 @@
 
   test_method_undefined_onNull() async {
     await assertErrorsInCode(r'''
+// @dart = 2.9
 Null f(int x) => null;
 main() {
   f(42).abs();
 }
 ''', [
-      error(CompileTimeErrorCode.UNDEFINED_METHOD, 40, 3),
+      error(CompileTimeErrorCode.UNDEFINED_METHOD, 55, 3),
     ]);
   }
 
@@ -198,6 +201,30 @@
     ]);
   }
 
+  test_typeAlias_functionType() async {
+    await assertErrorsInCode(r'''
+typedef A = void Function();
+
+void f() {
+  A.foo();
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_METHOD, 45, 3),
+    ]);
+  }
+
+  test_typeAlias_interfaceType() async {
+    await assertErrorsInCode(r'''
+typedef A = List<int>;
+
+void f() {
+  A.foo();
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_METHOD, 39, 3),
+    ]);
+  }
+
   test_withExtension() async {
     await assertErrorsInCode(r'''
 class C {}
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
index 993cf7e..eb831fc 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
@@ -24,6 +24,7 @@
 import 'package:analyzer_plugin/utilities/change_builder/change_workspace.dart';
 import 'package:analyzer_plugin/utilities/range_factory.dart';
 import 'package:dart_style/dart_style.dart';
+import 'package:meta/meta.dart';
 
 /// A [ChangeBuilder] used to build changes in Dart files.
 @Deprecated('Use ChangeBuilder')
@@ -1178,22 +1179,19 @@
       }
       return false;
     }
-    // The type `void` does not have an element.
-    if (type is VoidType) {
-      write('void');
+
+    var aliasElement = type.aliasElement;
+    if (aliasElement != null) {
+      _writeTypeElementArguments(
+        element: aliasElement,
+        typeArguments: type.aliasArguments,
+        methodBeingCopied: methodBeingCopied,
+      );
+      _writeTypeNullability(type);
       return true;
     }
 
-    var element = type.element;
-    // Typedef(s) are represented as GenericFunctionTypeElement(s).
-    if (element is GenericFunctionTypeElement &&
-        element.typeParameters.isEmpty &&
-        element.enclosingElement is FunctionTypeAliasElement) {
-      element = element.enclosingElement;
-    }
-
-    // Just a Function, not FunctionTypeAliasElement.
-    if (type is FunctionType && element is! FunctionTypeAliasElement) {
+    if (type is FunctionType) {
       if (_writeType(type.returnType, methodBeingCopied: methodBeingCopied)) {
         write(' ');
       }
@@ -1204,6 +1202,41 @@
       return true;
     }
 
+    if (type is InterfaceType) {
+      _writeTypeElementArguments(
+        element: type.element,
+        typeArguments: type.typeArguments,
+        methodBeingCopied: methodBeingCopied,
+      );
+      _writeTypeNullability(type);
+      return true;
+    }
+
+    if (type is NeverType) {
+      write('Never');
+      _writeTypeNullability(type);
+      return true;
+    }
+
+    if (type is TypeParameterType) {
+      write(type.element.name);
+      _writeTypeNullability(type);
+      return true;
+    }
+
+    if (type is VoidType) {
+      write('void');
+      return true;
+    }
+
+    throw UnimplementedError('(${type.runtimeType}) $type');
+  }
+
+  void _writeTypeElementArguments({
+    @required Element element,
+    @required List<DartType> typeArguments,
+    @required ExecutableElement methodBeingCopied,
+  }) {
     // Ensure that the element is imported.
     _writeLibraryReference(element);
 
@@ -1212,12 +1245,11 @@
     write(name);
 
     // Write type arguments.
-    if (type is ParameterizedType) {
-      var arguments = type.typeArguments;
+    if (typeArguments.isNotEmpty) {
       // Check if has arguments.
       var hasArguments = false;
       var allArgumentsVisible = true;
-      for (var argument in arguments) {
+      for (var argument in typeArguments) {
         hasArguments = hasArguments || !argument.isDynamic;
         allArgumentsVisible = allArgumentsVisible &&
             _getVisibleType(argument, methodBeingCopied: methodBeingCopied) !=
@@ -1226,8 +1258,8 @@
       // Write type arguments only if they are useful.
       if (hasArguments && allArgumentsVisible) {
         write('<');
-        for (var i = 0; i < arguments.length; i++) {
-          var argument = arguments[i];
+        for (var i = 0; i < typeArguments.length; i++) {
+          var argument = typeArguments[i];
           if (i != 0) {
             write(', ');
           }
@@ -1237,12 +1269,12 @@
         write('>');
       }
     }
+  }
 
+  void _writeTypeNullability(DartType type) {
     if (type.nullabilitySuffix == NullabilitySuffix.question) {
       write('?');
     }
-
-    return true;
   }
 }
 
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
index 6d37cfe..430be10 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
@@ -106,6 +106,14 @@
     var edit = getEdit(builder);
     expect(edit.replacement, equalsIgnoringWhitespace('required a'));
   }
+
+  Future<void> test_writeType_Never_none() async {
+    await _assertWriteType('Never');
+  }
+
+  Future<void> test_writeType_Never_question() async {
+    await _assertWriteType('Never?');
+  }
 }
 
 class DartEditBuilderImplTest extends AbstractContextTest
diff --git a/pkg/nnbd_migration/lib/src/variables.dart b/pkg/nnbd_migration/lib/src/variables.dart
index 84e0ea0..0362d62 100644
--- a/pkg/nnbd_migration/lib/src/variables.dart
+++ b/pkg/nnbd_migration/lib/src/variables.dart
@@ -395,7 +395,7 @@
       // case) `Function(T)`. Without this we would get `Function<T>(T)` which
       // is incorrect. This is a known issue with `.type` on typedefs in the
       // analyzer.
-      element = (element as FunctionTypeAliasElement).aliasedElement;
+      element = (element as TypeAliasElement).aliasedElement;
     }
 
     var target = NullabilityNodeTarget.element(element, _getLineInfo);
diff --git a/pkg/vm_service/CHANGELOG.md b/pkg/vm_service/CHANGELOG.md
index f6a97c1..322f952 100644
--- a/pkg/vm_service/CHANGELOG.md
+++ b/pkg/vm_service/CHANGELOG.md
@@ -1,11 +1,15 @@
 # Changelog
 
-## 6.1.0-nullsafety.0
+## 6.1.0
 - Added `identityHashCode` property to `HeapSnapshotObject`, which can be used to compare
   objects across heap snapshots.
 - Added `successors` iterable to `HeapSnapshotObject`, which provides a convenient way to
   access children of a given object.
 - Added `klass` getter to `HeapSnapshotObject`.
+- Fixed issue where `null` could be returned instead of `InstanceRef` of type `Null`.
+
+## 6.0.1
+- Stable null-safe release.
 
 ## 6.0.1-nullsafety.1
 - Fix issue where some `Instance` properties were not being populated correctly.
@@ -16,6 +20,7 @@
 ## 6.0.0-nullsafety.4
 - Fixed issue where response parsing could fail for `SourceReportRange.coverage`
   if no coverage information was provided.
+
 ## 6.0.0-nullsafety.3
 - Fixed issue where `Response.type` and classes which override `Response.type` were
   returning the name of the `package:vm_service` reference object (e.g., InstanceRef) instead of
diff --git a/pkg/vm_service/lib/src/vm_service.dart b/pkg/vm_service/lib/src/vm_service.dart
index fa49390..cc0643e 100644
--- a/pkg/vm_service/lib/src/vm_service.dart
+++ b/pkg/vm_service/lib/src/vm_service.dart
@@ -55,7 +55,8 @@
       } else {
         return null;
       }
-    } else if (_isNullInstance(json) && (!expectedTypes.contains(type))) {
+    } else if (_isNullInstance(json) &&
+        (!expectedTypes.contains('InstanceRef'))) {
       // Replace null instances with null when we don't expect an instance to
       // be returned.
       return null;
diff --git a/pkg/vm_service/pubspec.yaml b/pkg/vm_service/pubspec.yaml
index 3e87a37..7760e11 100644
--- a/pkg/vm_service/pubspec.yaml
+++ b/pkg/vm_service/pubspec.yaml
@@ -3,7 +3,7 @@
   A library to communicate with a service implementing the Dart VM
   service protocol.
 
-version: 6.1.0-nullsafety.0
+version: 6.1.0-dev
 
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/vm_service
 
@@ -13,10 +13,10 @@
 dependencies:
 
 dev_dependencies:
-  async: ^2.5.0-nullsafety.3
+  async: ^2.5.0
   markdown: ^4.0.0-nullsafety.0
   mockito: ^5.0.0-nullsafety.1
-  path: ^1.8.0-nullsafety.3
+  path: ^1.8.0
   pedantic: ^1.10.0-nullsafety.3
   pub_semver: ^2.0.0-nullsafety.0
   test: ^1.16.0-nullsafety.13
diff --git a/pkg/vm_service/test/regress_44842_test.dart b/pkg/vm_service/test/regress_44842_test.dart
new file mode 100644
index 0000000..8a794b4
--- /dev/null
+++ b/pkg/vm_service/test/regress_44842_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:vm_service/vm_service.dart';
+import 'package:test/test.dart';
+
+const Map<String, dynamic> kNullInstance = {
+  'type': '@Instance',
+  'id': 'instance/123',
+  'kind': 'Null',
+  'class': {
+    'type': '@Class',
+    'id': 'object/0',
+    'name': 'Null',
+  }
+};
+
+void main() {
+  test('Ensure createServiceObject handles Null @Instances properly', () {
+    expect(createServiceObject(kNullInstance, ['InstanceRef']), isNotNull);
+    expect(createServiceObject(kNullInstance, ['ClassRef']), isNull);
+  });
+}
diff --git a/pkg/vm_service/tool/dart/generate_dart.dart b/pkg/vm_service/tool/dart/generate_dart.dart
index 81b2970..3f4f20c 100644
--- a/pkg/vm_service/tool/dart/generate_dart.dart
+++ b/pkg/vm_service/tool/dart/generate_dart.dart
@@ -535,7 +535,7 @@
       } else {
         return null;
       }
-    } else if (_isNullInstance(json) && (!expectedTypes.contains(type))) {
+    } else if (_isNullInstance(json) && (!expectedTypes.contains('InstanceRef'))) {
       // Replace null instances with null when we don't expect an instance to
       // be returned.
       return null;
diff --git a/runtime/lib/vmservice.cc b/runtime/lib/vmservice.cc
index c42fa15..44d6148 100644
--- a/runtime/lib/vmservice.cc
+++ b/runtime/lib/vmservice.cc
@@ -27,15 +27,23 @@
  public:
   explicit RegisterRunningIsolatesVisitor(Thread* thread)
       : IsolateVisitor(),
+        zone_(thread->zone()),
         register_function_(Function::Handle(thread->zone())),
-        service_isolate_(thread->isolate()) {
-  }
+        service_isolate_(thread->isolate()) {}
 
   virtual void VisitIsolate(Isolate* isolate) {
-    ServiceIsolate::RegisterRunningIsolate(isolate);
+    isolate_ports_.Add(isolate->main_port());
+    isolate_names_.Add(&String::Handle(zone_, String::New(isolate->name())));
+  }
+
+  void RegisterIsolates() {
+    ServiceIsolate::RegisterRunningIsolates(isolate_ports_, isolate_names_);
   }
 
  private:
+  Zone* zone_;
+  GrowableArray<Dart_Port> isolate_ports_;
+  GrowableArray<const String*> isolate_names_;
   Function& register_function_;
   Isolate* service_isolate_;
 };
@@ -90,6 +98,7 @@
     OS::PrintErr("vm-service: Registering running isolates.\n");
   }
   Isolate::VisitIsolates(&register_isolates);
+  register_isolates.RegisterIsolates();
 #endif
   return Object::null();
 }
diff --git a/runtime/observatory/tests/service/get_version_rpc_test.dart b/runtime/observatory/tests/service/get_version_rpc_test.dart
index 5e1a8c9..9596513 100644
--- a/runtime/observatory/tests/service/get_version_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_version_rpc_test.dart
@@ -12,7 +12,7 @@
     final result = await vm.invokeRpcNoUpgrade('getVersion', {});
     expect(result['type'], 'Version');
     expect(result['major'], 3);
-    expect(result['minor'], 42);
+    expect(result['minor'], 43);
     expect(result['_privateMajor'], 0);
     expect(result['_privateMinor'], 0);
   },
diff --git a/runtime/observatory_2/tests/service_2/get_version_rpc_test.dart b/runtime/observatory_2/tests/service_2/get_version_rpc_test.dart
index 5160f96..9e2bc43 100644
--- a/runtime/observatory_2/tests/service_2/get_version_rpc_test.dart
+++ b/runtime/observatory_2/tests/service_2/get_version_rpc_test.dart
@@ -12,7 +12,7 @@
     var result = await vm.invokeRpcNoUpgrade('getVersion', {});
     expect(result['type'], equals('Version'));
     expect(result['major'], equals(3));
-    expect(result['minor'], equals(42));
+    expect(result['minor'], equals(43));
     expect(result['_privateMajor'], equals(0));
     expect(result['_privateMinor'], equals(0));
   },
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index 0390269..bd3b5d4 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -38,30 +38,6 @@
   virtual void AddFrame(const Object& code, const Smi& offset) = 0;
 };
 
-class RegularStackTraceBuilder : public StackTraceBuilder {
- public:
-  explicit RegularStackTraceBuilder(Zone* zone)
-      : code_list_(
-            GrowableObjectArray::Handle(zone, GrowableObjectArray::New())),
-        pc_offset_list_(
-            GrowableObjectArray::Handle(zone, GrowableObjectArray::New())) {}
-  ~RegularStackTraceBuilder() {}
-
-  const GrowableObjectArray& code_list() const { return code_list_; }
-  const GrowableObjectArray& pc_offset_list() const { return pc_offset_list_; }
-
-  virtual void AddFrame(const Object& code, const Smi& offset) {
-    code_list_.Add(code);
-    pc_offset_list_.Add(offset);
-  }
-
- private:
-  const GrowableObjectArray& code_list_;
-  const GrowableObjectArray& pc_offset_list_;
-
-  DISALLOW_COPY_AND_ASSIGN(RegularStackTraceBuilder);
-};
-
 class PreallocatedStackTraceBuilder : public StackTraceBuilder {
  public:
   explicit PreallocatedStackTraceBuilder(const Instance& stacktrace)
diff --git a/runtime/vm/service.h b/runtime/vm/service.h
index f66a951..00a3f32 100644
--- a/runtime/vm/service.h
+++ b/runtime/vm/service.h
@@ -15,7 +15,7 @@
 namespace dart {
 
 #define SERVICE_PROTOCOL_MAJOR_VERSION 3
-#define SERVICE_PROTOCOL_MINOR_VERSION 42
+#define SERVICE_PROTOCOL_MINOR_VERSION 43
 
 class Array;
 class EmbedderServiceHandler;
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index 20deaed..39e71d2 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -1,8 +1,8 @@
-# Dart VM Service Protocol 3.42
+# Dart VM Service Protocol 3.43
 
 > Please post feedback to the [observatory-discuss group][discuss-list]
 
-This document describes of _version 3.42_ of the Dart VM Service Protocol. This
+This document describes of _version 3.43_ of the Dart VM Service Protocol. This
 protocol is used to communicate with a running Dart Virtual Machine.
 
 To use the Service Protocol, start the VM with the *--observe* flag.
@@ -3948,5 +3948,6 @@
 3.40 | Added `IsolateFlag` object and `isolateFlags` property to `Isolate`.
 3.41 | Added `PortList` object, `ReceivePort` `InstanceKind`, and `getPorts` RPC.
 3.42 | Added `limit` optional parameter to `getStack` RPC.
+3.43 | Updated heap snapshot format to include identity hash codes.
 
 [discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/runtime/vm/service_isolate.cc b/runtime/vm/service_isolate.cc
index e01ccd4..07e58ba 100644
--- a/runtime/vm/service_isolate.cc
+++ b/runtime/vm/service_isolate.cc
@@ -583,42 +583,49 @@
   ServiceIsolate::SetServicePort(port);
 }
 
-void ServiceIsolate::RegisterRunningIsolate(Isolate* isolate) {
-  ASSERT(ServiceIsolate::IsServiceIsolate(Isolate::Current()));
+void ServiceIsolate::RegisterRunningIsolates(
+    const GrowableArray<Dart_Port>& isolate_ports,
+    const GrowableArray<const String*>& isolate_names) {
+  auto thread = Thread::Current();
+  auto zone = thread->zone();
 
-  // Get library.
+  ASSERT(ServiceIsolate::IsServiceIsolate(thread->isolate()));
+
+  // Obtain "_registerIsolate" function to call.
   const String& library_url = Symbols::DartVMService();
   ASSERT(!library_url.IsNull());
-  // TODO(bkonyi): hoist Thread::Current()
   const Library& library =
-      Library::Handle(Library::LookupLibrary(Thread::Current(), library_url));
+      Library::Handle(zone, Library::LookupLibrary(thread, library_url));
   ASSERT(!library.IsNull());
-  // Get function.
-  const String& function_name = String::Handle(String::New("_registerIsolate"));
+  const String& function_name =
+      String::Handle(zone, String::New("_registerIsolate"));
   ASSERT(!function_name.IsNull());
   const Function& register_function_ =
-      Function::Handle(library.LookupFunctionAllowPrivate(function_name));
+      Function::Handle(zone, library.LookupFunctionAllowPrivate(function_name));
   ASSERT(!register_function_.IsNull());
 
-  // Setup arguments for call.
-  Dart_Port port_id = isolate->main_port();
-  const Integer& port_int = Integer::Handle(Integer::New(port_id));
-  ASSERT(!port_int.IsNull());
-  const SendPort& send_port = SendPort::Handle(SendPort::New(port_id));
-  const String& name = String::Handle(String::New(isolate->name()));
-  ASSERT(!name.IsNull());
-  const Array& args = Array::Handle(Array::New(3));
-  ASSERT(!args.IsNull());
-  args.SetAt(0, port_int);
-  args.SetAt(1, send_port);
-  args.SetAt(2, name);
-  const Object& r =
-      Object::Handle(DartEntry::InvokeFunction(register_function_, args));
-  if (FLAG_trace_service) {
-    OS::PrintErr("vm-service: Isolate %s %" Pd64 " registered.\n",
-                 name.ToCString(), port_id);
+  Integer& port_int = Integer::Handle(zone);
+  SendPort& send_port = SendPort::Handle(zone);
+  Array& args = Array::Handle(zone, Array::New(3));
+  Object& result = Object::Handle(zone);
+
+  ASSERT(isolate_ports.length() == isolate_names.length());
+  for (intptr_t i = 0; i < isolate_ports.length(); ++i) {
+    const Dart_Port port_id = isolate_ports[i];
+    const String& name = *isolate_names[i];
+
+    port_int = Integer::New(port_id);
+    send_port = SendPort::New(port_id);
+    args.SetAt(0, port_int);
+    args.SetAt(1, send_port);
+    args.SetAt(2, name);
+    result = DartEntry::InvokeFunction(register_function_, args);
+    if (FLAG_trace_service) {
+      OS::PrintErr("vm-service: Isolate %s %" Pd64 " registered.\n",
+                   name.ToCString(), port_id);
+    }
+    ASSERT(!result.IsError());
   }
-  ASSERT(!r.IsError());
 }
 
 void ServiceIsolate::VisitObjectPointers(ObjectPointerVisitor* visitor) {}
diff --git a/runtime/vm/service_isolate.h b/runtime/vm/service_isolate.h
index 5411bb9..0fc018a 100644
--- a/runtime/vm/service_isolate.h
+++ b/runtime/vm/service_isolate.h
@@ -50,7 +50,9 @@
 
   static void BootVmServiceLibrary();
 
-  static void RegisterRunningIsolate(Isolate* isolate);
+  static void RegisterRunningIsolates(
+      const GrowableArray<Dart_Port>& isolate_ports,
+      const GrowableArray<const String*>& isolate_names);
 
   static void RequestServerInfo(const SendPort& sp);
   static void ControlWebServer(const SendPort& sp,
diff --git a/sdk/lib/io/file.dart b/sdk/lib/io/file.dart
index 14d68bb..07c3aeb 100644
--- a/sdk/lib/io/file.dart
+++ b/sdk/lib/io/file.dart
@@ -291,7 +291,7 @@
   /// with a [File] for the renamed file.
   ///
   /// If [newPath] is a relative path, it is resolved against
-  /// the current working directory ([Directory.cwd]).
+  /// the current working directory ([Directory.current]).
   /// This means that simply changing the name of a file,
   /// but keeping it the original directory,
   /// requires creating a new complete path with the new name
@@ -306,7 +306,7 @@
   /// ```
   /// On some platforms, a rename operation cannot move a file between
   /// different file systems. If that is the case, instead [copy] the
-  /// file to the new location and then [remove] the original.
+  /// file to the new location and then remove the original.
   ///
   /// If [newPath] identifies an existing file, that file is
   /// removed first. If [newPath] identifies an existing directory, the
@@ -318,7 +318,7 @@
   /// Returns a [File] for the renamed file.
   ///
   /// If [newPath] is a relative path, it is resolved against
-  /// the current working directory ([Directory.cwd]).
+  /// the current working directory ([Directory.current]).
   /// This means that simply changing the name of a file,
   /// but keeping it the original directory,
   /// requires creating a new complete path with the new name
@@ -333,7 +333,7 @@
   /// ```
   /// On some platforms, a rename operation cannot move a file between
   /// different file systems. If that is the case, instead [copySync] the
-  /// file to the new location and then [removeSync] the original.
+  /// file to the new location and then [deleteSync] the original.
   ///
   /// If [newPath] identifies an existing file, that file is
   /// removed first. If [newPath] identifies an existing directory the
@@ -343,7 +343,7 @@
   /// Copies this file.
   ///
   /// If [newPath] is a relative path, it is resolved against
-  /// the current working directory ([Directory.cwd]).
+  /// the current working directory ([Directory.current]).
   ///
   /// Returns a `Future<File>` that completes
   /// with a [File] for the copied file.
@@ -356,7 +356,7 @@
   /// Synchronously copies this file.
   ///
   /// If [newPath] is a relative path, it is resolved against
-  /// the current working directory ([Directory.cwd]).
+  /// the current working directory ([Directory.current]).
   ///
   /// Returns a [File] for the copied file.
   ///
diff --git a/sdk/lib/io/io.dart b/sdk/lib/io/io.dart
index 5be8785..9a89e63 100644
--- a/sdk/lib/io/io.dart
+++ b/sdk/lib/io/io.dart
@@ -47,8 +47,8 @@
 ///
 /// To get information about a path,
 /// you can use the [FileSystemEntity] static methods
-/// such as [FileSystemEntitiy.isDirectory], [FileSystemEntitiy.isFile],
-/// and [FileSystemEntitiy.exists].
+/// such as [FileSystemEntity.isDirectory], [FileSystemEntity.isFile],
+/// and [FileSystemEntity.exists].
 /// Because file system access involves I/O, these methods
 /// are asynchronous and return a [Future].
 /// ```dart
@@ -124,7 +124,7 @@
 /// ```
 /// The client connects to the [WebSocket] using the [WebSocket.connect] method
 /// and a URI that uses the Web Socket protocol.
-/// The client can write to the [WebSocket] with the [Websocket.add] method.
+/// The client can write to the [WebSocket] with the [WebSocket.add] method.
 /// For example,
 /// ```dart
 /// var socket = await WebSocket.connect('ws://127.0.0.1:4040/ws');
diff --git a/sdk/lib/io/socket.dart b/sdk/lib/io/socket.dart
index a0eea00..22d57dd 100644
--- a/sdk/lib/io/socket.dart
+++ b/sdk/lib/io/socket.dart
@@ -310,11 +310,11 @@
   /// the system.
   ///
   /// The optional argument [shared] specifies whether additional ServerSocket
-  /// objects can bind to the same combination of [address], [port] [and] [v6Only].
-  /// If [shared] is `true` and more [ServerSockets] from this isolate or other
-  /// isolates are bound to the port, then the incoming connections will be
-  /// distributed among all the bound [ServerSockets]. Connections can be
-  /// distributed over multiple isolates this way.
+  /// objects can bind to the same combination of [address], [port] and
+  /// [v6Only]. If [shared] is `true` and more server sockets from this
+  /// isolate or other isolates are bound to the port, then the incoming
+  /// connections will be distributed among all the bound server sockets.
+  /// Connections can be distributed over multiple isolates this way.
   static Future<ServerSocket> bind(address, int port,
       {int backlog = 0, bool v6Only = false, bool shared = false}) {
     final IOOverrides? overrides = IOOverrides.current;
diff --git a/sdk/lib/typed_data/typed_data.dart b/sdk/lib/typed_data/typed_data.dart
index 20d17f8..df48112 100644
--- a/sdk/lib/typed_data/typed_data.dart
+++ b/sdk/lib/typed_data/typed_data.dart
@@ -10,6 +10,7 @@
 /// import 'dart:typed_data';
 /// ```
 /// {@category Core}
+/// {@canonicalFor dart:_internal.BytesBuilder}
 library dart.typed_data;
 
 import "dart:_internal" show Since, UnmodifiableListBase;
diff --git a/sdk/lib/vmservice/message.dart b/sdk/lib/vmservice/message.dart
index 5b07cea..a3a0e61 100644
--- a/sdk/lib/vmservice/message.dart
+++ b/sdk/lib/vmservice/message.dart
@@ -155,10 +155,15 @@
     return new_list;
   }
 
-  Future<Response> sendToIsolate(SendPort sendPort) {
+  Future<Response> sendToIsolate(
+      List<RawReceivePort> ports, SendPort sendPort) {
     final receivePort = RawReceivePort(null, 'Isolate Message');
+    // Keep track of receive port associated with the request so we can close
+    // it if isolate exits before sending a response.
+    ports.add(receivePort);
     receivePort.handler = (value) {
       receivePort.close();
+      ports.remove(receivePort);
       _setResponseFromPort(value);
     };
     final keys = _makeAllString(params.keys.toList(growable: false));
@@ -172,6 +177,7 @@
       ..[5] = values;
     if (!sendIsolateServiceMessage(sendPort, request)) {
       receivePort.close();
+      ports.remove(receivePort);
       _completer.complete(Response.internalError(
           'could not send message [${serial}] to isolate'));
     }
diff --git a/sdk/lib/vmservice/running_isolate.dart b/sdk/lib/vmservice/running_isolate.dart
index 8a6dd36..3902193 100644
--- a/sdk/lib/vmservice/running_isolate.dart
+++ b/sdk/lib/vmservice/running_isolate.dart
@@ -8,15 +8,22 @@
   final int portId;
   final SendPort sendPort;
   final String name;
+  final pendingMessagesReceivePorts = <RawReceivePort>[];
 
   RunningIsolate(this.portId, this.sendPort, this.name);
 
+  void onIsolateExit() {
+    pendingMessagesReceivePorts.forEach((port) {
+      (port as RawReceivePort).close();
+    });
+  }
+
   String get serviceId => 'isolates/$portId';
 
   @override
   Future<Response> routeRequest(VMService service, Message message) {
     // Send message to isolate.
-    return message.sendToIsolate(sendPort);
+    return message.sendToIsolate(pendingMessagesReceivePorts, sendPort);
   }
 
   @override
diff --git a/sdk/lib/vmservice/running_isolates.dart b/sdk/lib/vmservice/running_isolates.dart
index 03a6811..f9db4a5 100644
--- a/sdk/lib/vmservice/running_isolates.dart
+++ b/sdk/lib/vmservice/running_isolates.dart
@@ -22,7 +22,7 @@
     if (_rootPortId == portId) {
       _rootPortId = null;
     }
-    isolates.remove(portId);
+    (isolates.remove(portId))?.onIsolateExit();
   }
 
   @override
diff --git a/tools/VERSION b/tools/VERSION
index a403296..16de12d 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 12
 PATCH 0
-PRERELEASE 284
+PRERELEASE 285
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 4093a81..e8829df 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -623,6 +623,24 @@
         ]
       }
     },
+    "dart2js-o0-(linux|mac|win)-d8": {
+      "options": {
+        "builder-tag": "dart2js_o0",
+        "use-sdk": true,
+        "dart2js-options": [
+          "-O0"
+        ]
+      }
+    },
+    "dart2js-modern-(linux|mac|win)-d8": {
+      "options": {
+        "builder-tag": "dart2js_modern",
+        "use-sdk": true,
+        "dart2js-options": [
+          "--no-legacy-javascript"
+        ]
+      }
+    },
     "dart2js-hostasserts-(linux|mac|win)-(ia32|x64)-d8": {
       "options": {
         "host-checked": true,
@@ -2444,6 +2462,22 @@
             "--dart2js-batch",
             "dart2js_2"
           ]
+        },
+        {
+          "name": "dart2js -O0 smoke tests",
+          "arguments": [
+            "-ndart2js-o0-linux-d8",
+            "--dart2js-batch",
+            "dart2js_2"
+          ]
+        },
+        {
+          "name": "dart2js --no-legacy-javascript smoke tests",
+          "arguments": [
+            "-ndart2js-modern-linux-d8",
+            "--dart2js-batch",
+            "dart2js_2"
+          ]
         }
       ]
     },
@@ -3250,7 +3284,7 @@
           "script": "out/ReleaseX64/dart-sdk/bin/dartdoc",
           "arguments": [
             "--exclude",
-            "dart:ffi,dart:html,dart:web_sql,dart:web_audio,dart:svg,dart:indexed_db,dart:io",
+            "dart:ffi,dart:html,dart:web_sql,dart:web_audio,dart:svg,dart:indexed_db",
             "--sdk-docs",
             "--no-generate-docs"
           ],