Version 2.19.0-34.0.dev

Merge commit 'f9e833416e81d4cf292fbeb3e96c77edc6ac20b0' into 'dev'
diff --git a/.github/ISSUE_TEMPLATE/1_cherry_pick.yml b/.github/ISSUE_TEMPLATE/1_cherry_pick.yml
index a1c9afd..1c4536f 100644
--- a/.github/ISSUE_TEMPLATE/1_cherry_pick.yml
+++ b/.github/ISSUE_TEMPLATE/1_cherry_pick.yml
@@ -27,7 +27,7 @@
     id: issue_description
     attributes:
       label: Issue Description
-      description: Brief description of the issue.  What is the issue? What platforms are the problems occuring on?
+      description: Brief description of the issue.  What is the issue? What platforms are the problems occurring on?
     validations:
       required: true
   - type: textarea
diff --git a/.mailmap b/.mailmap
index 5f5adcc..6698757 100644
--- a/.mailmap
+++ b/.mailmap
@@ -1,4 +1,4 @@
-# This file contains name to mail address mappings that are usefull
+# This file contains name to mail address mappings that are useful
 # for old svn based commits (to get nice names instead of mail in blame and
 # other tools)
 Adam Klein <adamk@google.com>
diff --git a/DEPS b/DEPS
index f45a066..e2150e6 100644
--- a/DEPS
+++ b/DEPS
@@ -43,7 +43,7 @@
 
   # co19 is a cipd package. Use update.sh in tests/co19[_2] to update these
   # hashes.
-  "co19_rev": "5e94d0db25a8d8dfb6b1320bdb342e2935faf1d0",
+  "co19_rev": "b76040d28ded4be3cf1e808d609f0cceb8004522",
   # This line prevents conflicts when both packages are rolled simultaneously.
   "co19_2_rev": "b2034a17609472e374623f3dbe0efd9f5cb258af",
 
diff --git a/benchmarks/BigIntParsePrint/dart/BigIntParsePrint.dart b/benchmarks/BigIntParsePrint/dart/BigIntParsePrint.dart
index 3451cc3..237b488 100644
--- a/benchmarks/BigIntParsePrint/dart/BigIntParsePrint.dart
+++ b/benchmarks/BigIntParsePrint/dart/BigIntParsePrint.dart
@@ -12,7 +12,7 @@
 import 'native_version_dummy.dart'
     if (dart.library.js) 'native_version_javascript.dart';
 
-// Benckmark BigInt and Int64 formatting and parsing.
+// Benchmark BigInt and Int64 formatting and parsing.
 
 // A global sink that is used in the [check] method ensures that the results are
 // not optimized.
@@ -49,7 +49,7 @@
       if (b.bitLength < bits) {
         restartDelta += seed >> 20;
         restartDelta += BigInt.one;
-        // Restart from a slighly reduced seed to generate different numbers.
+        // Restart from a slightly reduced seed to generate different numbers.
         b = seed - restartDelta;
       }
       var string = b.toString();
@@ -310,7 +310,7 @@
     selectFormatNativeBigIntBenchmark('JsBigInt.toString.4096.bits', 4096),
   ];
 
-  // Warm up all benchmarks to ensure consistent behavious of shared code.
+  // Warm up all benchmarks to ensure consistent behavior of shared code.
   benchmarks.forEach((bm) => bm()
     ..setup()
     ..run()
diff --git a/benchmarks/Richards/dart/Richards.dart b/benchmarks/Richards/dart/Richards.dart
index f930651..3d8ed86 100644
--- a/benchmarks/Richards/dart/Richards.dart
+++ b/benchmarks/Richards/dart/Richards.dart
@@ -414,7 +414,7 @@
 }
 
 /// A simple package of data that is manipulated by the tasks.  The exact layout
-/// of the payload data carried by a packet is not importaint, and neither is
+/// of the payload data carried by a packet is not important, and neither is
 /// the nature of the work performed on packets by the tasks. Besides carrying
 /// data, packets form linked lists and are hence used both as data and
 /// worklists.
diff --git a/benchmarks/Richards/dart2/Richards.dart b/benchmarks/Richards/dart2/Richards.dart
index f479a32..0cb0a1a 100644
--- a/benchmarks/Richards/dart2/Richards.dart
+++ b/benchmarks/Richards/dart2/Richards.dart
@@ -418,7 +418,7 @@
 }
 
 /// A simple package of data that is manipulated by the tasks.  The exact layout
-/// of the payload data carried by a packet is not importaint, and neither is
+/// of the payload data carried by a packet is not important, and neither is
 /// the nature of the work performed on packets by the tasks. Besides carrying
 /// data, packets form linked lists and are hence used both as data and
 /// worklists.
diff --git a/benchmarks/Richards/javascript/Richards.js b/benchmarks/Richards/javascript/Richards.js
index 8a71f99..6820d26 100644
--- a/benchmarks/Richards/javascript/Richards.js
+++ b/benchmarks/Richards/javascript/Richards.js
@@ -497,7 +497,7 @@
 
 /**
  * A simple package of data that is manipulated by the tasks.  The exact layout
- * of the payload data carried by a packet is not importaint, and neither is the
+ * of the payload data carried by a packet is not important, and neither is the
  * nature of the work performed on packets by the tasks.
  *
  * Besides carrying data, packets form linked lists and are hence used both as
diff --git a/build/mac/change_mach_o_flags.py b/build/mac/change_mach_o_flags.py
index 4155dc6..b59b00b 100755
--- a/build/mac/change_mach_o_flags.py
+++ b/build/mac/change_mach_o_flags.py
@@ -121,7 +121,7 @@
 
 
 def ReadUInt32(file, endian):
-    """Reads an unsinged 32-bit integer from the file-like |file| object,
+    """Reads an unsigned 32-bit integer from the file-like |file| object,
   treating it as having endianness specified by |endian| (per the |struct|
   module), and returns it as a number. Raises a MachOError if the proper
   length of data can't be read from |file|."""
@@ -160,7 +160,7 @@
 
 
 def WriteUInt32(file, uint32, endian):
-    """Writes |uint32| as an unsinged 32-bit integer to the file-like |file|
+    """Writes |uint32| as an unsigned 32-bit integer to the file-like |file|
   object, treating it as having endianness specified by |endian| (per the
   |struct| module)."""
 
diff --git a/pkg/_fe_analyzer_shared/test/macros/executor/simple_macro.dart b/pkg/_fe_analyzer_shared/test/macros/executor/simple_macro.dart
index d653f77..d502abc 100644
--- a/pkg/_fe_analyzer_shared/test/macros/executor/simple_macro.dart
+++ b/pkg/_fe_analyzer_shared/test/macros/executor/simple_macro.dart
@@ -8,7 +8,7 @@
 
 /// A very simple macro that augments any declaration it is given, usually
 /// adding print statements and inlining values from the declaration object
-/// for comparision with expected values in tests.
+/// for comparison with expected values in tests.
 ///
 /// When applied to [MethodDeclaration]s there is some extra work that happens
 /// to validate the introspection APIs work as expected.
diff --git a/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart b/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
index 00f7c4c..ffe914e 100644
--- a/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
@@ -306,7 +306,7 @@
 
 /// Result for a request to resolve the type definition locations of a symbol at
 /// a given text document position. The request's parameter is of type
-/// TextDocumentPositioParams the response is of type Definition or a Thenable
+/// TextDocumentPositionParams the response is of type Definition or a Thenable
 /// that resolves to such.
 typedef TextDocumentTypeDefinitionResult
     = Either2<Definition, List<DefinitionLink>>?;
@@ -21955,7 +21955,7 @@
     );
   }
 
-  /// The URI for which the client knowns a result id.
+  /// The URI for which the client knows a result id.
   final DocumentUri uri;
 
   /// The value of the previous result id.
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/rename_to_camel_case.dart b/pkg/analysis_server/lib/src/services/correction/dart/rename_to_camel_case.dart
index 3323ec6..83f4f0a 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/rename_to_camel_case.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/rename_to_camel_case.dart
@@ -5,7 +5,7 @@
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/correction/util.dart';
-import 'package:analysis_server/src/utilities/strings.dart';
+import 'package:analysis_server/src/utilities/extensions/string.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
@@ -39,11 +39,11 @@
     }
 
     // Prepare the new name.
-    var words = identifier.name.split('_');
-    if (words.length < 2) {
+    var newName = identifier.name.toLowerCamelCase;
+    if (newName == null) {
       return;
     }
-    _newName = words.first + words.skip(1).map((w) => capitalize(w)).join();
+    _newName = newName;
 
     // Find references to the identifier.
     List<SimpleIdentifier>? references;
diff --git a/pkg/analysis_server/lib/src/utilities/extensions/string.dart b/pkg/analysis_server/lib/src/utilities/extensions/string.dart
new file mode 100644
index 0000000..6e9d46f
--- /dev/null
+++ b/pkg/analysis_server/lib/src/utilities/extensions/string.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+extension StringExtension on String {
+  /// Assuming that the receiver is a valid identifier, return a lowerCamelCase
+  /// version of the identifier.
+  ///
+  /// No checks are made that the receiver is a valid identifier, but the
+  /// receiver must contain at least one underscore (but neither at the
+  /// beginning nor the end), and must not have two adjacent underscores.
+  ///
+  /// The resulting identifier is one in which only the letters following the
+  /// underscores are capitalized.
+  String? get toLowerCamelCase {
+    var words = split('_');
+    if (words.length < 2) {
+      return null;
+    }
+    var firstWord = words.first;
+    if (firstWord.isEmpty) {
+      return null;
+    }
+    var buffer = StringBuffer();
+    buffer.write(firstWord.toLowerCase());
+    for (var i = 1; i < words.length; i++) {
+      var word = words[i];
+      if (word.isEmpty) {
+        return null;
+      }
+      buffer.write(word._capitalized);
+    }
+    return buffer.toString();
+  }
+
+  /// Return a version of this string in which the first character is upper case
+  /// and all remaining characters are lower case.
+  String get _capitalized {
+    if (length <= 1) {
+      return toUpperCase();
+    }
+    return substring(0, 1).toUpperCase() + substring(1).toLowerCase();
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_super_constructor_invocation_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_super_constructor_invocation_test.dart
index 42c321b..39cf4a9 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_super_constructor_invocation_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_super_constructor_invocation_test.dart
@@ -125,6 +125,7 @@
 
   @FailingTest(
     reason: 'Generates positional arguments instead of named',
+    issue: 'https://github.com/dart-lang/sdk/issues/49514',
   )
   Future<void> test_unnamed_requiredNamed() async {
     await resolveTestCode('''
diff --git a/pkg/analysis_server/test/src/services/correction/fix/rename_to_camel_case_test.dart b/pkg/analysis_server/test/src/services/correction/fix/rename_to_camel_case_test.dart
index a658d2d..a70faee 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/rename_to_camel_case_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/rename_to_camel_case_test.dart
@@ -104,6 +104,19 @@
 ''');
   }
 
+  Future<void> test_parameter_function_screamingCaps() async {
+    await resolveTestCode('''
+void f(int FIRST_PARAMETER) {
+  print(FIRST_PARAMETER);
+}
+''');
+    await assertHasFix('''
+void f(int firstParameter) {
+  print(firstParameter);
+}
+''');
+  }
+
   Future<void> test_parameter_method() async {
     await resolveTestCode('''
 class A {
diff --git a/pkg/analysis_server/test/src/utilities/extensions/string_test.dart b/pkg/analysis_server/test/src/utilities/extensions/string_test.dart
new file mode 100644
index 0000000..8f7c1ec
--- /dev/null
+++ b/pkg/analysis_server/test/src/utilities/extensions/string_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/utilities/extensions/string.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ToLowerCamelCaseTest);
+  });
+}
+
+@reflectiveTest
+class ToLowerCamelCaseTest {
+  void test_adjacentUnderscores() {
+    expect('a__b'.toLowerCamelCase, null);
+  }
+
+  void test_empty() {
+    expect(''.toLowerCamelCase, null);
+  }
+
+  void test_leadingUnderscore() {
+    expect('_a'.toLowerCamelCase, null);
+  }
+
+  void test_screamingCaps() {
+    expect('AA_BB'.toLowerCamelCase, 'aaBb');
+  }
+
+  void test_snakeCase() {
+    expect('aa_bb'.toLowerCamelCase, 'aaBb');
+  }
+
+  void test_trailingUnderscore() {
+    expect('a_'.toLowerCamelCase, null);
+  }
+}
diff --git a/pkg/analysis_server/test/src/utilities/extensions/test_all.dart b/pkg/analysis_server/test/src/utilities/extensions/test_all.dart
index d4620d4..e3dbeea2 100644
--- a/pkg/analysis_server/test/src/utilities/extensions/test_all.dart
+++ b/pkg/analysis_server/test/src/utilities/extensions/test_all.dart
@@ -5,9 +5,11 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'range_factory_test.dart' as range_factory;
+import 'string_test.dart' as string;
 
 void main() {
   defineReflectiveSuite(() {
     range_factory.main();
+    string.main();
   });
 }
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index 181f7c6..0e7ef20 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -263,10 +263,10 @@
   /// Return the offset of the character immediately following the last
   /// character of this node's source range.
   ///
-  /// This is equivalent to `node.getOffset() + node.getLength()`. For a
-  /// compilation unit this will be equal to the length of the unit's source.
-  /// For synthetic nodes this will be equivalent to the node's offset (because
-  /// the length is zero (0) by definition).
+  /// This is equivalent to `node.offset + node.length`. For a compilation unit
+  /// this will be equal to the length of the unit's source. For synthetic nodes
+  /// this will be equivalent to the node's offset (because the length is zero
+  /// (0) by definition).
   @override
   int get end;
 
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index cbe9d70..a9e7282 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -472,7 +472,8 @@
   Member(this._typeProvider, this._declaration, this._substitution,
       this.isLegacy) {
     if (_declaration is Member) {
-      throw StateError('Members must be created from a declarations.');
+      throw StateError('Members must be created from a declaration, but is '
+          '(${_declaration.runtimeType}) "$_declaration".');
     }
     if (_typeProvider == null && isLegacy) {
       throw StateError(
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
index d9a70fa..0c7dbe3 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
@@ -434,7 +434,7 @@
       }
     }
 
-    // TODO(scheglov) Dont write type, AKA separate true `int` and `double`?
+    // TODO(scheglov) Don't write type, AKA separate true `int` and `double`?
     _storeExpression(node);
   }
 
diff --git a/pkg/analyzer/lib/src/workspace/bazel_watcher.dart b/pkg/analyzer/lib/src/workspace/bazel_watcher.dart
index 54b96a0..b53019e 100644
--- a/pkg/analyzer/lib/src/workspace/bazel_watcher.dart
+++ b/pkg/analyzer/lib/src/workspace/bazel_watcher.dart
@@ -432,7 +432,7 @@
 ///
 /// The idea here is to detect when Bazel finished running and use that to
 /// trigger polling. To detect that we use the `command.log` file that bazel
-/// contiuously updates as the build progresses. We find that file based on [1]:
+/// continuously updates as the build progresses. We find that file based on [1]:
 ///
 /// - In the workspace directory there should be a `bazel-out` symlink whose
 ///   target should be of the form:
diff --git a/pkg/async_helper/lib/async_helper.dart b/pkg/async_helper/lib/async_helper.dart
index 6dd1b87..8dd5754 100644
--- a/pkg/async_helper/lib/async_helper.dart
+++ b/pkg/async_helper/lib/async_helper.dart
@@ -89,7 +89,7 @@
   return f().then(asyncSuccess);
 }
 
-/// Verifies that the asyncronous [result] throws a [T].
+/// Verifies that the asynchronous [result] throws a [T].
 ///
 /// Fails if [result] completes with a value, or it completes with
 /// an error which is not a [T].
diff --git a/pkg/compiler/lib/src/elements/types.dart b/pkg/compiler/lib/src/elements/types.dart
index 3b9b9c6..d07daa3 100644
--- a/pkg/compiler/lib/src/elements/types.dart
+++ b/pkg/compiler/lib/src/elements/types.dart
@@ -2269,7 +2269,7 @@
         type is FunctionTypeVariable && canAssignGenericFunctionTo(type.bound);
   }
 
-  /// Returns `true` if [type] occuring in a program with no sound null safety
+  /// Returns `true` if [type] occurring in a program with no sound null safety
   /// cannot accept `null` under sound rules.
   bool isNonNullableIfSound(DartType type) {
     if (type is DynamicType ||
diff --git a/pkg/compiler/lib/src/inferrer/powersets/powerset_bits.dart b/pkg/compiler/lib/src/inferrer/powersets/powerset_bits.dart
index d6e4d47..fd522dd 100644
--- a/pkg/compiler/lib/src/inferrer/powersets/powerset_bits.dart
+++ b/pkg/compiler/lib/src/inferrer/powersets/powerset_bits.dart
@@ -523,7 +523,7 @@
         // type and is maximal (i.e. instantiated to bounds), the typemask,
         // which is based on the class element, is still precise. We check
         // against Top for the parameter arguments since we don't have a
-        // convenient check for instantation to bounds.
+        // convenient check for instantiation to bounds.
         //
         // TODO(sra): Check arguments against bounds.
         // TODO(sra): Handle other variances.
diff --git a/pkg/compiler/lib/src/inferrer/type_system.dart b/pkg/compiler/lib/src/inferrer/type_system.dart
index 34abce3..c13eaaa 100644
--- a/pkg/compiler/lib/src/inferrer/type_system.dart
+++ b/pkg/compiler/lib/src/inferrer/type_system.dart
@@ -569,7 +569,7 @@
     return _addPhi(node, variable, inputType, isTry);
   }
 
-  /// Simplies the phi representing [element] and of the type
+  /// Simplifies the phi representing [element] and of the type
   /// [phiType]. For example, if this phi has one incoming input, an
   /// implementation of this method could just return that incoming
   /// input type.
diff --git a/pkg/compiler/lib/src/inferrer/typemasks/masks.dart b/pkg/compiler/lib/src/inferrer/typemasks/masks.dart
index cdccaa4..b2f8896 100644
--- a/pkg/compiler/lib/src/inferrer/typemasks/masks.dart
+++ b/pkg/compiler/lib/src/inferrer/typemasks/masks.dart
@@ -352,7 +352,7 @@
         // type and is maximal (i.e. instantiated to bounds), the typemask,
         // which is based on the class element, is still precise. We check
         // against Top for the parameter arguments since we don't have a
-        // convenient check for instantation to bounds.
+        // convenient check for instantiation to bounds.
         //
         // TODO(sra): Check arguments against bounds.
         // TODO(sra): Handle other variances.
diff --git a/pkg/compiler/lib/src/io/position_information.dart b/pkg/compiler/lib/src/io/position_information.dart
index 1270cab..dc628b4 100644
--- a/pkg/compiler/lib/src/io/position_information.dart
+++ b/pkg/compiler/lib/src/io/position_information.dart
@@ -841,10 +841,10 @@
 
 /// Listener for the [JavaScriptTracer].
 abstract class TraceListener {
-  /// Called before [root] node is procesed by the [JavaScriptTracer].
+  /// Called before [root] node is processed by the [JavaScriptTracer].
   void onStart(js.Node root) {}
 
-  /// Called after [root] node has been procesed by the [JavaScriptTracer].
+  /// Called after [root] node has been processed by the [JavaScriptTracer].
   void onEnd(js.Node root) {}
 
   /// Called when a branch of the given [kind] is started. [value] is provided
diff --git a/pkg/compiler/lib/src/io/source_information.dart b/pkg/compiler/lib/src/io/source_information.dart
index 740d829..a07177a 100644
--- a/pkg/compiler/lib/src/io/source_information.dart
+++ b/pkg/compiler/lib/src/io/source_information.dart
@@ -66,7 +66,7 @@
 /// Context information about inlined calls.
 ///
 /// This is associated with SourceInformation objects to be able to emit
-/// precise data about inlining that can then be used by defobuscation tools
+/// precise data about inlining that can then be used by deobfuscation tools
 /// when reconstructing a source stack from a production stack trace.
 class FrameContext {
   static const String tag = 'frame-context';
diff --git a/pkg/compiler/lib/src/ir/scope_visitor.dart b/pkg/compiler/lib/src/ir/scope_visitor.dart
index 7a3863f..113387f 100644
--- a/pkg/compiler/lib/src/ir/scope_visitor.dart
+++ b/pkg/compiler/lib/src/ir/scope_visitor.dart
@@ -118,7 +118,7 @@
       assert(node is ir.Procedure || node is ir.Constructor);
       if (!(node is ir.Procedure && node.isRedirectingFactory)) {
         // Skip redirecting factories: they contain invalid expressions only
-        // used to suppport internal CFE modular compilation.
+        // used to support internal CFE modular compilation.
         node.accept(this);
       }
     }
diff --git a/pkg/compiler/lib/src/js/placeholder_safety.dart b/pkg/compiler/lib/src/js/placeholder_safety.dart
index 6a08913..f99b76c 100644
--- a/pkg/compiler/lib/src/js/placeholder_safety.dart
+++ b/pkg/compiler/lib/src/js/placeholder_safety.dart
@@ -10,7 +10,7 @@
 
 /// PlaceholderSafetyAnalysis determines which placeholders in a JavaScript
 /// template may be replaced with an arbitrary expression. Placeholders may be
-/// replaced with an arbitrary expression providied the template ensures the
+/// replaced with an arbitrary expression provided the template ensures the
 /// placeholders are evaluated in the same left-to-right order with no
 /// additional effects interleaved.
 ///
diff --git a/pkg/compiler/lib/src/js_backend/frequency_assignment.dart b/pkg/compiler/lib/src/js_backend/frequency_assignment.dart
index 7acd907..b189afa 100644
--- a/pkg/compiler/lib/src/js_backend/frequency_assignment.dart
+++ b/pkg/compiler/lib/src/js_backend/frequency_assignment.dart
@@ -176,7 +176,7 @@
 /// entities are identified by integers.
 class _Cohort {
   _Cohort? next; // Next cohort in decreasing frequency.
-  final int count; // This is the cohort of items occuring [count] times.
+  final int count; // This is the cohort of items occurring [count] times.
   Set<int> unassigned = Set();
 
   _Cohort(this.count);
diff --git a/pkg/compiler/lib/src/js_backend/string_reference.dart b/pkg/compiler/lib/src/js_backend/string_reference.dart
index 949aec8..b406bb4 100644
--- a/pkg/compiler/lib/src/js_backend/string_reference.dart
+++ b/pkg/compiler/lib/src/js_backend/string_reference.dart
@@ -10,7 +10,7 @@
 ///     foo1() => 'A very long string';
 ///
 /// might be compiled to something like the following, where StringReference1 is
-/// assocatied with the string `'A very long string'`.
+/// associated with the string `'A very long string'`.
 ///
 ///     foo1: function() {
 ///       return StringReference1;
@@ -77,7 +77,7 @@
   // (hot, cold, execute-once, etc).
   static const int shortestSharedLength = 40;
 
-  // TODO(sra): Add policy for huge non-shared strings, strings occuring in
+  // TODO(sra): Add policy for huge non-shared strings, strings occurring in
   // run-once code, etc. Maybe make policy settings assignable for testing or
   // command-line configuration.
 }
diff --git a/pkg/compiler/lib/src/js_backend/type_reference.dart b/pkg/compiler/lib/src/js_backend/type_reference.dart
index 2f4bc25..87bb36b 100644
--- a/pkg/compiler/lib/src/js_backend/type_reference.dart
+++ b/pkg/compiler/lib/src/js_backend/type_reference.dart
@@ -390,7 +390,7 @@
       }
 
       // TODO(sra): There are other contexts that would be beneficial, e.g. a
-      // type reference occuring only in a throw expression.
+      // type reference occurring only in a throw expression.
 
       String suggestedName = _RecipeToIdentifier().run(referenceSet.recipe);
       if (usedNames.contains(suggestedName)) {
diff --git a/pkg/compiler/lib/src/js_model/type_recipe.dart b/pkg/compiler/lib/src/js_model/type_recipe.dart
index 9214969..0bc5f99 100644
--- a/pkg/compiler/lib/src/js_model/type_recipe.dart
+++ b/pkg/compiler/lib/src/js_model/type_recipe.dart
@@ -559,7 +559,7 @@
     int count = _counts[variable] = (_counts[variable] ?? 0) + 1;
     if (count > 1) {
       // If the replacement is 'big', duplicating it can grow the term, perhaps
-      // exponentially given a sufficently pathological input.
+      // exponentially given a sufficiently pathological input.
       // TODO(sra): Fix exponential terms by encoding a DAG in recipes to avoid
       // linearization.
       if (replacement is FunctionType ||
diff --git a/pkg/compiler/tool/kernel_visitor/dart_html_metrics_visitor.dart b/pkg/compiler/tool/kernel_visitor/dart_html_metrics_visitor.dart
index 72edb13..8268481 100644
--- a/pkg/compiler/tool/kernel_visitor/dart_html_metrics_visitor.dart
+++ b/pkg/compiler/tool/kernel_visitor/dart_html_metrics_visitor.dart
@@ -69,7 +69,7 @@
 
   @override
   void visitClass(Class node) {
-    // Dont want to add duplicate info.
+    // Don't want to add duplicate info.
     // When mixed, anonymous mixin class generated so we want to ignore.
     if (!node.isAnonymousMixin) {
       currentClass = node.name;
diff --git a/pkg/dart2wasm/lib/closures.dart b/pkg/dart2wasm/lib/closures.dart
index 6eb4bdf..7edda581 100644
--- a/pkg/dart2wasm/lib/closures.dart
+++ b/pkg/dart2wasm/lib/closures.dart
@@ -246,7 +246,8 @@
 
   @override
   void visitTypeParameterType(TypeParameterType node) {
-    if (node.parameter.parent == member.enclosingClass) {
+    if (node.parameter.parent != null &&
+        node.parameter.parent == member.enclosingClass) {
       _visitThis();
     } else if (node.parameter.parent is FunctionNode) {
       _visitVariableUse(node.parameter);
diff --git a/pkg/dart2wasm/lib/intrinsics.dart b/pkg/dart2wasm/lib/intrinsics.dart
index 9e5effc..a4902ad 100644
--- a/pkg/dart2wasm/lib/intrinsics.dart
+++ b/pkg/dart2wasm/lib/intrinsics.dart
@@ -610,6 +610,15 @@
       return w.NumType.i32;
     }
 
+    if (target.enclosingLibrary.name == "dart.core" &&
+        target.name.text == "_isIntrinsified") {
+      // This is part of the VM's [BigInt] implementation. We just return false.
+      // TODO(joshualitt): Can we find another way to reuse this patch file
+      // without hardcoding this case?
+      b.i32_const(0);
+      return w.NumType.i32;
+    }
+
     return null;
   }
 
diff --git a/pkg/dart2wasm/lib/option.dart b/pkg/dart2wasm/lib/option.dart
index fc45d7d..ab9d219 100644
--- a/pkg/dart2wasm/lib/option.dart
+++ b/pkg/dart2wasm/lib/option.dart
@@ -34,7 +34,7 @@
                 defaultsTo: defaultsTo,
                 negatable: negatable),
             applyToOptions,
-            (v) => v == 'true' ? true : false);
+            (v) => v);
 }
 
 class ValueOption<T> extends Option<T> {
diff --git a/pkg/dartdev/lib/dartdev.dart b/pkg/dartdev/lib/dartdev.dart
index 11ddd06..f6f37dd 100644
--- a/pkg/dartdev/lib/dartdev.dart
+++ b/pkg/dartdev/lib/dartdev.dart
@@ -36,38 +36,48 @@
 /// This is typically called from bin/, but given the length of the method and
 /// analytics logic, it has been moved here.
 Future<void> runDartdev(List<String> args, SendPort? port) async {
-  VmInteropHandler.initialize(port);
-
-  // TODO(sigurdm): Remove when top-level pub is removed.
-  if (args[0] == '__deprecated_pub') {
-    // This is the entry-point supporting the top-level `pub` script.
-    // ignore: deprecated_member_use
-    VmInteropHandler.exit(await deprecatedpubCommand().run(args.skip(1)));
-    return;
-  }
-
-  if (args.contains('run')) {
-    // These flags have a format that can't be handled by package:args, so while
-    // they are valid flags we'll assume the VM has verified them by this point.
-    args = args
-        .where(
-          (element) => !(element.contains('--observe') ||
-              element.contains('--enable-vm-service') ||
-              element.contains('--devtools')),
-        )
-        .toList();
-  }
-
-  // Finally, call the runner to execute the command; see DartdevRunner.
-  final runner = DartdevRunner(args);
   int? exitCode = 1;
   try {
-    exitCode = await runner.run(args);
+    VmInteropHandler.initialize(port);
+
+    // TODO(sigurdm): Remove when top-level pub is removed.
+    if (args[0] == '__deprecated_pub') {
+      // This is the entry-point supporting the top-level `pub` script.
+      // ignore: deprecated_member_use
+      exitCode = await deprecatedpubCommand().run(args.skip(1));
+    } else {
+      if (args.contains('run')) {
+        // These flags have a format that can't be handled by package:args, so while
+        // they are valid flags we'll assume the VM has verified them by this point.
+        args = args
+            .where(
+              (element) => !(element.contains('--observe') ||
+                  element.contains('--enable-vm-service') ||
+                  element.contains('--devtools')),
+            )
+            .toList();
+      }
+
+      // Finally, call the runner to execute the command; see DartdevRunner.
+      final runner = DartdevRunner(args);
+      exitCode = await runner.run(args);
+    }
   } on UsageException catch (e) {
     // TODO(sigurdm): It is unclear when a UsageException gets to here, and
     // when it is in DartdevRunner.runCommand.
     io.stderr.writeln('$e');
     exitCode = 64;
+  } catch (e, st) {
+    // Unexpected error encountered.
+    io.stderr.writeln('An unexpected error was encountered by the Dart CLI.');
+    io.stderr.writeln('Please file an issue at '
+        'https://github.com/dart-lang/sdk/issues/new with the following '
+        'details:\n');
+    io.stderr.writeln("Invocation: 'dart ${args.join(' ')}'");
+    io.stderr.writeln("Exception: '$e'");
+    io.stderr.writeln('Stack Trace:');
+    io.stderr.writeln(st.toString());
+    exitCode = 255;
   } finally {
     VmInteropHandler.exit(exitCode);
   }
diff --git a/pkg/dartdev/lib/src/sdk.dart b/pkg/dartdev/lib/src/sdk.dart
index 57b99c6..a994d9e 100644
--- a/pkg/dartdev/lib/src/sdk.dart
+++ b/pkg/dartdev/lib/src/sdk.dart
@@ -114,7 +114,7 @@
 
   static Runtime _createSingleton() {
     var versionString = Platform.version;
-    // Exepcted format: "version (channel) ..."
+    // Expected format: "version (channel) ..."
     var version = versionString;
     String? channel;
     var versionEnd = versionString.indexOf(' ');
diff --git a/pkg/dds/lib/src/dap/adapters/dart.dart b/pkg/dds/lib/src/dap/adapters/dart.dart
index 67f3368..7c00a55 100644
--- a/pkg/dds/lib/src/dap/adapters/dart.dart
+++ b/pkg/dds/lib/src/dap/adapters/dart.dart
@@ -311,7 +311,7 @@
   /// The DDS instance that was started and that [vmService] is connected to.
   ///
   /// `null` if the session is running in noDebug mode of the connection has not
-  /// yet been made.
+  /// yet been made or has been shut down.
   DartDevelopmentService? _dds;
 
   /// The [InitializeRequestArguments] provided by the client in the
@@ -786,8 +786,10 @@
     isTerminating = true;
 
     await disconnectImpl();
-    await shutdown();
+    await shutdownDebugee();
     sendResponse();
+
+    await shutdown();
   }
 
   /// evaluateRequest is called by the client to evaluate a string expression.
@@ -1227,16 +1229,38 @@
     sendResponse(SetExceptionBreakpointsResponseBody());
   }
 
-  /// Shuts down and cleans up.
+  /// Shuts down/detatches from the debugee and cleans up.
   ///
   /// This is called by [disconnectRequest] and [terminateRequest] but may also
   /// be called if the client just disconnects from the server without calling
   /// either.
   ///
   /// This method must tolerate being called multiple times.
-  @mustCallSuper
-  Future<void> shutdown() async {
+  @nonVirtual
+  Future<void> shutdownDebugee() async {
     await _dds?.shutdown();
+    _dds = null;
+  }
+
+  /// Shuts down the debug adapter, including terminating/detatching from the
+  /// debugee if required.
+  @nonVirtual
+  Future<void> shutdown() async {
+    await _waitForPendingOutputEvents();
+    await shutdownDebugee();
+
+    // Delay the shutdown slightly to allow any pending responses (such as the
+    // terminate response) to be sent.
+    //
+    // If we don't wait long enough here, the client may miss events like the
+    // TerminatedEvent. Waiting too long is generally not an issue, as the
+    // client can terminate the process itself once it processes the
+    // TerminatedEvent.
+
+    Future.delayed(
+      Duration(milliseconds: 500),
+      () => super.shutdown(),
+    );
   }
 
   /// [sourceRequest] is called by the client to request source code for a given
@@ -1445,8 +1469,10 @@
     isTerminating = true;
 
     await terminateImpl();
-    await shutdown();
+    await shutdownDebugee();
     sendResponse();
+
+    await shutdown();
   }
 
   /// Handles a request from the client for the list of threads.
diff --git a/pkg/dds/lib/src/dap/base_debug_adapter.dart b/pkg/dds/lib/src/dap/base_debug_adapter.dart
index 92fcf2e..bd67bb6 100644
--- a/pkg/dds/lib/src/dap/base_debug_adapter.dart
+++ b/pkg/dds/lib/src/dap/base_debug_adapter.dart
@@ -368,6 +368,12 @@
     }
   }
 
+  /// Shuts down the debug adapter by closing the underlying communication
+  /// channel.
+  void shutdown() {
+    _channel.close();
+  }
+
   /// Helpers for requests that have `void` arguments. The supplied args are
   /// ignored.
   void _voidArgs(Map<String, Object?>? args) {}
diff --git a/pkg/dds/test/dap/integration/debug_test.dart b/pkg/dds/test/dap/integration/debug_test.dart
index 5eae24a..057ad74 100644
--- a/pkg/dds/test/dap/integration/debug_test.dart
+++ b/pkg/dds/test/dap/integration/debug_test.dart
@@ -11,6 +11,7 @@
 
 import 'test_client.dart';
 import 'test_scripts.dart';
+import 'test_server.dart';
 import 'test_support.dart';
 
 main() {
@@ -311,6 +312,12 @@
           .firstWhere((event) => event.output.trim() == newText);
 
       await dap.client.terminate();
+
+      // If we're running out of process, ensure the server process terminates.
+      final server = dap.server;
+      if (server is OutOfProcessDapTestServer) {
+        await server.exitCode;
+      }
     });
     // These tests can be slow due to starting up the external server process.
   }, timeout: Timeout.none);
diff --git a/pkg/dds/test/dap/integration/test_server.dart b/pkg/dds/test/dap/integration/test_server.dart
index 2da9a3a..612e555 100644
--- a/pkg/dds/test/dap/integration/test_server.dart
+++ b/pkg/dds/test/dap/integration/test_server.dart
@@ -77,6 +77,7 @@
   var _isShuttingDown = false;
   final Process _process;
 
+  Future<int> get exitCode => _process.exitCode;
   StreamSink<List<int>> get sink => _process.stdin;
   Stream<List<int>> get stream => _process.stdout;
 
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index b249140..bf38b06 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -3646,7 +3646,7 @@
           runtimeCall('nullFailed(#, #, #, #)', [
             location != null
                 ? _cacheUri(location.file.toString())
-                : NullLiteral(),
+                : js_ast.LiteralNull(),
             js.number(location?.line ?? -1),
             js.number(location?.column ?? -1),
             js.escapedString('${p.name}')
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_shared.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_shared.dart
index 1bf8c27..f1b4474 100644
--- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_shared.dart
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_shared.dart
@@ -357,6 +357,34 @@
     });
   });
 
+  group('Automatically inserted argument null checks', () {
+    var source = r'''
+      main() {
+        // Breakpoint: bp
+        print('hello world');
+      }
+    ''';
+
+    setUpAll(() async {
+      await driver.initSource(setup, source);
+    });
+
+    tearDownAll(() async {
+      await driver.cleanupTest();
+    });
+
+    test('do not cause a crash in the expression compiler', () async {
+      // Compiling an expression that contains a method with a non-nullable
+      // parameter was causing a compiler crash due to the lack of a source
+      // location and the use of the wrong null literal value. This verifies
+      // the expression compiler can safely compile this pattern.
+      await driver.check(
+          breakpointId: 'bp',
+          expression: '((){bool fn(bool b) {return b;} return fn(true);})()',
+          expectedResult: 'true');
+    });
+  });
+
   group('Synthetic variables', () {
     var source = r'''
       dynamic couldReturnNull() => null;
@@ -376,7 +404,7 @@
       await driver.cleanupTest();
     });
 
-    test('do not cause a crash the expression compiler', () async {
+    test('do not cause a crash in the expression compiler', () async {
       // The null aware code in the test source causes the compiler to introduce
       // a let statement that includes a synthetic variable declaration.
       // That variable has no name and was causing a crash in the expression
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_suite.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_suite.dart
index 57466f1..3941227 100644
--- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_suite.dart
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_suite.dart
@@ -266,8 +266,9 @@
     }
 
     // Connect to the first 'normal' tab.
-    var tab = await chrome.chromeConnection
-        .getTab((tab) => !tab.isBackgroundPage && !tab.isChromeExtension);
+    var tab = await chrome.chromeConnection.getTab(
+        (tab) => !tab.isBackgroundPage && !tab.isChromeExtension,
+        retryFor: Duration(seconds: 5));
     if (tab == null) {
       throw Exception('Unable to connect to Chrome tab');
     }
diff --git a/pkg/frontend_server/lib/src/strong_components.dart b/pkg/frontend_server/lib/src/strong_components.dart
index 3fca363..6a85d6b 100644
--- a/pkg/frontend_server/lib/src/strong_components.dart
+++ b/pkg/frontend_server/lib/src/strong_components.dart
@@ -34,7 +34,7 @@
   /// The Component that is being compiled.
   ///
   /// On incremental compiles, this will only contain the invalidated
-  /// lbraries.
+  /// libraries.
   final Component component;
 
   /// The libraries loaded from a dill file that should not be processed.
diff --git a/pkg/js/proposal.md b/pkg/js/proposal.md
index 8460195..c5eab45 100644
--- a/pkg/js/proposal.md
+++ b/pkg/js/proposal.md
@@ -1370,7 +1370,7 @@
   final int x = 1;
   int y, z;
   factory MyDartClass(int y, int z) {
-    // super constructpr parameters passed here?
+    // super constructor parameters passed here?
     var self = createJS<MyDartClass>(); 
     self.y = y;
     self.z = z;
diff --git a/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart b/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart
index cb6601e..85e700f 100644
--- a/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart
+++ b/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart
@@ -433,7 +433,7 @@
   ///
   /// Upon transformation the [changedStructureNotifier] (if provided) is used
   /// to notify the listener that  that class hierarchy of certain classes has
-  /// changed. This is neccesary for instance when doing an incremental
+  /// changed. This is necessary for instance when doing an incremental
   /// compilation where the class hierarchy is kept between compiles and thus
   /// has to be kept up to date.
   void transform(Component module, List<Library> libraries,
diff --git a/pkg/modular_test/lib/src/pipeline.dart b/pkg/modular_test/lib/src/pipeline.dart
index dee4a68..b65eb12 100644
--- a/pkg/modular_test/lib/src/pipeline.dart
+++ b/pkg/modular_test/lib/src/pipeline.dart
@@ -4,7 +4,7 @@
 
 /// Abstraction for a compilation pipeline.
 ///
-/// A pipeline defines how modular steps are excuted and ensures that a step
+/// A pipeline defines how modular steps are executed and ensures that a step
 /// only has access to the data it declares.
 ///
 /// The abstract implementation validates how the data is declared, and the
@@ -42,7 +42,7 @@
   /// Whether this step is only executed on the main module.
   final bool onlyOnMain;
 
-  /// Whether this step is only exceuted on the SDK.
+  /// Whether this step is only executed on the SDK.
   final bool onlyOnSdk;
 
   /// Whether this step is not executed on the SDK.
diff --git a/pkg/native_stack_traces/CHANGELOG.md b/pkg/native_stack_traces/CHANGELOG.md
index a1b47ce..39f1612 100644
--- a/pkg/native_stack_traces/CHANGELOG.md
+++ b/pkg/native_stack_traces/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.5.1
+
+- Exported more ELF utilities for use in Dart tests.
+
 ## 0.5.0
 
 - Require Dart >= 2.17 (enhanced enum support)
diff --git a/pkg/native_stack_traces/lib/elf.dart b/pkg/native_stack_traces/lib/elf.dart
index 31272b1..7c6e4bb 100644
--- a/pkg/native_stack_traces/lib/elf.dart
+++ b/pkg/native_stack_traces/lib/elf.dart
@@ -8,4 +8,12 @@
         isolateSymbolName,
         vmDataSymbolName,
         vmSymbolName;
-export 'src/elf.dart' show DynamicTable, DynamicTableTag, Elf, Section, Symbol;
+export 'src/elf.dart'
+    show
+        DynamicTable,
+        DynamicTableTag,
+        Elf,
+        Section,
+        Symbol,
+        SymbolBinding,
+        SymbolType;
diff --git a/pkg/native_stack_traces/lib/src/elf.dart b/pkg/native_stack_traces/lib/src/elf.dart
index d8328eb..6b8bbbe 100644
--- a/pkg/native_stack_traces/lib/src/elf.dart
+++ b/pkg/native_stack_traces/lib/src/elf.dart
@@ -696,16 +696,19 @@
   }
 }
 
+/// An enumeration of recognized symbol binding values used by the ELF format.
 enum SymbolBinding {
   STB_LOCAL,
   STB_GLOBAL,
   STB_WEAK,
 }
 
+/// An enumeration of recognized symbol types used by the ELF format.
 enum SymbolType {
   STT_NOTYPE,
   STT_OBJECT,
   STT_FUNC,
+  STT_SECTION,
 }
 
 enum SymbolVisibility {
@@ -1006,6 +1009,17 @@
     return null;
   }
 
+  /// Returns an iterable of the symbols in the dynamic symbol table(s).
+  /// The ordering of the symbols is not guaranteed.
+  Iterable<Symbol> get dynamicSymbols sync* {
+    for (final section in namedSections('.dynsym')) {
+      final dynsym = section as SymbolTable;
+      for (final symbol in dynsym.values) {
+        yield symbol;
+      }
+    }
+  }
+
   /// Reverse lookup of the static symbol that contains the given virtual
   /// address. Returns null if no static symbol matching the address is found.
   @override
@@ -1028,6 +1042,17 @@
     return bestSym;
   }
 
+  /// Returns an iterable of the symbols in the static symbol table(s).
+  /// The ordering of the symbols is not guaranteed.
+  Iterable<Symbol> get staticSymbols sync* {
+    for (final section in namedSections('.symtab')) {
+      final symtab = section as SymbolTable;
+      for (final symbol in symtab.values) {
+        yield symbol;
+      }
+    }
+  }
+
   /// Creates an [Elf] from the data pointed to by [reader].
   ///
   /// After succesful completion, the [endian] and [wordSize] fields of the
diff --git a/pkg/nnbd_migration/test/api_test.dart b/pkg/nnbd_migration/test/api_test.dart
index 2ea7e14..5e31fe1 100644
--- a/pkg/nnbd_migration/test/api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -111,7 +111,7 @@
     }
   }
 
-  /// Verifies that migraiton of the single file with the given [content]
+  /// Verifies that migration of the single file with the given [content]
   /// produces the [expected] output.
   ///
   /// Optional parameter [removeViaComments] indicates whether dead code should
diff --git a/pkg/test_runner/lib/src/process_queue.dart b/pkg/test_runner/lib/src/process_queue.dart
index 8610553..1e432e6 100644
--- a/pkg/test_runner/lib/src/process_queue.dart
+++ b/pkg/test_runner/lib/src/process_queue.dart
@@ -149,7 +149,7 @@
 
         eventFinishedTestCase(finishedTestCase);
       }, onDone: () {
-        // Wait until the commandQueue/exectutor is done (it may need to stop
+        // Wait until the commandQueue/executor is done (it may need to stop
         // batch runners, browser controllers, ....)
         commandQueue.done.then((_) {
           cancelDebugTimer();
diff --git a/pkg/test_runner/test/skipping_dart2js_compilations_test.dart b/pkg/test_runner/test/skipping_dart2js_compilations_test.dart
index 969a1bb..8abedc3 100644
--- a/pkg/test_runner/test/skipping_dart2js_compilations_test.dart
+++ b/pkg/test_runner/test/skipping_dart2js_compilations_test.dart
@@ -29,7 +29,7 @@
 
 import 'utils.dart';
 
-/// This class is reponsible for setting up the files necessary for this test
+/// This class is responsible for setting up the files necessary for this test
 /// as well as touching a file.
 class FileUtils {
   late Directory tempDir;
diff --git a/pkg/vm_service/lib/src/vm_service.dart b/pkg/vm_service/lib/src/vm_service.dart
index 3e66f4b..f182689 100644
--- a/pkg/vm_service/lib/src/vm_service.dart
+++ b/pkg/vm_service/lib/src/vm_service.dart
@@ -2442,7 +2442,7 @@
 
   String? get details => data == null ? null : data!['details'];
 
-  /// Return a map representation of this error suitable for converstion to
+  /// Return a map representation of this error suitable for conversion to
   /// json.
   Map<String, dynamic> toMap() {
     Map<String, dynamic> map = {
diff --git a/pkg/vm_service/tool/dart/generate_dart.dart b/pkg/vm_service/tool/dart/generate_dart.dart
index 5475adc..f972a69 100644
--- a/pkg/vm_service/tool/dart/generate_dart.dart
+++ b/pkg/vm_service/tool/dart/generate_dart.dart
@@ -292,7 +292,7 @@
 
   String? get details => data == null ? null : data!['details'];
 
-  /// Return a map representation of this error suitable for converstion to
+  /// Return a map representation of this error suitable for conversion to
   /// json.
   Map<String, dynamic> toMap() {
     Map<String, dynamic> map = {
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 4f2fc30..f45925e 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -1615,7 +1615,7 @@
  * \param error A non-NULL pointer which will hold an error message if the call
  *   fails. The error has to be free()ed by the caller.
  *
- * \return If successfull the VM takes owernship of the isolate and takes care
+ * \return If successful the VM takes owernship of the isolate and takes care
  *   of its message loop. If not successful the caller retains owernship of the
  *   isolate.
  */
diff --git a/runtime/lib/ffi_dynamic_library.cc b/runtime/lib/ffi_dynamic_library.cc
index afb94aa..84c6ec6 100644
--- a/runtime/lib/ffi_dynamic_library.cc
+++ b/runtime/lib/ffi_dynamic_library.cc
@@ -15,6 +15,34 @@
 
 namespace dart {
 
+#if defined(USING_SIMULATOR)
+
+DART_NORETURN static void SimulatorUnsupported() {
+  Exceptions::ThrowUnsupportedError(
+      "Not supported on simulated architectures.");
+}
+
+DEFINE_NATIVE_ENTRY(Ffi_dl_open, 0, 1) {
+  SimulatorUnsupported();
+}
+DEFINE_NATIVE_ENTRY(Ffi_dl_processLibrary, 0, 0) {
+  SimulatorUnsupported();
+}
+DEFINE_NATIVE_ENTRY(Ffi_dl_executableLibrary, 0, 0) {
+  SimulatorUnsupported();
+}
+DEFINE_NATIVE_ENTRY(Ffi_dl_lookup, 1, 2) {
+  SimulatorUnsupported();
+}
+DEFINE_NATIVE_ENTRY(Ffi_dl_getHandle, 0, 1) {
+  SimulatorUnsupported();
+}
+DEFINE_NATIVE_ENTRY(Ffi_dl_providesSymbol, 0, 2) {
+  SimulatorUnsupported();
+}
+
+#else  // defined(USING_SIMULATOR)
+
 static void* LoadDynamicLibrary(const char* library_file) {
   char* error = nullptr;
   void* handle = Utils::LoadDynamicLibrary(library_file, &error);
@@ -63,11 +91,8 @@
     defined(DART_HOST_OS_ANDROID) || defined(DART_HOST_OS_FUCHSIA)
   return DynamicLibrary::New(RTLD_DEFAULT);
 #else
-  const Array& args = Array::Handle(Array::New(1));
-  args.SetAt(0,
-             String::Handle(String::New(
-                 "DynamicLibrary.process is not available on this platform.")));
-  Exceptions::ThrowByType(Exceptions::kUnsupported, args);
+  Exceptions::ThrowUnsupportedError(
+      "DynamicLibrary.process is not available on this platform.");
 #endif
 }
 
@@ -105,4 +130,6 @@
   return Bool::Get(SymbolExists(handle, argSymbolName.ToCString())).ptr();
 }
 
+#endif  // defined(USING_SIMULATOR)
+
 }  // namespace dart
diff --git a/runtime/observatory/lib/src/elements/heap_snapshot.dart b/runtime/observatory/lib/src/elements/heap_snapshot.dart
index 7deb8c7..6f79bf4 100644
--- a/runtime/observatory/lib/src/elements/heap_snapshot.dart
+++ b/runtime/observatory/lib/src/elements/heap_snapshot.dart
@@ -418,7 +418,7 @@
     for (var i = 0; i < worklist.length; i++) {
       worklist[i]._computeChildren(worklist);
     }
-    // Compute area botton-up.
+    // Compute area bottom-up.
     for (var i = worklist.length - 1; i >= 0; i--) {
       worklist[i]._computeArea();
     }
diff --git a/runtime/observatory/lib/src/elements/process_snapshot.dart b/runtime/observatory/lib/src/elements/process_snapshot.dart
index 6e87923..03b727b 100644
--- a/runtime/observatory/lib/src/elements/process_snapshot.dart
+++ b/runtime/observatory/lib/src/elements/process_snapshot.dart
@@ -113,7 +113,7 @@
     for (var i = 0; i < worklist.length; i++) {
       worklist[i]._computeChildren(worklist);
     }
-    // Compute area botton-up.
+    // Compute area bottom-up.
     for (var i = worklist.length - 1; i >= 0; i--) {
       worklist[i]._computeArea();
     }
diff --git a/runtime/observatory/lib/tracer.dart b/runtime/observatory/lib/tracer.dart
index 3f9a07f..f47ddc9 100644
--- a/runtime/observatory/lib/tracer.dart
+++ b/runtime/observatory/lib/tracer.dart
@@ -67,7 +67,7 @@
   // The start time for the current request.
   Stopwatch? _time;
 
-  // A list of all tracing events for thre current request.
+  // A list of all tracing events for the current request.
   List<TraceEvent> events = <TraceEvent>[];
 
   Tracer() {
diff --git a/runtime/observatory/tests/service/string_escaping_test.dart b/runtime/observatory/tests/service/string_escaping_test.dart
index 866178c6..958432e 100644
--- a/runtime/observatory/tests/service/string_escaping_test.dart
+++ b/runtime/observatory/tests/service/string_escaping_test.dart
@@ -53,7 +53,7 @@
   nullInTheMiddle = "There are four\u0000 words.";
   escapedUnicodeEscape = "Should not be A: \\u0041";
 
-  // A surrogate pair will cross the preferred truncation boundry.
+  // A surrogate pair will cross the preferred truncation boundary.
   longStringEven = "..";
   for (int i = 0; i < 512; i++) longStringEven += "𝄞";
   longStringOdd = ".";
diff --git a/runtime/observatory_2/lib/src/elements/heap_snapshot.dart b/runtime/observatory_2/lib/src/elements/heap_snapshot.dart
index 3ab4f6c..0320519 100644
--- a/runtime/observatory_2/lib/src/elements/heap_snapshot.dart
+++ b/runtime/observatory_2/lib/src/elements/heap_snapshot.dart
@@ -457,7 +457,7 @@
     for (var i = 0; i < worklist.length; i++) {
       worklist[i]._computeChildren(worklist);
     }
-    // Compute area botton-up.
+    // Compute area bottom-up.
     for (var i = worklist.length - 1; i >= 0; i--) {
       worklist[i]._computeArea();
     }
diff --git a/runtime/observatory_2/lib/src/elements/helpers/tag.dart b/runtime/observatory_2/lib/src/elements/helpers/tag.dart
index 342c521..7ff4120 100644
--- a/runtime/observatory_2/lib/src/elements/helpers/tag.dart
+++ b/runtime/observatory_2/lib/src/elements/helpers/tag.dart
@@ -90,7 +90,7 @@
   /// Tag name.
   final String name;
 
-  /// Dependent tags that need to be registred for this tag to work properly.
+  /// Dependent tags that need to be registered for this tag to work properly.
   final Iterable<Tag> dependencies;
 
   const Tag(this.name, {this.dependencies: const []});
diff --git a/runtime/observatory_2/lib/tracer.dart b/runtime/observatory_2/lib/tracer.dart
index 3a18cfd..5c15ecb 100644
--- a/runtime/observatory_2/lib/tracer.dart
+++ b/runtime/observatory_2/lib/tracer.dart
@@ -67,7 +67,7 @@
   // The start time for the current request.
   Stopwatch _time;
 
-  // A list of all tracing events for thre current request.
+  // A list of all tracing events for the current request.
   List<TraceEvent> events = <TraceEvent>[];
 
   Tracer() {
diff --git a/runtime/observatory_2/tests/service_2/string_escaping_test.dart b/runtime/observatory_2/tests/service_2/string_escaping_test.dart
index 4d48a3f..62a0b13 100644
--- a/runtime/observatory_2/tests/service_2/string_escaping_test.dart
+++ b/runtime/observatory_2/tests/service_2/string_escaping_test.dart
@@ -53,7 +53,7 @@
   nullInTheMiddle = "There are four\u0000 words.";
   escapedUnicodeEscape = "Should not be A: \\u0041";
 
-  // A surrogate pair will cross the preferred truncation boundry.
+  // A surrogate pair will cross the preferred truncation boundary.
   longStringEven = "..";
   for (int i = 0; i < 512; i++) longStringEven += "𝄞";
   longStringOdd = ".";
diff --git a/runtime/tests/vm/dart/flutter_regress_101514_test.dart b/runtime/tests/vm/dart/flutter_regress_101514_test.dart
index 6c78710..2f63fa7 100644
--- a/runtime/tests/vm/dart/flutter_regress_101514_test.dart
+++ b/runtime/tests/vm/dart/flutter_regress_101514_test.dart
@@ -13,7 +13,7 @@
 }
 
 Stream<int> foo() async* {
-  // While the generator (i.e. this funtion) runs, we cancel the consumer and
+  // While the generator (i.e. this function) runs, we cancel the consumer and
   // try to yield more.
   sub.cancel();
   yield* Stream.fromIterable([1, 2, 3]);
diff --git a/runtime/tests/vm/dart/isolates/fast_object_copy_test.dart b/runtime/tests/vm/dart/isolates/fast_object_copy_test.dart
index 22bf3ac..955c5b2 100644
--- a/runtime/tests/vm/dart/isolates/fast_object_copy_test.dart
+++ b/runtime/tests/vm/dart/isolates/fast_object_copy_test.dart
@@ -725,10 +725,10 @@
 
     {
       final result = await sendReceive([
-        weakRef1, // Does not have its target inluded.
+        weakRef1, // Does not have its target included.
         weakRef2, // Has its target included later than itself.
         object2,
-        weakRef3, // Does not have its target inluded.
+        weakRef3, // Does not have its target included.
         expando3,
         weakRef4, // Has its target included due to expando.
         expando4,
@@ -747,11 +747,11 @@
 
     {
       final result = await sendReceive([
-        weakRef1, // Does not have its target inluded.
+        weakRef1, // Does not have its target included.
         weakRef2, // Has its target included later than itself.
         notAllocatableInTLAB,
         object2,
-        weakRef3, // Does not have its target inluded.
+        weakRef3, // Does not have its target included.
         expando3,
         weakRef4, // Has its target included due to expando.
         expando4,
diff --git a/runtime/tests/vm/dart/licm_and_assert_strengthening_test.dart b/runtime/tests/vm/dart/licm_and_assert_strengthening_test.dart
index a1c962e..a52194b 100644
--- a/runtime/tests/vm/dart/licm_and_assert_strengthening_test.dart
+++ b/runtime/tests/vm/dart/licm_and_assert_strengthening_test.dart
@@ -19,7 +19,7 @@
 class C extends B {}
 
 void foo(dynamic a) {
-  // To prevent AssertAssignable strengthening from occuring too early we
+  // To prevent AssertAssignable strengthening from occurring too early we
   // need to hide the fact that CheckClass and AssertAssignable are performed
   // against the same SSA value. To achieve that we store a into an array and
   // then load it back. Load Forwarding would happen just before LICM and
diff --git a/runtime/tests/vm/dart/readonly_data_symbols_test.dart b/runtime/tests/vm/dart/readonly_data_symbols_test.dart
new file mode 100644
index 0000000..3ccad9b
--- /dev/null
+++ b/runtime/tests/vm/dart/readonly_data_symbols_test.dart
@@ -0,0 +1,115 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This test checks that gen_snapshot outputs static symbols for read-only
+// data objects.
+
+// OtherResources=use_save_debugging_info_flag_program.dart
+
+import "dart:async";
+import "dart:io";
+
+import 'package:expect/expect.dart';
+import 'package:native_stack_traces/elf.dart';
+import 'package:path/path.dart' as path;
+
+import 'use_flag_test_helper.dart';
+
+main(List<String> args) async {
+  if (!isAOTRuntime) {
+    return; // Running in JIT: AOT binaries not available.
+  }
+
+  if (Platform.isAndroid) {
+    return; // SDK tree and dart_bootstrap not available on the test device.
+  }
+
+  // These are the tools we need to be available to run on a given platform:
+  if (!await testExecutable(genSnapshot)) {
+    throw "Cannot run test as $genSnapshot not available";
+  }
+  if (!await testExecutable(aotRuntime)) {
+    throw "Cannot run test as $aotRuntime not available";
+  }
+  if (!File(platformDill).existsSync()) {
+    throw "Cannot run test as $platformDill does not exist";
+  }
+
+  await withTempDir('readonly-symbols-flag-test', (String tempDir) async {
+    final cwDir = path.dirname(Platform.script.toFilePath());
+    final script =
+        path.join(cwDir, 'use_save_debugging_info_flag_program.dart');
+    final scriptDill = path.join(tempDir, 'flag_program.dill');
+
+    // Compile script to Kernel IR.
+    await run(genKernel, <String>[
+      '--aot',
+      '--platform=$platformDill',
+      '-o',
+      scriptDill,
+      script,
+    ]);
+
+    final scriptSnapshot = path.join(tempDir, 'dwarf.so');
+    final scriptDebuggingInfo = path.join(tempDir, 'debug_info.so');
+    await run(genSnapshot, <String>[
+      '--dwarf-stack-traces-mode',
+      '--save-debugging-info=$scriptDebuggingInfo',
+      '--snapshot-kind=app-aot-elf',
+      '--elf=$scriptSnapshot',
+      scriptDill,
+    ]);
+
+    checkElf(scriptSnapshot);
+    checkElf(scriptDebuggingInfo);
+  });
+}
+
+void checkElf(String filename) {
+  // Check that the static symbol table contains entries that are not in the
+  // dynamic symbol table, have STB_LOCAL binding, and are of type STT_OBJECT.
+  final elf = Elf.fromFile(filename);
+  Expect.isNotNull(elf);
+  final dynamicSymbols = elf!.dynamicSymbols.toList();
+  for (final symbol in dynamicSymbols) {
+    // All symbol tables have an initial entry with zero-valued fields.
+    if (symbol.name == '') {
+      Expect.equals(SymbolBinding.STB_LOCAL, symbol.bind);
+      Expect.equals(SymbolType.STT_NOTYPE, symbol.type);
+      Expect.equals(0, symbol.value);
+    } else {
+      Expect.equals(SymbolBinding.STB_GLOBAL, symbol.bind);
+      Expect.equals(SymbolType.STT_OBJECT, symbol.type);
+      Expect.isTrue(symbol.name.startsWith('_kDart'),
+          'unexpected symbol name ${symbol.name}');
+    }
+  }
+  final onlyStaticSymbols = elf.staticSymbols
+      .where((s1) => !dynamicSymbols.any((s2) => s1.name == s2.name));
+  Expect.isNotEmpty(onlyStaticSymbols, 'no static-only symbols');
+  final objectSymbols =
+      onlyStaticSymbols.where((s) => s.type == SymbolType.STT_OBJECT);
+  Expect.isNotEmpty(objectSymbols, 'no static-only object symbols');
+  for (final symbol in objectSymbols) {
+    // Currently we only write local object symbols.
+    Expect.equals(SymbolBinding.STB_LOCAL, symbol.bind);
+    // All object symbols are prefixed with the type of the C++ object.
+    final objectType = symbol.name.substring(0, symbol.name.indexOf('_'));
+    switch (objectType) {
+      // Used for entries in the non-clustered portion of the read-only data
+      // section that don't correspond to a specific Dart object.
+      case 'RawBytes':
+      // Currently the only types of objects written to the non-clustered
+      // portion of the read-only data section.
+      case 'OneByteString':
+      case 'TwoByteString':
+      case 'CodeSourceMap':
+      case 'PcDescriptors':
+      case 'CompressedStackMaps':
+        break;
+      default:
+        Expect.fail('unexpected object type $objectType');
+    }
+  }
+}
diff --git a/runtime/tests/vm/dart/regress_lsl_with_constant_test.dart b/runtime/tests/vm/dart/regress_lsl_with_constant_test.dart
index 368a98b..622bb1b 100644
--- a/runtime/tests/vm/dart/regress_lsl_with_constant_test.dart
+++ b/runtime/tests/vm/dart/regress_lsl_with_constant_test.dart
@@ -13,7 +13,7 @@
 
 @pragma('vm:never-inline')
 void test(Int32List v) {
-  // The shape of the code here is choosen to trigger Int64->Int32
+  // The shape of the code here is chosen to trigger Int64->Int32
   // narrowing in the range analysis.
   v[0] = (v[0] & 0xFF) << (N - 1);
 }
diff --git a/runtime/tests/vm/dart/tts_regression39716_test.dart b/runtime/tests/vm/dart/tts_regression39716_test.dart
index 782f3fa..9683b51 100644
--- a/runtime/tests/vm/dart/tts_regression39716_test.dart
+++ b/runtime/tests/vm/dart/tts_regression39716_test.dart
@@ -14,7 +14,7 @@
   // `A`, both have type argument vector at a different offset, so it wouldn't
   // know where to load it from)
 
-  // Populate the SubtypeTestCache with successfull `add(I<String>())`.
+  // Populate the SubtypeTestCache with successful `add(I<String>())`.
   final x = <dynamic>[<A<String>>[]];
   x.single.add(I<String>());
 
diff --git a/runtime/tests/vm/dart_2/flutter_regress_101514_test.dart b/runtime/tests/vm/dart_2/flutter_regress_101514_test.dart
index 44d029a..177a2a4 100644
--- a/runtime/tests/vm/dart_2/flutter_regress_101514_test.dart
+++ b/runtime/tests/vm/dart_2/flutter_regress_101514_test.dart
@@ -15,7 +15,7 @@
 }
 
 Stream<int> foo() async* {
-  // While the generator (i.e. this funtion) runs, we cancel the consumer and
+  // While the generator (i.e. this function) runs, we cancel the consumer and
   // try to yield more.
   sub.cancel();
   yield* Stream.fromIterable([1, 2, 3]);
diff --git a/runtime/tests/vm/dart_2/isolates/fast_object_copy_test.dart b/runtime/tests/vm/dart_2/isolates/fast_object_copy_test.dart
index 1e3773d..58343a9 100644
--- a/runtime/tests/vm/dart_2/isolates/fast_object_copy_test.dart
+++ b/runtime/tests/vm/dart_2/isolates/fast_object_copy_test.dart
@@ -727,10 +727,10 @@
 
     {
       final result = await sendReceive([
-        weakRef1, // Does not have its target inluded.
+        weakRef1, // Does not have its target included.
         weakRef2, // Has its target included later than itself.
         object2,
-        weakRef3, // Does not have its target inluded.
+        weakRef3, // Does not have its target included.
         expando3,
         weakRef4, // Has its target included due to expando.
         expando4,
@@ -749,11 +749,11 @@
 
     {
       final result = await sendReceive([
-        weakRef1, // Does not have its target inluded.
+        weakRef1, // Does not have its target included.
         weakRef2, // Has its target included later than itself.
         notAllocatableInTLAB,
         object2,
-        weakRef3, // Does not have its target inluded.
+        weakRef3, // Does not have its target included.
         expando3,
         weakRef4, // Has its target included due to expando.
         expando4,
diff --git a/runtime/tests/vm/dart_2/licm_and_assert_strengthening_test.dart b/runtime/tests/vm/dart_2/licm_and_assert_strengthening_test.dart
index a3c26bf..de629a6 100644
--- a/runtime/tests/vm/dart_2/licm_and_assert_strengthening_test.dart
+++ b/runtime/tests/vm/dart_2/licm_and_assert_strengthening_test.dart
@@ -21,7 +21,7 @@
 class C extends B {}
 
 void foo(dynamic a) {
-  // To prevent AssertAssignable strengthening from occuring too early we
+  // To prevent AssertAssignable strengthening from occurring too early we
   // need to hide the fact that CheckClass and AssertAssignable are performed
   // against the same SSA value. To achieve that we store a into an array and
   // then load it back. Load Forwarding would happen just before LICM and
diff --git a/runtime/tests/vm/dart_2/readonly_data_symbols_test.dart b/runtime/tests/vm/dart_2/readonly_data_symbols_test.dart
new file mode 100644
index 0000000..c646840
--- /dev/null
+++ b/runtime/tests/vm/dart_2/readonly_data_symbols_test.dart
@@ -0,0 +1,117 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+// This test checks that gen_snapshot outputs static symbols for read-only data
+// objects.
+
+// OtherResources=use_save_debugging_info_flag_program.dart
+
+import "dart:async";
+import "dart:io";
+
+import 'package:expect/expect.dart';
+import 'package:native_stack_traces/elf.dart';
+import 'package:path/path.dart' as path;
+
+import 'use_flag_test_helper.dart';
+
+main(List<String> args) async {
+  if (!isAOTRuntime) {
+    return; // Running in JIT: AOT binaries not available.
+  }
+
+  if (Platform.isAndroid) {
+    return; // SDK tree and dart_bootstrap not available on the test device.
+  }
+
+  // These are the tools we need to be available to run on a given platform:
+  if (!await testExecutable(genSnapshot)) {
+    throw "Cannot run test as $genSnapshot not available";
+  }
+  if (!await testExecutable(aotRuntime)) {
+    throw "Cannot run test as $aotRuntime not available";
+  }
+  if (!File(platformDill).existsSync()) {
+    throw "Cannot run test as $platformDill does not exist";
+  }
+
+  await withTempDir('readonly-symbols-flag-test', (String tempDir) async {
+    final cwDir = path.dirname(Platform.script.toFilePath());
+    final script =
+        path.join(cwDir, 'use_save_debugging_info_flag_program.dart');
+    final scriptDill = path.join(tempDir, 'flag_program.dill');
+
+    // Compile script to Kernel IR.
+    await run(genKernel, <String>[
+      '--aot',
+      '--platform=$platformDill',
+      '-o',
+      scriptDill,
+      script,
+    ]);
+
+    final scriptSnapshot = path.join(tempDir, 'dwarf.so');
+    final scriptDebuggingInfo = path.join(tempDir, 'debug_info.so');
+    await run(genSnapshot, <String>[
+      '--dwarf-stack-traces-mode',
+      '--save-debugging-info=$scriptDebuggingInfo',
+      '--snapshot-kind=app-aot-elf',
+      '--elf=$scriptSnapshot',
+      scriptDill,
+    ]);
+
+    checkElf(scriptSnapshot);
+    checkElf(scriptDebuggingInfo);
+  });
+}
+
+void checkElf(String filename) {
+  // Check that the static symbol table contains entries that are not in the
+  // dynamic symbol table, have STB_LOCAL binding, and are of type STT_OBJECT.
+  final elf = Elf.fromFile(filename);
+  Expect.isNotNull(elf);
+  final dynamicSymbols = elf.dynamicSymbols.toList();
+  for (final symbol in dynamicSymbols) {
+    // All symbol tables have an initial entry with zero-valued fields.
+    if (symbol.name == '') {
+      Expect.equals(SymbolBinding.STB_LOCAL, symbol.bind);
+      Expect.equals(SymbolType.STT_NOTYPE, symbol.type);
+      Expect.equals(0, symbol.value);
+    } else {
+      Expect.equals(SymbolBinding.STB_GLOBAL, symbol.bind);
+      Expect.equals(SymbolType.STT_OBJECT, symbol.type);
+      Expect.isTrue(symbol.name.startsWith('_kDart'),
+          'unexpected symbol name ${symbol.name}');
+    }
+  }
+  final onlyStaticSymbols = elf.staticSymbols
+      .where((s1) => !dynamicSymbols.any((s2) => s1.name == s2.name));
+  Expect.isNotEmpty(onlyStaticSymbols, 'no static-only symbols');
+  final objectSymbols =
+      onlyStaticSymbols.where((s) => s.type == SymbolType.STT_OBJECT);
+  Expect.isNotEmpty(objectSymbols, 'no static-only object symbols');
+  for (final symbol in objectSymbols) {
+    // Currently we only write local object symbols.
+    Expect.equals(SymbolBinding.STB_LOCAL, symbol.bind);
+    // All object symbols are prefixed with the type of the C++ object.
+    final objectType = symbol.name.substring(0, symbol.name.indexOf('_'));
+    switch (objectType) {
+      // Used for entries in the non-clustered portion of the read-only data
+      // section that don't correspond to a specific Dart object.
+      case 'RawBytes':
+      // Currently the only types of objects written to the non-clustered
+      // portion of the read-only data section.
+      case 'OneByteString':
+      case 'TwoByteString':
+      case 'CodeSourceMap':
+      case 'PcDescriptors':
+      case 'CompressedStackMaps':
+        break;
+      default:
+        Expect.fail('unexpected object type $objectType');
+    }
+  }
+}
diff --git a/runtime/tests/vm/dart_2/regress_lsl_with_constant_test.dart b/runtime/tests/vm/dart_2/regress_lsl_with_constant_test.dart
index 31d65f9..c08672e 100644
--- a/runtime/tests/vm/dart_2/regress_lsl_with_constant_test.dart
+++ b/runtime/tests/vm/dart_2/regress_lsl_with_constant_test.dart
@@ -15,7 +15,7 @@
 
 @pragma('vm:never-inline')
 void test(Int32List v) {
-  // The shape of the code here is choosen to trigger Int64->Int32
+  // The shape of the code here is chosen to trigger Int64->Int32
   // narrowing in the range analysis.
   v[0] = (v[0] & 0xFF) << (N - 1);
 }
diff --git a/runtime/tests/vm/dart_2/tts_regression39716_test.dart b/runtime/tests/vm/dart_2/tts_regression39716_test.dart
index a762f55..e8c8c83 100644
--- a/runtime/tests/vm/dart_2/tts_regression39716_test.dart
+++ b/runtime/tests/vm/dart_2/tts_regression39716_test.dart
@@ -16,7 +16,7 @@
   // `A`, both have type argument vector at a different offset, so it wouldn't
   // know where to load it from)
 
-  // Populate the SubtypeTestCache with successfull `add(I<String>())`.
+  // Populate the SubtypeTestCache with successful `add(I<String>())`.
   final x = <dynamic>[<A<String>>[]];
   x.single.add(I<String>());
 
diff --git a/runtime/tools/dartfuzz/dartfuzz_test.dart b/runtime/tools/dartfuzz/dartfuzz_test.dart
index 6cf216e..7f77a53 100644
--- a/runtime/tools/dartfuzz/dartfuzz_test.dart
+++ b/runtime/tools/dartfuzz/dartfuzz_test.dart
@@ -343,7 +343,10 @@
   bool ffiCapable(String mode1, String mode2) =>
       mode1.startsWith('jit') &&
       mode2.startsWith('jit') &&
-      (!mode1.contains('arm') && !mode2.contains('arm'));
+      !mode1.contains('arm') &&
+      !mode2.contains('arm') &&
+      !mode1.contains('riscv') &&
+      !mode2.contains('riscv');
 
   bool nestedTypesAllowed(String mode1, String mode2) =>
       (!mode1.contains('arm') && !mode2.contains('arm'));
diff --git a/runtime/vm/app_snapshot.cc b/runtime/vm/app_snapshot.cc
index dcf35fd..78cb595 100644
--- a/runtime/vm/app_snapshot.cc
+++ b/runtime/vm/app_snapshot.cc
@@ -7285,7 +7285,11 @@
 }
 
 uint32_t Serializer::GetDataOffset(ObjectPtr object) const {
+#if defined(SNAPSHOT_BACKTRACE)
+  return image_writer_->GetDataOffsetFor(object, ParentOf(object));
+#else
   return image_writer_->GetDataOffsetFor(object);
+#endif
 }
 
 intptr_t Serializer::GetDataSize() const {
@@ -7390,7 +7394,16 @@
 }
 
 #if defined(SNAPSHOT_BACKTRACE)
-ObjectPtr Serializer::ParentOf(const Object& object) {
+ObjectPtr Serializer::ParentOf(ObjectPtr object) const {
+  for (intptr_t i = 0; i < parent_pairs_.length(); i += 2) {
+    if (parent_pairs_[i]->ptr() == object) {
+      return parent_pairs_[i + 1]->ptr();
+    }
+  }
+  return Object::null();
+}
+
+ObjectPtr Serializer::ParentOf(const Object& object) const {
   for (intptr_t i = 0; i < parent_pairs_.length(); i += 2) {
     if (parent_pairs_[i]->ptr() == object.ptr()) {
       return parent_pairs_[i + 1]->ptr();
diff --git a/runtime/vm/app_snapshot.h b/runtime/vm/app_snapshot.h
index 922c8ac..3445cb4 100644
--- a/runtime/vm/app_snapshot.h
+++ b/runtime/vm/app_snapshot.h
@@ -19,10 +19,6 @@
 #include "vm/snapshot.h"
 #include "vm/version.h"
 
-#if defined(DEBUG)
-#define SNAPSHOT_BACKTRACE
-#endif
-
 namespace dart {
 
 // For full snapshots, we use a clustered snapshot format that trades longer
@@ -244,7 +240,8 @@
 
   void UnexpectedObject(ObjectPtr object, const char* message);
 #if defined(SNAPSHOT_BACKTRACE)
-  ObjectPtr ParentOf(const Object& object);
+  ObjectPtr ParentOf(ObjectPtr object) const;
+  ObjectPtr ParentOf(const Object& object) const;
 #endif
 
   SerializationCluster* NewClusterForClass(intptr_t cid, bool is_canonical);
diff --git a/runtime/vm/compiler/backend/constant_propagator.h b/runtime/vm/compiler/backend/constant_propagator.h
index f2a6929..0a5b00b 100644
--- a/runtime/vm/compiler/backend/constant_propagator.h
+++ b/runtime/vm/compiler/backend/constant_propagator.h
@@ -42,7 +42,7 @@
   void Analyze();
   void Transform();
   // Tries to replace uses of [defn] with a constant, returns true if
-  // successfull. The [value] is used as a temporary handle.
+  // successful. The [value] is used as a temporary handle.
   bool TransformDefinition(Definition* defn);
   void EliminateRedundantBranches();
 
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index b5f2e3e..c025d2d 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -1014,7 +1014,7 @@
 }
 
 Instruction* AssertSubtypeInstr::Canonicalize(FlowGraph* flow_graph) {
-  // If all inputs needed to check instantation are constant, instantiate the
+  // If all inputs needed to check instantiation are constant, instantiate the
   // sub and super type and remove the instruction if the subtype test succeeds.
   if (super_type()->BindsToConstant() && sub_type()->BindsToConstant() &&
       instantiator_type_arguments()->BindsToConstant() &&
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 01a552f..5230ed8 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -9553,8 +9553,7 @@
     JSONArray jstream(&obj, "available");
     Timeline::PrintFlagsToJSONArray(&jstream);
     const char* js_str = js.ToCString();
-#define TIMELINE_STREAM_CHECK(name, fuchsia_name)                              \
-  EXPECT_SUBSTRING(#name, js_str);
+#define TIMELINE_STREAM_CHECK(name, ...) EXPECT_SUBSTRING(#name, js_str);
     TIMELINE_STREAM_LIST(TIMELINE_STREAM_CHECK)
 #undef TIMELINE_STREAM_CHECK
   }
diff --git a/runtime/vm/heap/compactor.cc b/runtime/vm/heap/compactor.cc
index e5a5c3e..9afb2d7 100644
--- a/runtime/vm/heap/compactor.cc
+++ b/runtime/vm/heap/compactor.cc
@@ -51,7 +51,7 @@
   // Marks a range of allocation units belonging to an object live by setting
   // the corresponding bits in this ForwardingBlock.  Does not update the
   // new_address_ field; that is done after the total live size of the block is
-  // known and forwarding location is choosen. Does not mark words in subsequent
+  // known and forwarding location is chosen. Does not mark words in subsequent
   // ForwardingBlocks live for objects that extend into the next block.
   void RecordLive(uword old_addr, intptr_t size) {
     intptr_t size_in_units = size >> kObjectAlignmentLog2;
diff --git a/runtime/vm/heap/marker.cc b/runtime/vm/heap/marker.cc
index 3629c5f..29bf3ed 100644
--- a/runtime/vm/heap/marker.cc
+++ b/runtime/vm/heap/marker.cc
@@ -94,7 +94,7 @@
     // by a conservative estimate of the duration of one batch of work.
     deadline -= 1500;
 
-    // A 512kB budget is choosen to be large enough that we don't waste too much
+    // A 512kB budget is chosen to be large enough that we don't waste too much
     // time on the overhead of exiting ProcessMarkingStack, querying the clock,
     // and re-entering, and small enough that a few batches can fit in the idle
     // time between animation frames. This amount of marking takes ~1ms on a
diff --git a/runtime/vm/image_snapshot.cc b/runtime/vm/image_snapshot.cc
index 8115931..508fb3e4 100644
--- a/runtime/vm/image_snapshot.cc
+++ b/runtime/vm/image_snapshot.cc
@@ -179,6 +179,9 @@
       next_text_offset_(0),
       objects_(),
       instructions_(),
+#if defined(DART_PRECOMPILER)
+      namer_(t->zone()),
+#endif
       image_type_(TagObjectTypeAsReadOnly(zone_, "Image")),
       instructions_section_type_(
           TagObjectTypeAsReadOnly(zone_, "InstructionsSection")),
@@ -286,11 +289,20 @@
   }
 }
 
+#if defined(SNAPSHOT_BACKTRACE)
+uint32_t ImageWriter::GetDataOffsetFor(ObjectPtr raw_object,
+                                       ObjectPtr raw_parent) {
+#else
 uint32_t ImageWriter::GetDataOffsetFor(ObjectPtr raw_object) {
+#endif
   const intptr_t snap_size = SizeInSnapshot(raw_object);
   const intptr_t offset = next_data_offset_;
   next_data_offset_ += snap_size;
+#if defined(SNAPSHOT_BACKTRACE)
+  objects_.Add(ObjectData(raw_object, raw_parent));
+#else
   objects_.Add(ObjectData(raw_object));
+#endif
   return offset;
 }
 
@@ -455,8 +467,11 @@
     heap->SetObjectId(data.insns_->ptr(), 0);
   }
   for (auto& data : objects_) {
-    if (data.is_object) {
+    if (data.is_object()) {
       data.obj = &Object::Handle(zone_, data.raw_obj);
+#if defined(SNAPSHOT_BACKTRACE)
+      data.parent = &Object::Handle(zone_, data.raw_parent);
+#endif
     }
   }
 
@@ -464,11 +479,14 @@
   // to string objects. String is used for simplicity as a bit container,
   // can't use TypedData because it has an internal pointer (data_) field.
   for (auto& data : objects_) {
-    if (!data.is_object) {
+    if (!data.is_object()) {
       const auto bytes = data.bytes;
       data.obj = &Object::Handle(
           zone_, OneByteString::New(bytes.buf, bytes.length, Heap::kOld));
-      data.is_object = true;
+#if defined(SNAPSHOT_BACKTRACE)
+      data.parent = &Object::null_object();
+#endif
+      data.set_is_object(true);
       String::Cast(*data.obj).Hash();
       free(bytes.buf);
     }
@@ -489,13 +507,8 @@
 }
 
 void ImageWriter::WriteROData(NonStreamingWriteStream* stream, bool vm) {
-#if defined(DART_PRECOMPILER)
-  const intptr_t start_position = stream->Position();
-#endif
-  stream->Align(ImageWriter::kRODataAlignment);
-
+  ASSERT(Utils::IsAligned(stream->Position(), kRODataAlignment));
   // Heap page starts here.
-
   intptr_t section_start = stream->Position();
 
   stream->WriteWord(next_data_offset_);  // Data length.
@@ -505,20 +518,20 @@
   ASSERT_EQUAL(stream->Position() - section_start, Image::kHeaderSize);
 #if defined(DART_PRECOMPILER)
   if (profile_writer_ != nullptr) {
-    const intptr_t end_position = stream->Position();
+    // Attribute the Image header to the artificial root.
     profile_writer_->AttributeBytesTo(
-        V8SnapshotProfileWriter::kArtificialRootId,
-        end_position - start_position);
+        V8SnapshotProfileWriter::kArtificialRootId, Image::kHeaderSize);
   }
 #endif
 
   // Heap page objects start here.
 
   for (auto entry : objects_) {
-    ASSERT(entry.is_object);
+    ASSERT(entry.is_object());
     const Object& obj = *entry.obj;
 #if defined(DART_PRECOMPILER)
     AutoTraceImage(obj, section_start, stream);
+    const char* object_name = namer_.SnapshotNameFor(entry);
 #endif
     auto const object_start = stream->Position();
 
@@ -568,6 +581,9 @@
     }
     stream->Align(compiler::target::ObjectAlignment::kObjectAlignment);
     ASSERT_EQUAL(stream->Position() - object_start, SizeInSnapshot(obj));
+#if defined(DART_PRECOMPILER)
+    AddDataSymbol(object_name, object_start, stream->Position() - object_start);
+#endif
   }
 }
 
@@ -772,7 +788,6 @@
 
 #if defined(DART_PRECOMPILER)
   PcDescriptors& descriptors = PcDescriptors::Handle(zone_);
-  SnapshotTextObjectNamer namer(zone_);
 #endif
 
   ASSERT(offset_space_ != IdSpace::kSnapshot);
@@ -782,10 +797,7 @@
     ASSERT_EQUAL(data.text_offset_, text_offset);
 
 #if defined(DART_PRECOMPILER)
-    // We won't add trampolines as symbols, so their name need not be unique
-    // across different WriteText() calls.
-    const char* object_name = namer.SnapshotNameFor(
-        is_trampoline ? i : unique_symbol_counter_++, data);
+    const char* object_name = namer_.SnapshotNameFor(data);
 
     if (profile_writer_ != nullptr) {
       const V8SnapshotProfileWriter::ObjectId id(offset_space_, text_offset);
@@ -1106,7 +1118,7 @@
   }
 }
 
-static void AddAssemblerIdentifier(ZoneTextBuffer* printer, const char* label) {
+static void AddAssemblerIdentifier(BaseTextBuffer* printer, const char* label) {
   ASSERT(label[0] != '.');
   if (label[0] == 'L' && printer->length() == 0) {
     // Assembler treats labels starting with `L` as local which can cause
@@ -1159,47 +1171,89 @@
   }
 }
 
-const char* SnapshotTextObjectNamer::SnapshotNameFor(intptr_t code_index,
-                                                     const Code& code) {
-  ASSERT(!code.IsNull());
-  owner_ = code.owner();
-  if (owner_.IsNull()) {
-    insns_ = code.instructions();
-    const char* name = StubCode::NameOfStub(insns_.EntryPoint());
-    ASSERT(name != nullptr);
-    return OS::SCreate(zone_, "Stub_%s", name);
-  }
-  // The weak reference to the Code's owner should never have been removed via
-  // an intermediate serialization, since WSRs are only introduced during
-  // precompilation.
-  owner_ = WeakSerializationReference::Unwrap(owner_);
-  ASSERT(!owner_.IsNull());
-  ZoneTextBuffer printer(zone_);
-  if (owner_.IsClass()) {
-    const char* name = Class::Cast(owner_).ScrubbedNameCString();
-    printer.AddString("AllocationStub_");
-    AddAssemblerIdentifier(&printer, name);
-  } else if (owner_.IsAbstractType()) {
-    const char* name = namer_.StubNameForType(AbstractType::Cast(owner_));
-    printer.AddString(name);
-  } else if (owner_.IsFunction()) {
-    const char* name = Function::Cast(owner_).QualifiedScrubbedNameCString();
-    AddAssemblerIdentifier(&printer, name);
+void ImageWriter::SnapshotTextObjectNamer::AddNonUniqueNameFor(
+    BaseTextBuffer* buffer,
+    const Object& object) {
+  if (object.IsCode()) {
+    const Code& code = Code::Cast(object);
+    owner_ = WeakSerializationReference::Unwrap(code.owner());
+    if (owner_.IsNull()) {
+      buffer->AddString("Stub_");
+      insns_ = code.instructions();
+      const char* name = StubCode::NameOfStub(insns_.EntryPoint());
+      ASSERT(name != nullptr);
+      buffer->AddString(name);
+    } else {
+      if (owner_.IsClass()) {
+        buffer->AddString("AllocationStub_");
+      } else if (!owner_.IsAbstractType() && !owner_.IsFunction()) {
+        // Double-check that we didn't get an invalid owner for the Code object.
+        UNREACHABLE();
+      }
+      AddNonUniqueNameFor(buffer, owner_);
+    }
+  } else if (object.IsClass()) {
+    const char* name = Class::Cast(object).ScrubbedNameCString();
+    AddAssemblerIdentifier(buffer, name);
+  } else if (object.IsAbstractType()) {
+    namer_.WriteStubNameForTypeTo(buffer, AbstractType::Cast(object));
+  } else if (object.IsFunction()) {
+    const char* name = Function::Cast(object).QualifiedScrubbedNameCString();
+    AddAssemblerIdentifier(buffer, name);
+  } else if (object.IsCompressedStackMaps()) {
+    buffer->AddString("CompressedStackMaps");
+  } else if (object.IsPcDescriptors()) {
+    buffer->AddString("PcDescriptors");
+  } else if (object.IsCodeSourceMap()) {
+    buffer->AddString("CodeSourceMap");
+  } else if (object.IsString()) {
+    const String& str = String::Cast(object);
+    if (str.IsOneByteString()) {
+      buffer->AddString("OneByteString");
+    } else if (str.IsTwoByteString()) {
+      buffer->AddString("TwoByteString");
+    }
   } else {
     UNREACHABLE();
   }
+}
 
-  printer.Printf("_%" Pd, code_index);
+const char* ImageWriter::SnapshotTextObjectNamer::SnapshotNameFor(
+    const InstructionsData& data) {
+  ZoneTextBuffer printer(zone_);
+  if (data.trampoline_bytes != nullptr) {
+    printer.AddString("Trampoline");
+  } else {
+    AddNonUniqueNameFor(&printer, *data.code_);
+  }
+  printer.Printf("_%" Pd, nonce_++);
   return printer.buffer();
 }
 
-const char* SnapshotTextObjectNamer::SnapshotNameFor(
-    intptr_t index,
-    const ImageWriter::InstructionsData& data) {
-  if (data.trampoline_bytes != nullptr) {
-    return OS::SCreate(zone_, "Trampoline_%" Pd "", index);
+const char* ImageWriter::SnapshotTextObjectNamer::SnapshotNameFor(
+    const ObjectData& data) {
+  ASSERT(data.is_object());
+  ZoneTextBuffer printer(zone_);
+  if (data.is_original_object()) {
+    const Object& obj = *data.obj;
+    AddNonUniqueNameFor(&printer, obj);
+#if defined(SNAPSHOT_BACKTRACE)
+    // It's less useful knowing the parent of a String than other read-only
+    // data objects, and this avoids us having to handle other classes
+    // in AddNonUniqueNameFor.
+    if (!obj.IsString()) {
+      const Object& parent = *data.parent;
+      if (!parent.IsNull()) {
+        printer.AddString("_");
+        AddNonUniqueNameFor(&printer, parent);
+      }
+    }
+#endif
+  } else {
+    printer.AddString("RawBytes");
   }
-  return SnapshotNameFor(index, *data.code_);
+  printer.Printf("_%" Pd, nonce_++);
+  return printer.buffer();
 }
 
 void AssemblyImageWriter::WriteBss(bool vm) {
@@ -1215,12 +1269,35 @@
 
 void AssemblyImageWriter::WriteROData(NonStreamingWriteStream* clustered_stream,
                                       bool vm) {
-  ImageWriter::WriteROData(clustered_stream, vm);
   if (!EnterSection(ProgramSection::Data, vm, ImageWriter::kRODataAlignment)) {
     return;
   }
-  WriteBytes(clustered_stream->buffer(), clustered_stream->bytes_written());
-  ExitSection(ProgramSection::Data, vm, clustered_stream->bytes_written());
+  // The clustered stream already has some data on it from the serializer, so
+  // make sure that the read-only objects start at the appropriate alignment
+  // within the stream, as we'll write the entire clustered stream to the
+  // assembly output (which was aligned in EnterSection).
+  const intptr_t start_position = clustered_stream->Position();
+  clustered_stream->Align(ImageWriter::kRODataAlignment);
+  if (profile_writer_ != nullptr) {
+    // Attribute any padding needed to the artificial root.
+    const intptr_t padding = clustered_stream->Position() - start_position;
+    profile_writer_->AttributeBytesTo(
+        V8SnapshotProfileWriter::kArtificialRootId, padding);
+  }
+  // First write the read-only data objects to the clustered stream.
+  ImageWriter::WriteROData(clustered_stream, vm);
+  // Next, write the bytes of the clustered stream (along with any symbols
+  // if appropriate) to the assembly output.
+  const uint8_t* bytes = clustered_stream->buffer();
+  const intptr_t len = clustered_stream->bytes_written();
+  intptr_t last_position = 0;
+  for (const auto& symbol : *current_symbols_) {
+    WriteBytes(bytes + last_position, symbol.offset - last_position);
+    assembly_stream_->Printf("%s:\n", symbol.name);
+    last_position = symbol.offset;
+  }
+  WriteBytes(bytes + last_position, len - last_position);
+  ExitSection(ProgramSection::Data, vm, len);
 }
 
 bool AssemblyImageWriter::EnterSection(ProgramSection section,
@@ -1240,10 +1317,14 @@
       global_symbol = true;
       break;
     case ProgramSection::Data:
-      if (debug_elf_ != nullptr) {
-        current_symbols_ =
-            new (zone_) ZoneGrowableArray<Elf::SymbolData>(zone_, 0);
-      }
+      // We create a SymbolData array even if there is no debug_elf_ because we
+      // may be writing RO data symbols, and RO data is written in two steps:
+      // 1. Serializing the read-only data objects to the clustered stream
+      // 2. Writing the bytes of the clustered stream to the assembly output.
+      // Thus, we'll need to interleave the symbols with the cluster bytes
+      // during step 2.
+      current_symbols_ =
+          new (zone_) ZoneGrowableArray<Elf::SymbolData>(zone_, 0);
 #if defined(DART_TARGET_OS_LINUX) || defined(DART_TARGET_OS_ANDROID) ||        \
     defined(DART_TARGET_OS_FUCHSIA)
       assembly_stream_->WriteString(".section .rodata\n");
@@ -1381,6 +1462,12 @@
   assembly_stream_->Printf("%s:\n", symbol);
 }
 
+void AssemblyImageWriter::AddDataSymbol(const char* symbol,
+                                        intptr_t offset,
+                                        size_t size) {
+  current_symbols_->Add({symbol, elf::STT_OBJECT, offset, size});
+}
+
 void AssemblyImageWriter::FrameUnwindPrologue() {
   // Creates DWARF's .debug_frame
   // CFI = Call frame information
@@ -1504,11 +1591,22 @@
 
 void BlobImageWriter::WriteROData(NonStreamingWriteStream* clustered_stream,
                                   bool vm) {
-  ImageWriter::WriteROData(clustered_stream, vm);
-  current_section_stream_ = clustered_stream;
+#if defined(DART_PRECOMPILER)
+  const intptr_t start_position = clustered_stream->Position();
+#endif
+  current_section_stream_ = ASSERT_NOTNULL(clustered_stream);
   if (!EnterSection(ProgramSection::Data, vm, ImageWriter::kRODataAlignment)) {
     return;
   }
+#if defined(DART_PRECOMPILER)
+  if (profile_writer_ != nullptr) {
+    // Attribute any padding needed to the artificial root.
+    const intptr_t padding = clustered_stream->Position() - start_position;
+    profile_writer_->AttributeBytesTo(
+        V8SnapshotProfileWriter::kArtificialRootId, padding);
+  }
+#endif
+  ImageWriter::WriteROData(clustered_stream, vm);
   ExitSection(ProgramSection::Data, vm, clustered_stream->bytes_written());
 }
 
@@ -1520,7 +1618,6 @@
   ASSERT(current_relocations_ == nullptr);
   ASSERT(current_symbols_ == nullptr);
 #endif
-  // For now, we set current_section_stream_ in ::WriteData.
   ASSERT(section == ProgramSection::Data || current_section_stream_ == nullptr);
   ASSERT(current_section_symbol_ == nullptr);
   switch (section) {
@@ -1535,6 +1632,8 @@
 #endif
       break;
     case ProgramSection::Data:
+      // The stream to use is passed into WriteROData and set there.
+      ASSERT(current_section_stream_ != nullptr);
 #if defined(DART_PRECOMPILER)
       current_relocations_ =
           new (zone_) ZoneGrowableArray<Elf::Relocation>(zone_, 0);
@@ -1614,6 +1713,12 @@
     debug_elf_->dwarf()->AddCode(code, symbol);
   }
 }
+
+void BlobImageWriter::AddDataSymbol(const char* symbol,
+                                    intptr_t offset,
+                                    size_t size) {
+  current_symbols_->Add({symbol, elf::STT_OBJECT, offset, size});
+}
 #endif  // defined(DART_PRECOMPILER)
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
diff --git a/runtime/vm/image_snapshot.h b/runtime/vm/image_snapshot.h
index 730b861..c1ce151 100644
--- a/runtime/vm/image_snapshot.h
+++ b/runtime/vm/image_snapshot.h
@@ -22,6 +22,10 @@
 #include "vm/type_testing_stubs.h"
 #include "vm/v8_snapshot_writer.h"
 
+#if defined(DEBUG)
+#define SNAPSHOT_BACKTRACE
+#endif
+
 namespace dart {
 
 // Forward declarations.
@@ -270,7 +274,11 @@
            offset_space_ == IdSpace::kIsolateText;
   }
   int32_t GetTextOffsetFor(InstructionsPtr instructions, CodePtr code);
+#if defined(SNAPSHOT_BACKTRACE)
+  uint32_t GetDataOffsetFor(ObjectPtr raw_object, ObjectPtr raw_parent);
+#else
   uint32_t GetDataOffsetFor(ObjectPtr raw_object);
+#endif
 
   uint32_t AddBytesToData(uint8_t* bytes, intptr_t length);
 
@@ -356,10 +364,27 @@
   };
 
   struct ObjectData {
-    explicit ObjectData(ObjectPtr raw_obj)
-        : raw_obj(raw_obj), is_object(true) {}
+#if defined(SNAPSHOT_BACKTRACE)
+    explicit ObjectData(ObjectPtr raw_obj, ObjectPtr raw_parent)
+        : raw_obj(raw_obj),
+          raw_parent(raw_parent),
+          flags(IsObjectField::encode(true) |
+                IsOriginalObjectField::encode(true)) {}
     ObjectData(uint8_t* buf, intptr_t length)
-        : bytes({buf, length}), is_object(false) {}
+        : bytes({buf, length}),
+          raw_parent(Object::null()),
+          flags(IsObjectField::encode(false) |
+                IsOriginalObjectField::encode(false)) {}
+#else
+    explicit ObjectData(ObjectPtr raw_obj)
+        : raw_obj(raw_obj),
+          flags(IsObjectField::encode(true) |
+                IsOriginalObjectField::encode(true)) {}
+    ObjectData(uint8_t* buf, intptr_t length)
+        : bytes({buf, length}),
+          flags(IsObjectField::encode(false) |
+                IsOriginalObjectField::encode(false)) {}
+#endif
 
     union {
       struct {
@@ -369,7 +394,26 @@
       ObjectPtr raw_obj;
       const Object* obj;
     };
-    bool is_object;
+#if defined(SNAPSHOT_BACKTRACE)
+    union {
+      ObjectPtr raw_parent;
+      const Object* parent;
+    };
+#endif
+    uint8_t flags;
+
+    bool is_object() const { return IsObjectField::decode(flags); }
+    bool is_original_object() const {
+      return IsOriginalObjectField::decode(flags);
+    }
+
+    void set_is_object(bool value) {
+      flags = IsObjectField::update(value, flags);
+    }
+
+    using IsObjectField = BitField<uint8_t, bool, 0, 1>;
+    using IsOriginalObjectField =
+        BitField<uint8_t, bool, IsObjectField::kNextBit, 1>;
   };
 
   // Methods abstracting out the particulars of the underlying concrete writer.
@@ -415,6 +459,10 @@
   virtual void AddCodeSymbol(const Code& code,
                              const char* symbol,
                              intptr_t section_offset) = 0;
+  // Creates a static symbol for a read-only data object when appropriate.
+  virtual void AddDataSymbol(const char* symbol,
+                             intptr_t section_offset,
+                             size_t size) = 0;
 
   // Overloaded convenience versions of the above virtual methods.
 
@@ -442,6 +490,47 @@
   GrowableArray<ObjectData> objects_;
   GrowableArray<InstructionsData> instructions_;
 
+#if defined(DART_PRECOMPILER)
+  class SnapshotTextObjectNamer : ValueObject {
+   public:
+    explicit SnapshotTextObjectNamer(Zone* zone)
+        : zone_(ASSERT_NOTNULL(zone)),
+          owner_(Object::Handle(zone)),
+          string_(String::Handle(zone)),
+          insns_(Instructions::Handle(zone)),
+          store_(IsolateGroup::Current()->object_store()) {}
+
+    const char* StubNameForType(const AbstractType& type) const;
+
+    // Returns a unique assembly-safe name for text data to use in symbols.
+    // Assumes that code in the InstructionsData has been allocated a handle.
+    const char* SnapshotNameFor(const InstructionsData& data);
+    // Returns a unique assembly-safe name for read-only data to use in symbols.
+    // Assumes that the ObjectData has already been converted to object handles.
+    const char* SnapshotNameFor(const ObjectData& data);
+
+   private:
+    // Returns a unique assembly-safe name for the given code or read-only
+    // data object for use in symbols.
+    const char* SnapshotNameFor(const Object& object);
+    // Adds a non-unique assembly-safe name for the given object to the given
+    // buffer.
+    void AddNonUniqueNameFor(BaseTextBuffer* buffer, const Object& object);
+
+    Zone* const zone_;
+    Object& owner_;
+    String& string_;
+    Instructions& insns_;
+    ObjectStore* const store_;
+    TypeTestingStubNamer namer_;
+    intptr_t nonce_ = 0;
+
+    DISALLOW_COPY_AND_ASSIGN(SnapshotTextObjectNamer);
+  };
+
+  SnapshotTextObjectNamer namer_;
+#endif
+
   IdSpace offset_space_ = IdSpace::kSnapshot;
   V8SnapshotProfileWriter* profile_writer_ = nullptr;
   const char* const image_type_;
@@ -449,12 +538,8 @@
   const char* const instructions_type_;
   const char* const trampoline_type_;
 
-  // Used to make sure Code symbols are unique across text sections.
-  intptr_t unique_symbol_counter_ = 0;
-
   template <class T>
   friend class TraceImageObjectScope;
-  friend class SnapshotTextObjectNamer;  // For InstructionsData.
 
  private:
   static intptr_t SizeInSnapshotForBytes(intptr_t length);
@@ -503,32 +588,6 @@
   DISALLOW_COPY_AND_ASSIGN(TraceImageObjectScope);
 };
 
-class SnapshotTextObjectNamer : ValueObject {
- public:
-  explicit SnapshotTextObjectNamer(Zone* zone)
-      : zone_(ASSERT_NOTNULL(zone)),
-        owner_(Object::Handle(zone)),
-        string_(String::Handle(zone)),
-        insns_(Instructions::Handle(zone)),
-        store_(IsolateGroup::Current()->object_store()) {}
-
-  const char* StubNameForType(const AbstractType& type) const;
-
-  const char* SnapshotNameFor(intptr_t code_index, const Code& code);
-  const char* SnapshotNameFor(intptr_t index,
-                              const ImageWriter::InstructionsData& data);
-
- private:
-  Zone* const zone_;
-  Object& owner_;
-  String& string_;
-  Instructions& insns_;
-  ObjectStore* const store_;
-  TypeTestingStubNamer namer_;
-
-  DISALLOW_COPY_AND_ASSIGN(SnapshotTextObjectNamer);
-};
-
 class AssemblyImageWriter : public ImageWriter {
  public:
   AssemblyImageWriter(Thread* thread,
@@ -563,6 +622,7 @@
   virtual void AddCodeSymbol(const Code& code,
                              const char* symbol,
                              intptr_t offset);
+  virtual void AddDataSymbol(const char* symbol, intptr_t offset, size_t size);
 
   BaseWriteStream* const assembly_stream_;
   Dwarf* const assembly_dwarf_;
@@ -571,8 +631,8 @@
   // Used in Relocation to output "(.)" for relocations involving the current
   // section position and creating local symbols in AddCodeSymbol.
   const char* current_section_symbol_ = nullptr;
-  // Used for creating local symbols for code objects in the debugging info,
-  // if separately written.
+  // Used for creating local symbols for code and data objects in the
+  // debugging info, if separately written.
   ZoneGrowableArray<Elf::SymbolData>* current_symbols_ = nullptr;
 
   DISALLOW_COPY_AND_ASSIGN(AssemblyImageWriter);
@@ -616,6 +676,7 @@
   virtual void AddCodeSymbol(const Code& code,
                              const char* symbol,
                              intptr_t offset);
+  virtual void AddDataSymbol(const char* symbol, intptr_t offset, size_t size);
 
   // Set on section entrance to a new array containing the relocations for the
   // current section.
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index a3c025d..3c6cc54 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -8070,7 +8070,7 @@
     kSizeInWords,
   };
 
-  // The array is terminated by the value kNoInstantiator occuring in place of
+  // The array is terminated by the value kNoInstantiator occurring in place of
   // the instantiator type args of the 4-tuple that would otherwise follow.
   // Therefore, kNoInstantiator must be distinct from any type arguments vector,
   // even a null one. Since arrays are initialized with 0, the instantiations_
@@ -8276,7 +8276,7 @@
   // type arguments, if any.
   void PrintName(NameVisibility visibility, BaseTextBuffer* printer) const;
 
-  // Add the class name and URI of each occuring type to the uris
+  // Add the class name and URI of each occurring type to the uris
   // list and mark ambiguous triplets to be printed.
   virtual void EnumerateURIs(URIs* uris) const;
 
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 85cf403..a455360 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -198,7 +198,7 @@
     intptr_t element_pos = 0;
 
     // Allocate our element array.  +1 for NULL terminator.
-    // The caller is reponsible for deleting this memory.
+    // The caller is responsible for deleting this memory.
     char** elements = new char*[element_count + 1];
     elements[element_count] = NULL;
 
@@ -296,7 +296,7 @@
 #if defined(SUPPORT_TIMELINE)
 static const char* const timeline_streams_enum_names[] = {
     "all",
-#define DEFINE_NAME(name, unused) #name,
+#define DEFINE_NAME(name, ...) #name,
     TIMELINE_STREAM_LIST(DEFINE_NAME)
 #undef DEFINE_NAME
         NULL};
@@ -328,7 +328,7 @@
     return false;
   }
 
-#define SET_ENABLE_STREAM(name, unused)                                        \
+#define SET_ENABLE_STREAM(name, ...)                                           \
   Timeline::SetStream##name##Enabled(HasStream(streams, #name));
   TIMELINE_STREAM_LIST(SET_ENABLE_STREAM);
 #undef SET_ENABLE_STREAM
diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc
index 90b0a23..f5140c6 100644
--- a/runtime/vm/timeline.cc
+++ b/runtime/vm/timeline.cc
@@ -202,7 +202,7 @@
   ASSERT(recorder_ != NULL);
   enabled_streams_ = GetEnabledByDefaultTimelineStreams();
 // Global overrides.
-#define TIMELINE_STREAM_FLAG_DEFAULT(name, fuchsia_name)                       \
+#define TIMELINE_STREAM_FLAG_DEFAULT(name, ...)                                \
   stream_##name##_.set_enabled(HasStream(enabled_streams_, #name));
   TIMELINE_STREAM_LIST(TIMELINE_STREAM_FLAG_DEFAULT)
 #undef TIMELINE_STREAM_FLAG_DEFAULT
@@ -218,7 +218,7 @@
 #endif
 
 // Disable global streams.
-#define TIMELINE_STREAM_DISABLE(name, fuchsia_name)                            \
+#define TIMELINE_STREAM_DISABLE(name, ...)                                     \
   Timeline::stream_##name##_.set_enabled(false);
   TIMELINE_STREAM_LIST(TIMELINE_STREAM_DISABLE)
 #undef TIMELINE_STREAM_DISABLE
@@ -265,7 +265,7 @@
 
 #ifndef PRODUCT
 void Timeline::PrintFlagsToJSONArray(JSONArray* arr) {
-#define ADD_RECORDED_STREAM_NAME(name, fuchsia_name)                           \
+#define ADD_RECORDED_STREAM_NAME(name, ...)                                    \
   if (stream_##name##_.enabled()) {                                            \
     arr->AddValue(#name);                                                      \
   }
@@ -285,13 +285,13 @@
   }
   {
     JSONArray availableStreams(&obj, "availableStreams");
-#define ADD_STREAM_NAME(name, fuchsia_name) availableStreams.AddValue(#name);
+#define ADD_STREAM_NAME(name, ...) availableStreams.AddValue(#name);
     TIMELINE_STREAM_LIST(ADD_STREAM_NAME);
 #undef ADD_STREAM_NAME
   }
   {
     JSONArray recordedStreams(&obj, "recordedStreams");
-#define ADD_RECORDED_STREAM_NAME(name, fuchsia_name)                           \
+#define ADD_RECORDED_STREAM_NAME(name, ...)                                    \
   if (stream_##name##_.enabled()) {                                            \
     recordedStreams.AddValue(#name);                                           \
   }
@@ -402,8 +402,9 @@
 MallocGrowableArray<char*>* Timeline::enabled_streams_ = NULL;
 bool Timeline::recorder_discards_clock_values_ = false;
 
-#define TIMELINE_STREAM_DEFINE(name, fuchsia_name)                             \
-  TimelineStream Timeline::stream_##name##_(#name, fuchsia_name, false);
+#define TIMELINE_STREAM_DEFINE(name, fuchsia_name, static_labels)              \
+  TimelineStream Timeline::stream_##name##_(#name, fuchsia_name,               \
+                                            static_labels, false);
 TIMELINE_STREAM_LIST(TIMELINE_STREAM_DEFINE)
 #undef TIMELINE_STREAM_DEFINE
 
@@ -774,6 +775,7 @@
 
 TimelineStream::TimelineStream(const char* name,
                                const char* fuchsia_name,
+                               bool has_static_labels,
                                bool enabled)
     : name_(name),
       fuchsia_name_(fuchsia_name),
@@ -786,6 +788,7 @@
 #if defined(DART_HOST_OS_MACOS)
   if (__builtin_available(iOS 12.0, macOS 10.14, *)) {
     macos_log_ = os_log_create("Dart", name);
+    has_static_labels_ = has_static_labels;
   }
 #endif
 }
diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h
index 7b89e4b..2d06a1e 100644
--- a/runtime/vm/timeline.h
+++ b/runtime/vm/timeline.h
@@ -57,23 +57,26 @@
 #define STARTUP_RECORDER_NAME "Startup"
 #define SYSTRACE_RECORDER_NAME "Systrace"
 
-// (name, fuchsia_name).
+// (name, fuchsia_name, has_static_labels).
 #define TIMELINE_STREAM_LIST(V)                                                \
-  V(API, "dart:api")                                                           \
-  V(Compiler, "dart:compiler")                                                 \
-  V(CompilerVerbose, "dart:compiler.verbose")                                  \
-  V(Dart, "dart:dart")                                                         \
-  V(Debugger, "dart:debugger")                                                 \
-  V(Embedder, "dart:embedder")                                                 \
-  V(GC, "dart:gc")                                                             \
-  V(Isolate, "dart:isolate")                                                   \
-  V(VM, "dart:vm")
+  V(API, "dart:api", true)                                                     \
+  V(Compiler, "dart:compiler", true)                                           \
+  V(CompilerVerbose, "dart:compiler.verbose", true)                            \
+  V(Dart, "dart:dart", false)                                                  \
+  V(Debugger, "dart:debugger", true)                                           \
+  V(Embedder, "dart:embedder", true)                                           \
+  V(GC, "dart:gc", true)                                                       \
+  V(Isolate, "dart:isolate", true)                                             \
+  V(VM, "dart:vm", true)
 
 // A stream of timeline events. A stream has a name and can be enabled or
 // disabled (globally and per isolate).
 class TimelineStream {
  public:
-  TimelineStream(const char* name, const char* fuchsia_name, bool enabled);
+  TimelineStream(const char* name,
+                 const char* fuchsia_name,
+                 bool static_labels,
+                 bool enabled);
 
   const char* name() const { return name_; }
   const char* fuchsia_name() const { return fuchsia_name_; }
@@ -105,7 +108,8 @@
 #if defined(DART_HOST_OS_FUCHSIA)
   trace_site_t* trace_site() { return &trace_site_; }
 #elif defined(DART_HOST_OS_MACOS)
-  os_log_t macos_log() { return macos_log_; }
+  os_log_t macos_log() const { return macos_log_; }
+  bool has_static_labels() const { return has_static_labels_; }
 #endif
 
  private:
@@ -120,6 +124,7 @@
   trace_site_t trace_site_ = {};
 #elif defined(DART_HOST_OS_MACOS)
   os_log_t macos_log_ = {};
+  bool has_static_labels_ = false;
 #endif
 };
 
@@ -196,12 +201,12 @@
   static void PrintFlagsToJSONArray(JSONArray* arr);
 #endif
 
-#define TIMELINE_STREAM_ACCESSOR(name, fuchsia_name)                           \
+#define TIMELINE_STREAM_ACCESSOR(name, ...)                                    \
   static TimelineStream* Get##name##Stream() { return &stream_##name##_; }
   TIMELINE_STREAM_LIST(TIMELINE_STREAM_ACCESSOR)
 #undef TIMELINE_STREAM_ACCESSOR
 
-#define TIMELINE_STREAM_FLAGS(name, fuchsia_name)                              \
+#define TIMELINE_STREAM_FLAGS(name, ...)                                       \
   static void SetStream##name##Enabled(bool enabled) {                         \
     stream_##name##_.set_enabled(enabled);                                     \
   }
@@ -216,7 +221,7 @@
   static MallocGrowableArray<char*>* enabled_streams_;
   static bool recorder_discards_clock_values_;
 
-#define TIMELINE_STREAM_DECLARE(name, fuchsia_name)                            \
+#define TIMELINE_STREAM_DECLARE(name, ...)                                     \
   static TimelineStream stream_##name##_;
   TIMELINE_STREAM_LIST(TIMELINE_STREAM_DECLARE)
 #undef TIMELINE_STREAM_DECLARE
diff --git a/runtime/vm/timeline_macos.cc b/runtime/vm/timeline_macos.cc
index d187617..55e0b24 100644
--- a/runtime/vm/timeline_macos.cc
+++ b/runtime/vm/timeline_macos.cc
@@ -30,39 +30,45 @@
   }
 
   const char* label = event->label();
+  bool is_static_label = event->stream_->has_static_labels();
   uint8_t _Alignas(16) buffer[64];
   buffer[0] = 0;
 
   switch (event->event_type()) {
-    case TimelineEvent::kInstant: {
-      _os_signpost_emit_with_name_impl(&__dso_handle, log, OS_SIGNPOST_EVENT,
-                                       OS_SIGNPOST_ID_EXCLUSIVE, label, "",
-                                       buffer, sizeof(buffer));
+    case TimelineEvent::kInstant:
+      if (is_static_label) {
+        _os_signpost_emit_with_name_impl(&__dso_handle, log, OS_SIGNPOST_EVENT,
+                                         OS_SIGNPOST_ID_EXCLUSIVE, label, "",
+                                         buffer, sizeof(buffer));
+      } else {
+        os_signpost_event_emit(log, OS_SIGNPOST_ID_EXCLUSIVE, "Event", "%s",
+                               label);
+      }
       break;
-    }
     case TimelineEvent::kBegin:
-    case TimelineEvent::kAsyncBegin: {
-      _os_signpost_emit_with_name_impl(&__dso_handle, log,
-                                       OS_SIGNPOST_INTERVAL_BEGIN, event->Id(),
-                                       label, "", buffer, sizeof(buffer));
+    case TimelineEvent::kAsyncBegin:
+      if (is_static_label) {
+        _os_signpost_emit_with_name_impl(
+            &__dso_handle, log, OS_SIGNPOST_INTERVAL_BEGIN, event->Id(), label,
+            "", buffer, sizeof(buffer));
+      } else {
+        os_signpost_interval_begin(log, event->Id(), "Event", "%s", label);
+      }
       break;
-    }
     case TimelineEvent::kEnd:
-    case TimelineEvent::kAsyncEnd: {
-      _os_signpost_emit_with_name_impl(&__dso_handle, log,
-                                       OS_SIGNPOST_INTERVAL_END, event->Id(),
-                                       label, "", buffer, sizeof(buffer));
+    case TimelineEvent::kAsyncEnd:
+      if (is_static_label) {
+        _os_signpost_emit_with_name_impl(&__dso_handle, log,
+                                         OS_SIGNPOST_INTERVAL_END, event->Id(),
+                                         label, "", buffer, sizeof(buffer));
+      } else {
+        os_signpost_interval_end(log, event->Id(), "Event");
+      }
       break;
-    }
-    case TimelineEvent::kCounter: {
-      const char* fmt = "%s";
-      Utils::SNPrint(reinterpret_cast<char*>(buffer), sizeof(buffer), fmt,
-                     event->arguments()[0].value);
-      _os_signpost_emit_with_name_impl(&__dso_handle, log, OS_SIGNPOST_EVENT,
-                                       OS_SIGNPOST_ID_EXCLUSIVE, label, fmt,
-                                       buffer, sizeof(buffer));
+    case TimelineEvent::kCounter:
+      os_signpost_event_emit(log, OS_SIGNPOST_ID_EXCLUSIVE, "Counter", "%s=%s",
+                             label, event->arguments()[0].value);
       break;
-    }
     default:
       break;
   }
diff --git a/runtime/vm/timeline_test.cc b/runtime/vm/timeline_test.cc
index 3c5ec04..09d226b 100644
--- a/runtime/vm/timeline_test.cc
+++ b/runtime/vm/timeline_test.cc
@@ -105,7 +105,7 @@
 
 TEST_CASE(TimelineEventIsValid) {
   // Create a test stream.
-  TimelineStream stream("testStream", "testStream", true);
+  TimelineStream stream("testStream", "testStream", false, true);
 
   TimelineEvent event;
   TimelineTestHelper::SetStream(&event, &stream);
@@ -124,7 +124,7 @@
 
 TEST_CASE(TimelineEventDuration) {
   // Create a test stream.
-  TimelineStream stream("testStream", "testStream", true);
+  TimelineStream stream("testStream", "testStream", false, true);
 
   // Create a test event.
   TimelineEvent event;
@@ -139,7 +139,7 @@
 
 TEST_CASE(TimelineEventDurationPrintJSON) {
   // Create a test stream.
-  TimelineStream stream("testStream", "testStream", true);
+  TimelineStream stream("testStream", "testStream", false, true);
 
   // Create a test event.
   TimelineEvent event;
@@ -169,7 +169,7 @@
   char buffer[kBufferLength];
 
   // Create a test stream.
-  TimelineStream stream("testStream", "testStream", true);
+  TimelineStream stream("testStream", "testStream", false, true);
 
   // Create a test event.
   TimelineEvent event;
@@ -213,7 +213,7 @@
 
 TEST_CASE(TimelineEventArguments) {
   // Create a test stream.
-  TimelineStream stream("testStream", "testStream", true);
+  TimelineStream stream("testStream", "testStream", false, true);
 
   // Create a test event.
   TimelineEvent event;
@@ -233,7 +233,7 @@
 
 TEST_CASE(TimelineEventArgumentsPrintJSON) {
   // Create a test stream.
-  TimelineStream stream("testStream", "testStream", true);
+  TimelineStream stream("testStream", "testStream", false, true);
 
   // Create a test event.
   TimelineEvent event;
@@ -296,7 +296,7 @@
   }
 
   // Create a test stream.
-  TimelineStream stream("testStream", "testStream", true);
+  TimelineStream stream("testStream", "testStream", false, true);
 
   TimelineEvent* event = NULL;
 
@@ -341,7 +341,7 @@
 }
 
 TEST_CASE(TimelineRingRecorderJSONOrder) {
-  TimelineStream stream("testStream", "testStream", true);
+  TimelineStream stream("testStream", "testStream", false, true);
 
   TimelineEventRingRecorder* recorder =
       new TimelineEventRingRecorder(TimelineEventBlock::kBlockSize * 2);
diff --git a/runtime/vm/type_testing_stubs.cc b/runtime/vm/type_testing_stubs.cc
index 41ac9d1..a62a5e4 100644
--- a/runtime/vm/type_testing_stubs.cc
+++ b/runtime/vm/type_testing_stubs.cc
@@ -14,6 +14,7 @@
 #include "vm/stub_code.h"
 #include "vm/timeline.h"
 #include "vm/type_testing_stubs.h"
+#include "vm/zone_text_buffer.h"
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
 #include "vm/compiler/backend/flow_graph_compiler.h"
@@ -32,57 +33,60 @@
 
 const char* TypeTestingStubNamer::StubNameForType(
     const AbstractType& type) const {
-  Zone* Z = Thread::Current()->zone();
-  return OS::SCreate(Z, "TypeTestingStub_%s", StringifyType(type));
+  ZoneTextBuffer buffer(Thread::Current()->zone());
+  WriteStubNameForTypeTo(&buffer, type);
+  return buffer.buffer();
 }
 
-const char* TypeTestingStubNamer::StringifyType(
+void TypeTestingStubNamer::WriteStubNameForTypeTo(
+    BaseTextBuffer* buffer,
     const AbstractType& type) const {
+  buffer->AddString("TypeTestingStub_");
+  StringifyTypeTo(buffer, type);
+}
+
+void TypeTestingStubNamer::StringifyTypeTo(BaseTextBuffer* buffer,
+                                           const AbstractType& type) const {
   NoSafepointScope no_safepoint;
-  Zone* Z = Thread::Current()->zone();
   if (type.IsType()) {
     const intptr_t cid = Type::Cast(type).type_class_id();
     ClassTable* class_table = IsolateGroup::Current()->class_table();
     klass_ = class_table->At(cid);
     ASSERT(!klass_.IsNull());
 
-    const char* curl = "";
     lib_ = klass_.library();
     if (!lib_.IsNull()) {
       string_ = lib_.url();
-      curl = OS::SCreate(Z, "%s_", string_.ToCString());
+      buffer->AddString(string_.ToCString());
     } else {
-      static std::atomic<intptr_t> counter = 0;
-      curl = OS::SCreate(Z, "nolib%" Pd "_", counter++);
+      buffer->Printf("nolib%" Pd "_", nonce_++);
     }
 
-    const char* concatenated = AssemblerSafeName(
-        OS::SCreate(Z, "%s_%s", curl, klass_.ScrubbedNameCString()));
+    buffer->AddString("_");
+    buffer->AddString(klass_.ScrubbedNameCString());
 
     const intptr_t type_parameters = klass_.NumTypeParameters();
-    auto& type_arguments = TypeArguments::Handle();
-    if (type.arguments() != TypeArguments::null() && type_parameters > 0) {
+    auto& type_arguments = TypeArguments::Handle(type.arguments());
+    if (!type_arguments.IsNull() && type_parameters > 0) {
       type_arguments = type.arguments();
       ASSERT(type_arguments.Length() >= type_parameters);
       const intptr_t length = type_arguments.Length();
       for (intptr_t i = 0; i < type_parameters; ++i) {
         type_ = type_arguments.TypeAt(length - type_parameters + i);
-        concatenated =
-            OS::SCreate(Z, "%s__%s", concatenated, StringifyType(type_));
+        buffer->AddString("__");
+        StringifyTypeTo(buffer, type_);
       }
     }
-
-    return concatenated;
   } else if (type.IsTypeParameter()) {
-    return AssemblerSafeName(
-        OS::SCreate(Z, "%s", TypeParameter::Cast(type).CanonicalNameCString()));
+    buffer->AddString(TypeParameter::Cast(type).CanonicalNameCString());
   } else {
-    return AssemblerSafeName(OS::SCreate(Z, "%s", type.ToCString()));
+    buffer->AddString(type.ToCString());
   }
+  MakeNameAssemblerSafe(buffer);
 }
 
-const char* TypeTestingStubNamer::AssemblerSafeName(char* cname) {
-  char* cursor = cname;
+void TypeTestingStubNamer::MakeNameAssemblerSafe(BaseTextBuffer* buffer) {
+  char* cursor = buffer->buffer();
   while (*cursor != '\0') {
     char c = *cursor;
     if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
@@ -91,7 +95,6 @@
     }
     cursor++;
   }
-  return cname;
 }
 
 CodePtr TypeTestingStubGenerator::DefaultCodeForType(
diff --git a/runtime/vm/type_testing_stubs.h b/runtime/vm/type_testing_stubs.h
index 7807bc1..b823215 100644
--- a/runtime/vm/type_testing_stubs.h
+++ b/runtime/vm/type_testing_stubs.h
@@ -24,15 +24,19 @@
   //
   // (only during dart_boostrap).
   const char* StubNameForType(const AbstractType& type) const;
+  void WriteStubNameForTypeTo(BaseTextBuffer* buffer,
+                              const AbstractType& type) const;
 
  private:
-  const char* StringifyType(const AbstractType& type) const;
-  static const char* AssemblerSafeName(char* cname);
+  void StringifyTypeTo(BaseTextBuffer* buffer, const AbstractType& type) const;
+  // Converts the contents of the buffer to an assembly-safe name.
+  static void MakeNameAssemblerSafe(BaseTextBuffer* buffer);
 
   Library& lib_;
   Class& klass_;
   AbstractType& type_;
   String& string_;
+  mutable intptr_t nonce_ = 0;
 };
 
 class TypeTestingStubGenerator {
diff --git a/samples-dev/swarm/swarm_ui_lib/layout/SizingFunctions.dart b/samples-dev/swarm/swarm_ui_lib/layout/SizingFunctions.dart
index bc4258a..a85a420 100644
--- a/samples-dev/swarm/swarm_ui_lib/layout/SizingFunctions.dart
+++ b/samples-dev/swarm/swarm_ui_lib/layout/SizingFunctions.dart
@@ -27,7 +27,7 @@
 }
 
 /**
- * Fixed size reprensents a length as defined by CSS3 Values spec.
+ * Fixed size represents a length as defined by CSS3 Values spec.
  * Can also be a percentage of the Grid element's logical width (for columns)
  * or logical height (for rows). When the width or height of the Grid element
  * is undefined, the percentage is ignored and the Grid Track will be
diff --git a/samples/ffi/sample_ffi_functions_structs.dart b/samples/ffi/sample_ffi_functions_structs.dart
index a051fcf..bf9c0ca 100644
--- a/samples/ffi/sample_ffi_functions_structs.dart
+++ b/samples/ffi/sample_ffi_functions_structs.dart
@@ -44,7 +44,7 @@
   }
 
   {
-    // Pass an array of structs to a c funtion.
+    // Pass an array of structs to a c function.
     Pointer<NativeFunction<NativeCoordinateOp>> p1 =
         ffiTestFunctions.lookup("CoordinateElemAt1");
     NativeCoordinateOp f1 = p1.asFunction();
diff --git a/samples_2/ffi/sample_ffi_functions_structs.dart b/samples_2/ffi/sample_ffi_functions_structs.dart
index 7a8370e..e8f0387 100644
--- a/samples_2/ffi/sample_ffi_functions_structs.dart
+++ b/samples_2/ffi/sample_ffi_functions_structs.dart
@@ -46,7 +46,7 @@
   }
 
   {
-    // Pass an array of structs to a c funtion.
+    // Pass an array of structs to a c function.
     Pointer<NativeFunction<NativeCoordinateOp>> p1 =
         ffiTestFunctions.lookup("CoordinateElemAt1");
     NativeCoordinateOp f1 = p1.asFunction();
diff --git a/sdk/lib/_http/websocket_impl.dart b/sdk/lib/_http/websocket_impl.dart
index fdafda8..16f92d5 100644
--- a/sdk/lib/_http/websocket_impl.dart
+++ b/sdk/lib/_http/websocket_impl.dart
@@ -647,7 +647,7 @@
     }
 
     // RFC 7692 7.2.3.6. "Generating an Empty Fragment" says that if the
-    // compression library doesn't generate any data when the bufer is empty,
+    // compression library doesn't generate any data when the buffer is empty,
     // then an empty uncompressed deflate block is used for this purpose. The
     // 0x00 block has the BFINAL header bit set to 0 and the BTYPE header set to
     // 00 along with 5 bits of padding. This block decodes to zero bytes.
diff --git a/sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart
index b9cf805..27b7981 100644
--- a/sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart
+++ b/sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart
@@ -140,7 +140,7 @@
   static final _scheduleImmediateClosure = _initializeScheduleImmediate();
 
   static void Function(void Function()) _initializeScheduleImmediate() {
-    // d8 support, see preambles/d8.js for the definiton of `scheduleImmediate`.
+    // d8 support, see preambles/d8.js for the definition of `scheduleImmediate`.
     //
     // TODO(jmesserly): do we need this? It's only for our d8 stack trace test.
     if (JS('', '#.scheduleImmediate', dart.global_) != null) {
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
index 0d8ebd4..9e1183c 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
@@ -273,7 +273,7 @@
 /// denote *some* package:js type in our subtyping logic.
 ///
 /// Used only when a concrete PackageJSType is not available i.e. when neither
-/// the object nor the target type is a PackageJSType. Avoids initializating a
+/// the object nor the target type is a PackageJSType. Avoids initializing a
 /// new PackageJSType every time. Note that we don't add it to the set of JS
 /// types, since it's not an actual JS class.
 final _pkgJSTypeForSubtyping = PackageJSType('');
diff --git a/sdk/lib/_internal/js_shared/lib/rti.dart b/sdk/lib/_internal/js_shared/lib/rti.dart
index 36b18b5..6e2b265 100644
--- a/sdk/lib/_internal/js_shared/lib/rti.dart
+++ b/sdk/lib/_internal/js_shared/lib/rti.dart
@@ -2224,7 +2224,7 @@
 ///   ToType(Rti): Same Rti
 ///
 ///
-/// Notes on enviroments and indexing.
+/// Notes on environments and indexing.
 ///
 /// To avoid creating a binding Rti for a single function type parameter, the
 /// type is passed without creating a 1-tuple object. This means that the
diff --git a/sdk/lib/_internal/vm/bin/socket_patch.dart b/sdk/lib/_internal/vm/bin/socket_patch.dart
index ed5a892..52ba285 100644
--- a/sdk/lib/_internal/vm/bin/socket_patch.dart
+++ b/sdk/lib/_internal/vm/bin/socket_patch.dart
@@ -481,7 +481,7 @@
   // Only used for UDP sockets.
   bool _availableDatagram = false;
 
-  // The number of incoming connnections for Listening socket.
+  // The number of incoming connections for Listening socket.
   int connections = 0;
 
   // The count of received event from eventhandler.
diff --git a/sdk/lib/_internal/vm/lib/regexp_patch.dart b/sdk/lib/_internal/vm/lib/regexp_patch.dart
index a977b67..4936407 100644
--- a/sdk/lib/_internal/vm/lib/regexp_patch.dart
+++ b/sdk/lib/_internal/vm/lib/regexp_patch.dart
@@ -53,7 +53,7 @@
   static int _findEscapeChar(String text, int start) {
     // Table where each character in the range U+0000 to U+007f is represented
     // by whether it needs to be escaped in a regexp.
-    // The \x00 characters means escacped, and \x01 means non-escaped.
+    // The \x00 characters means escaped, and \x01 means non-escaped.
     const escapes =
         "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
         "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
diff --git a/sdk/lib/_internal/vm/lib/string_patch.dart b/sdk/lib/_internal/vm/lib/string_patch.dart
index 8e353de..540f373 100644
--- a/sdk/lib/_internal/vm/lib/string_patch.dart
+++ b/sdk/lib/_internal/vm/lib/string_patch.dart
@@ -918,7 +918,7 @@
     int startIndex = 0;
     int previousIndex = 0;
     // 'pattern' may not be implemented correctly and therefore we cannot
-    // call _substringUnhchecked unless it is a trustworthy type (e.g. String).
+    // call _substringUnchecked unless it is a trustworthy type (e.g. String).
     while (true) {
       if (startIndex == length || !iterator.moveNext()) {
         result.add(this.substring(previousIndex, length));
diff --git a/sdk/lib/_internal/wasm/lib/string_patch.dart b/sdk/lib/_internal/wasm/lib/string_patch.dart
index 5b09baa..b5e57fd 100644
--- a/sdk/lib/_internal/wasm/lib/string_patch.dart
+++ b/sdk/lib/_internal/wasm/lib/string_patch.dart
@@ -849,7 +849,7 @@
     int startIndex = 0;
     int previousIndex = 0;
     // 'pattern' may not be implemented correctly and therefore we cannot
-    // call _substringUnhchecked unless it is a trustworthy type (e.g. String).
+    // call _substringUnchecked unless it is a trustworthy type (e.g. String).
     while (true) {
       if (startIndex == length || !iterator.moveNext()) {
         result.add(this.substring(previousIndex, length));
diff --git a/sdk/lib/async/stream_controller.dart b/sdk/lib/async/stream_controller.dart
index 2baf008..8ede57e 100644
--- a/sdk/lib/async/stream_controller.dart
+++ b/sdk/lib/async/stream_controller.dart
@@ -701,8 +701,8 @@
     // If either of addStream's cancel or `onCancel` returns a future,
     // we wait for it before continuing.
     // Any error during this process ends up in the returned future.
-    // If more errors happen, we act as if it happens inside nested try/finallys
-    // or whenComplete calls, and only the last error ends up in the
+    // If more errors happen, we act as if it happens inside nested try/finally
+    // blocks or whenComplete calls, and only the last error ends up in the
     // returned future.
     Future<void>? result;
     if (_isAddingStream) {
diff --git a/sdk/lib/developer/profiler.dart b/sdk/lib/developer/profiler.dart
index b134de7..431d2a9 100644
--- a/sdk/lib/developer/profiler.dart
+++ b/sdk/lib/developer/profiler.dart
@@ -44,7 +44,7 @@
 
   Metric(this.name, this.description) {
     if ((name == 'vm') || name.contains('/')) {
-      throw new ArgumentError('Invalid Metric name.');
+      throw ArgumentError('Invalid Metric name.');
     }
   }
 
@@ -74,7 +74,7 @@
     // TODO: When NNBD is complete, delete the following two lines.
     ArgumentError.checkNotNull(min, 'min');
     ArgumentError.checkNotNull(max, 'max');
-    if (!(min < max)) throw new ArgumentError('min must be less than max');
+    if (!(min < max)) throw ArgumentError('min must be less than max');
   }
 
   Map _toJSON() {
@@ -113,23 +113,25 @@
   }
 }
 
+/// Register and deregister custom [Metric]s to be displayed in developer
+/// tooling.
 class Metrics {
   /// The current set of registered [Metric]s.
   static UnmodifiableMapView<String, Metric> get current =>
       UnmodifiableMapView<String, Metric>(_metrics);
   static final _metrics = <String, Metric>{};
 
-  /// Register [Metric]s to make them visible to Observatory.
+  /// Register [Metric]s to make them visible to developer tooling.
   static void register(Metric metric) {
     // TODO: When NNBD is complete, delete the following line.
     ArgumentError.checkNotNull(metric, 'metric');
     if (_metrics[metric.name] != null) {
-      throw new ArgumentError('Registered metrics have unique names');
+      throw ArgumentError('Registered metrics have unique names');
     }
     _metrics[metric.name] = metric;
   }
 
-  /// Deregister [Metric]s to make them not visible to Observatory.
+  /// Deregister [Metric]s to make them not visible to developer tooling.
   static void deregister(Metric metric) {
     // TODO: When NNBD is complete, delete the following line.
     ArgumentError.checkNotNull(metric, 'metric');
diff --git a/sdk/lib/io/socket.dart b/sdk/lib/io/socket.dart
index dd68941..4884414 100644
--- a/sdk/lib/io/socket.dart
+++ b/sdk/lib/io/socket.dart
@@ -904,7 +904,7 @@
 /// [RawSocket.readMessage].
 ///
 /// Control messages could carry different information including
-/// [ResourceHandle]. If [ResourceHandle]s are availabe as part of this message,
+/// [ResourceHandle]. If [ResourceHandle]s are available as part of this message,
 /// they can be extracted via [extractHandles].
 abstract class SocketControlMessage {
   /// Creates a control message containing the provided [handles].
diff --git a/sdk/lib/libraries.json b/sdk/lib/libraries.json
index a398608..9f93f8b 100644
--- a/sdk/lib/libraries.json
+++ b/sdk/lib/libraries.json
@@ -195,6 +195,7 @@
         "patches": [
           "_internal/wasm/lib/core_patch.dart",
           "_internal/vm/lib/array_patch.dart",
+          "_internal/vm/lib/bigint_patch.dart",
           "_internal/wasm/lib/bool.dart",
           "_internal/vm/lib/bool_patch.dart",
           "_internal/wasm/lib/date_patch.dart",
diff --git a/sdk/lib/libraries.yaml b/sdk/lib/libraries.yaml
index ee7ad39..b1a0e70 100644
--- a/sdk/lib/libraries.yaml
+++ b/sdk/lib/libraries.yaml
@@ -185,6 +185,7 @@
       patches:
       - _internal/wasm/lib/core_patch.dart
       - _internal/vm/lib/array_patch.dart
+      - _internal/vm/lib/bigint_patch.dart
       - _internal/wasm/lib/bool.dart
       - _internal/vm/lib/bool_patch.dart
       - _internal/wasm/lib/date_patch.dart
diff --git a/tests/co19/update.sh b/tests/co19/update.sh
index 47ecedc..3a156d4 100755
--- a/tests/co19/update.sh
+++ b/tests/co19/update.sh
@@ -29,7 +29,7 @@
   "$(printf "[co19] Roll co19 to $NEW\n\n" \
   && cd $CO19 \
   && git log --date='format:%Y-%m-%d' --pretty='format:%ad %ae %s' $OLD..$NEW \
-    | sed 's/\#/dart-lang\/co19\#/g'
+    | sed 's/\#/dart-lang\/co19\#/g')"
 
 rm -rf tests/co19/src.git
 
diff --git a/tests/co19_2/update.sh b/tests/co19_2/update.sh
index d7f1540..b910c1e 100755
--- a/tests/co19_2/update.sh
+++ b/tests/co19_2/update.sh
@@ -29,7 +29,7 @@
   "$(printf "[co19] Roll co19_2 to $NEW\n\n" \
   && cd $CO19 \
   && git log --date='format:%Y-%m-%d' --pretty='format:%ad %ae %s' $OLD..$NEW \
-    | sed 's/\#/dart-lang\/co19\#/g'
+    | sed 's/\#/dart-lang\/co19\#/g')"
 
 rm -rf tests/co19_2/src.git
 
diff --git a/tests/corelib/shuffle_test.dart b/tests/corelib/shuffle_test.dart
index 2836c42..3d46ded 100644
--- a/tests/corelib/shuffle_test.dart
+++ b/tests/corelib/shuffle_test.dart
@@ -67,7 +67,7 @@
   // of a proper shuffling hitting the same list again is less than 10^80
   // (arbitrary bignum - approx. number of atoms in the universe).
   //
-  // The probablility of shuffling a list of length n into the same list is
+  // The probability of shuffling a list of length n into the same list is
   // 1/n!. If one shuffle didn't change the list, repeat shuffling until
   // probability of randomly hitting the same list every time is less than
   // 1/1e80.
diff --git a/tests/corelib/uri_ipv6_test.dart b/tests/corelib/uri_ipv6_test.dart
index e5dbb9df..a93c276 100644
--- a/tests/corelib/uri_ipv6_test.dart
+++ b/tests/corelib/uri_ipv6_test.dart
@@ -169,7 +169,7 @@
   Expect.equals('https://[fe80::8eae:4c4d:fee9:8434%25rename3]/index.html',
       uri.toString());
 
-  // Test construtors with host name
+  // Test constructors with host name
   uri = Uri(scheme: 'https', host: '[ff02::5678%pvc1.3]');
   uri = Uri(scheme: 'https', host: '[fe80::a%1]');
   uri = Uri(scheme: 'https', host: '[fe80::a%25eE1]');
diff --git a/tests/corelib_2/shuffle_test.dart b/tests/corelib_2/shuffle_test.dart
index c36ad5c..aaab68c 100644
--- a/tests/corelib_2/shuffle_test.dart
+++ b/tests/corelib_2/shuffle_test.dart
@@ -69,7 +69,7 @@
   // of a proper shuffling hitting the same list again is less than 10^80
   // (arbitrary bignum - approx. number of atoms in the universe).
   //
-  // The probablility of shuffling a list of length n into the same list is
+  // The probability of shuffling a list of length n into the same list is
   // 1/n!. If one shuffle didn't change the list, repeat shuffling until
   // probability of randomly hitting the same list every time is less than
   // 1/1e80.
diff --git a/tests/corelib_2/uri_ipv6_test.dart b/tests/corelib_2/uri_ipv6_test.dart
index a40cf1d..8bd10bd 100644
--- a/tests/corelib_2/uri_ipv6_test.dart
+++ b/tests/corelib_2/uri_ipv6_test.dart
@@ -171,7 +171,7 @@
   Expect.equals('https://[fe80::8eae:4c4d:fee9:8434%25rename3]/index.html',
       uri.toString());
 
-  // Test construtors with host name
+  // Test constructors with host name
   uri = Uri(scheme: 'https', host: '[ff02::5678%pvc1.3]');
   uri = Uri(scheme: 'https', host: '[fe80::a%1]');
   uri = Uri(scheme: 'https', host: '[fe80::a%25eE1]');
diff --git a/tests/ffi/function_structs_test.dart b/tests/ffi/function_structs_test.dart
index b0f2cdb..bfd6563 100644
--- a/tests/ffi/function_structs_test.dart
+++ b/tests/ffi/function_structs_test.dart
@@ -57,7 +57,7 @@
   calloc.free(c2);
 }
 
-/// pass an array of structs to a c funtion
+/// pass an array of structs to a c function
 void testFunctionWithStructArray({bool isLeaf: false}) {
   Pointer<NativeFunction<NativeCoordinateOp>> p1 =
       ffiTestFunctions.lookup("CoordinateElemAt1");
diff --git a/tests/ffi/generator/structs_by_value_tests_configuration.dart b/tests/ffi/generator/structs_by_value_tests_configuration.dart
index 9179d50..1fff672 100644
--- a/tests/ffi/generator/structs_by_value_tests_configuration.dart
+++ b/tests/ffi/generator/structs_by_value_tests_configuration.dart
@@ -719,7 +719,7 @@
 
 final struct17bytesInt = StructType([int64, int64, int8]);
 
-/// This struct has only 1 byte field-alignmnent requirements.
+/// This struct has only 1 byte field-alignment requirements.
 final struct19bytesInt = StructType(List.filled(19, uint8));
 
 /// The first homogenous integer struct that does not go into registers
diff --git a/tests/ffi/generator/structs_by_value_tests_generator.dart b/tests/ffi/generator/structs_by_value_tests_generator.dart
index 3a18095..671f65e 100644
--- a/tests/ffi/generator/structs_by_value_tests_generator.dart
+++ b/tests/ffi/generator/structs_by_value_tests_generator.dart
@@ -96,7 +96,7 @@
 }
 
 extension on CType {
-  /// A list of statements adding all members recurisvely to `result`.
+  /// A list of statements adding all members recursively to `result`.
   ///
   /// Both valid in Dart and C.
   String addToResultStatements(String variableName) {
@@ -130,7 +130,7 @@
 }
 
 extension on List<Member> {
-  /// A list of statements adding all members recurisvely to `result`.
+  /// A list of statements adding all members recursively to `result`.
   ///
   /// Both valid in Dart and C.
   String addToResultStatements([String namePrefix = ""]) {
diff --git a/tests/ffi/regress_40537_test.dart b/tests/ffi/regress_40537_test.dart
index d003b21..bd4cdf9 100644
--- a/tests/ffi/regress_40537_test.dart
+++ b/tests/ffi/regress_40537_test.dart
@@ -29,14 +29,14 @@
 
 variant1Negative() {
   // 0xF9 =  -7 in 2s complement.
-  // 0xF9 = 249 in unsinged.
+  // 0xF9 = 249 in unsigned.
   final result = regress40537(-7);
   print(result);
   Expect.equals(1, result);
 }
 
 variant1Positive() {
-  // 0xF9 = 249 in unsinged.
+  // 0xF9 = 249 in unsigned.
   final result = regress40537(0xFFFFFFF9);
   print(result);
   Expect.equals(1, result);
diff --git a/tests/ffi_2/function_structs_test.dart b/tests/ffi_2/function_structs_test.dart
index 86f49de..2aa80ed 100644
--- a/tests/ffi_2/function_structs_test.dart
+++ b/tests/ffi_2/function_structs_test.dart
@@ -58,7 +58,7 @@
   calloc.free(c2);
 }
 
-/// pass an array of structs to a c funtion
+/// pass an array of structs to a c function
 void testFunctionWithStructArray({bool isLeaf: false}) {
   Pointer<NativeFunction<NativeCoordinateOp>> p1 =
       ffiTestFunctions.lookup("CoordinateElemAt1");
diff --git a/tests/ffi_2/regress_40537_test.dart b/tests/ffi_2/regress_40537_test.dart
index a9983db..bb5eb58 100644
--- a/tests/ffi_2/regress_40537_test.dart
+++ b/tests/ffi_2/regress_40537_test.dart
@@ -31,14 +31,14 @@
 
 variant1Negative() {
   // 0xF9 =  -7 in 2s complement.
-  // 0xF9 = 249 in unsinged.
+  // 0xF9 = 249 in unsigned.
   final result = regress40537(-7);
   print(result);
   Expect.equals(1, result);
 }
 
 variant1Positive() {
-  // 0xF9 = 249 in unsinged.
+  // 0xF9 = 249 in unsigned.
   final result = regress40537(0xFFFFFFF9);
   print(result);
   Expect.equals(1, result);
diff --git a/tests/language/async_star/async_star_await_for_test.dart b/tests/language/async_star/async_star_await_for_test.dart
index 0493a1f..46b5ca5 100644
--- a/tests/language/async_star/async_star_await_for_test.dart
+++ b/tests/language/async_star/async_star_await_for_test.dart
@@ -54,7 +54,7 @@
     if (event == yieldAt) {
       log.add("y$event[");
       // Yield may cause subscription to pause or cancel.
-      // This loop should stay at the yield until the event has been delieverd.
+      // This loop should stay at the yield until the event has been delivered.
       // If the receiver pauses or cancels, we delay or break the loop here.
       yield event;
       log.add("]");
diff --git a/tests/language/const/string_test.dart b/tests/language/const/string_test.dart
index 13f1a9c..44f6241 100644
--- a/tests/language/const/string_test.dart
+++ b/tests/language/const/string_test.dart
@@ -21,7 +21,7 @@
   Expect.isTrue(identical("abcd", 'ab' 'cd'));
   Expect.isTrue(identical("abcd", 'ab' "cd"));
 
-  // Or when there are more than 2 contatenations.
+  // Or when there are more than 2 concatenations.
   Expect.isTrue(identical("abcd", "a" "b" "cd"));
   Expect.isTrue(identical("abcd", "a" "b" "c" "d"));
   Expect.isTrue(identical('abcd', 'a' 'b' 'c' 'd'));
diff --git a/tests/language/constants_2018/potential_const_dynamic_test.dart b/tests/language/constants_2018/potential_const_dynamic_test.dart
index 63f031a..228701e 100644
--- a/tests/language/constants_2018/potential_const_dynamic_test.dart
+++ b/tests/language/constants_2018/potential_const_dynamic_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 // Tests that a dynamic type does not affect whether an expression is
-// potentially constant, the actual type of the value of an experssion
+// potentially constant, the actual type of the value of an expression
 // only matters if the expression is evaluated as a constant.
 
 main() {
diff --git a/tests/language/constants_2018/potential_const_test.dart b/tests/language/constants_2018/potential_const_test.dart
index ad516a9..0341479 100644
--- a/tests/language/constants_2018/potential_const_test.dart
+++ b/tests/language/constants_2018/potential_const_test.dart
@@ -12,7 +12,7 @@
   const C(this.v);
 
   // Redirecting generative constructor invocation parameters,
-  // must be potenentially constant.
+  // must be potentially constant.
   const C.r1() : this(const C(null));
 
   // Only evaluates the true branch when passed `true` as argument.
diff --git a/tests/language/constructor/tear_off_test.dart b/tests/language/constructor/tear_off_test.dart
index ce7144d..98dd2f3 100644
--- a/tests/language/constructor/tear_off_test.dart
+++ b/tests/language/constructor/tear_off_test.dart
@@ -194,7 +194,7 @@
   // Using a type variable, not a constant type expression.
   // Canonicalization is unspecified, but equality holds.
   (<T>() {
-    // Tear off with explicit instantation to the same non-constant type.
+    // Tear off with explicit instantiation to the same non-constant type.
     Expect.equals(GGen<T>.new, GGen<T>.new);
     Expect.equals(GGen<T>.named, GGen<T>.named);
     Expect.equals(GGenRedir<T>.new, GGenRedir<T>.new);
diff --git a/tests/language/nonfunction_type_aliases/private_names/private_name_mixin_test.dart b/tests/language/nonfunction_type_aliases/private_names/private_name_mixin_test.dart
index 797f425..39e9f8c 100644
--- a/tests/language/nonfunction_type_aliases/private_names/private_name_mixin_test.dart
+++ b/tests/language/nonfunction_type_aliases/private_names/private_name_mixin_test.dart
@@ -62,7 +62,7 @@
   // original library.
   Expect.equals(privateLibrarySentinel, callPrivateSuperMixinMethod(p));
   Expect.equals(privateLibrarySentinel, callPrivateInstanceMethod(p));
-  // The new private mixin and instance methods are acessible in this library.
+  // The new private mixin and instance methods are accessible in this library.
   Expect.equals(publicLibrarySentinel, p._privateMixinMethod());
   Expect.equals(publicLibrarySentinel, p._privateInstanceMethod());
 }
diff --git a/tests/language_2/async_star/async_star_await_for_test.dart b/tests/language_2/async_star/async_star_await_for_test.dart
index 980f8c7..f4a2a4d 100644
--- a/tests/language_2/async_star/async_star_await_for_test.dart
+++ b/tests/language_2/async_star/async_star_await_for_test.dart
@@ -56,7 +56,7 @@
     if (event == yieldAt) {
       log.add("y$event[");
       // Yield may cause subscription to pause or cancel.
-      // This loop should stay at the yield until the event has been delieverd.
+      // This loop should stay at the yield until the event has been delivered.
       // If the receiver pauses or cancels, we delay or break the loop here.
       yield event;
       log.add("]");
diff --git a/tests/language_2/const/string_test.dart b/tests/language_2/const/string_test.dart
index 0429ff5..5895d76 100644
--- a/tests/language_2/const/string_test.dart
+++ b/tests/language_2/const/string_test.dart
@@ -23,7 +23,7 @@
   Expect.isTrue(identical("abcd", 'ab' 'cd'));
   Expect.isTrue(identical("abcd", 'ab' "cd"));
 
-  // Or when there are more than 2 contatenations.
+  // Or when there are more than 2 concatenations.
   Expect.isTrue(identical("abcd", "a" "b" "cd"));
   Expect.isTrue(identical("abcd", "a" "b" "c" "d"));
   Expect.isTrue(identical('abcd', 'a' 'b' 'c' 'd'));
diff --git a/tests/language_2/constants_2018/potential_const_dynamic_test.dart b/tests/language_2/constants_2018/potential_const_dynamic_test.dart
index 2f98cc3..e8a6158 100644
--- a/tests/language_2/constants_2018/potential_const_dynamic_test.dart
+++ b/tests/language_2/constants_2018/potential_const_dynamic_test.dart
@@ -5,7 +5,7 @@
 // @dart = 2.9
 
 // Tests that a dynamic type does not affect whether an expression is
-// potentially constant, the actual type of the value of an experssion
+// potentially constant, the actual type of the value of an expression
 // only matters if the expression is evaluated as a constant.
 
 main() {
diff --git a/tests/language_2/constants_2018/potential_const_test.dart b/tests/language_2/constants_2018/potential_const_test.dart
index e7fd658..be26de8 100644
--- a/tests/language_2/constants_2018/potential_const_test.dart
+++ b/tests/language_2/constants_2018/potential_const_test.dart
@@ -14,7 +14,7 @@
   const C(this.v);
 
   // Redirecting generative constructor invocation parameters,
-  // must be potenentially constant.
+  // must be potentially constant.
   const C.r1() : this(const C(null));
 
   // Only evaluates the true branch when passed `true` as argument.
diff --git a/tests/lib/async/zone_value_test.dart b/tests/lib/async/zone_value_test.dart
index 7841776..41564df 100644
--- a/tests/lib/async/zone_value_test.dart
+++ b/tests/lib/async/zone_value_test.dart
@@ -138,7 +138,7 @@
 }
 
 // Class of objects that consider themselves equal to their originals.
-// Sees through mimickry.
+// Sees through mimicry.
 class Mimic {
   final Object original;
   Mimic(this.original);
diff --git a/tests/lib/isolate/weak_reference_message_2_test.dart b/tests/lib/isolate/weak_reference_message_2_test.dart
index cc70985..80d9517 100644
--- a/tests/lib/isolate/weak_reference_message_2_test.dart
+++ b/tests/lib/isolate/weak_reference_message_2_test.dart
@@ -59,10 +59,10 @@
   expando4[key4] = object4;
 
   final message = <dynamic>[
-    weakRef1, // Does not have its target inluded.
+    weakRef1, // Does not have its target included.
     weakRef2, // Has its target included later than itself.
     object2,
-    weakRef3, // Does not have its target inluded.
+    weakRef3, // Does not have its target included.
     expando3,
     weakRef4, // Has its target included due to expando.
     expando4,
diff --git a/tests/lib/js/array_test.dart b/tests/lib/js/array_test.dart
index 30bae97..caa1f90 100644
--- a/tests/lib/js/array_test.dart
+++ b/tests/lib/js/array_test.dart
@@ -21,7 +21,7 @@
   var list = <int>[1, 2, 3];
   testArray = list;
 
-  // Call the consturctor with `new`.
+  // Call the constructor with `new`.
   var array = js.callConstructor(js.getProperty(testArray, 'constructor'), []);
   var list2 = array as List;
   Expect.listEquals(list2, []);
diff --git a/tests/lib/js/js_util/properties_test.dart b/tests/lib/js/js_util/properties_test.dart
index 5f718a6..0ac3310 100644
--- a/tests/lib/js/js_util/properties_test.dart
+++ b/tests/lib/js/js_util/properties_test.dart
@@ -315,7 +315,7 @@
       expect(index, equals(1));
       expect(js_util.getProperty(f.list, index), equals(4));
 
-      // Accessing nested object properites.
+      // Accessing nested object properties.
       var objectProperty = js_util.getProperty(f, 'objectProperty');
       expect(js_util.getProperty(objectProperty, 'c'), equals(1));
       expect(js_util.getProperty(objectProperty, 'list') is List, isTrue);
diff --git a/tests/lib_2/async/zone_value_test.dart b/tests/lib_2/async/zone_value_test.dart
index 8be36a0..15e2c83 100644
--- a/tests/lib_2/async/zone_value_test.dart
+++ b/tests/lib_2/async/zone_value_test.dart
@@ -140,7 +140,7 @@
 }
 
 // Class of objects that consider themselves equal to their originals.
-// Sees through mimickry.
+// Sees through mimicry.
 class Mimic {
   final Object original;
   Mimic(this.original);
diff --git a/tests/lib_2/isolate/weak_reference_message_2_test.dart b/tests/lib_2/isolate/weak_reference_message_2_test.dart
index 1c18735..5dfa95f 100644
--- a/tests/lib_2/isolate/weak_reference_message_2_test.dart
+++ b/tests/lib_2/isolate/weak_reference_message_2_test.dart
@@ -61,10 +61,10 @@
   expando4[key4] = object4;
 
   final message = <dynamic>[
-    weakRef1, // Does not have its target inluded.
+    weakRef1, // Does not have its target included.
     weakRef2, // Has its target included later than itself.
     object2,
-    weakRef3, // Does not have its target inluded.
+    weakRef3, // Does not have its target included.
     expando3,
     weakRef4, // Has its target included due to expando.
     expando4,
diff --git a/tests/lib_2/js/array_test.dart b/tests/lib_2/js/array_test.dart
index 4cf5558..76c6021 100644
--- a/tests/lib_2/js/array_test.dart
+++ b/tests/lib_2/js/array_test.dart
@@ -23,7 +23,7 @@
   var list = <int>[1, 2, 3];
   testArray = list;
 
-  // Call the consturctor with `new`.
+  // Call the constructor with `new`.
   var array = js.callConstructor(js.getProperty(testArray, 'constructor'), []);
   var list2 = array as List;
   Expect.listEquals(list2, []);
diff --git a/tests/lib_2/js/js_util/properties_test.dart b/tests/lib_2/js/js_util/properties_test.dart
index 2b0af10..6618c4f 100644
--- a/tests/lib_2/js/js_util/properties_test.dart
+++ b/tests/lib_2/js/js_util/properties_test.dart
@@ -317,7 +317,7 @@
       expect(index, equals(1));
       expect(js_util.getProperty(f.list, index), equals(4));
 
-      // Accessing nested object properites.
+      // Accessing nested object properties.
       var objectProperty = js_util.getProperty(f, 'objectProperty');
       expect(js_util.getProperty(objectProperty, 'c'), equals(1));
       expect(js_util.getProperty(objectProperty, 'list') is List, isTrue);
diff --git a/tests/standalone/io/raw_secure_server_socket_test.dart b/tests/standalone/io/raw_secure_server_socket_test.dart
index a461480..6cea592 100644
--- a/tests/standalone/io/raw_secure_server_socket_test.dart
+++ b/tests/standalone/io/raw_secure_server_socket_test.dart
@@ -54,7 +54,7 @@
     asyncEnd();
   });
 
-  // Bind to an unavaliable IP-address.
+  // Bind to an unavailable IP-address.
   asyncStart();
   print("asyncStart testInvalidBind 2");
   RawSecureServerSocket.bind("8.8.8.8", 0, serverContext).then((_) {
diff --git a/tests/standalone/io/raw_socket_test.dart b/tests/standalone/io/raw_socket_test.dart
index 935db37..27aefff 100644
--- a/tests/standalone/io/raw_socket_test.dart
+++ b/tests/standalone/io/raw_socket_test.dart
@@ -38,7 +38,7 @@
     asyncEnd();
   });
 
-  // Bind to an unavaliable IP-address.
+  // Bind to an unavailable IP-address.
   asyncStart();
   RawServerSocket.bind("8.8.8.8", 0).then((_) {
     Expect.fail("Failure expected");
diff --git a/tests/standalone/io/raw_synchronous_socket_test.dart b/tests/standalone/io/raw_synchronous_socket_test.dart
index 96f4511..71dabd0 100644
--- a/tests/standalone/io/raw_synchronous_socket_test.dart
+++ b/tests/standalone/io/raw_synchronous_socket_test.dart
@@ -33,7 +33,7 @@
     Expect.isTrue(e is SocketException);
   }
 
-  // Connect to an unavaliable IP-address.
+  // Connect to an unavailable IP-address.
   try {
     var socket = RawSynchronousSocket.connectSync("1.2.3.4", 0);
     Expect.fail("Failure expected");
diff --git a/tests/standalone/io/secure_server_socket_test.dart b/tests/standalone/io/secure_server_socket_test.dart
index 627ed6d..9fd735c 100644
--- a/tests/standalone/io/secure_server_socket_test.dart
+++ b/tests/standalone/io/secure_server_socket_test.dart
@@ -49,7 +49,7 @@
     asyncEnd();
   });
 
-  // Bind to an unavaliable IP-address.
+  // Bind to an unavailable IP-address.
   asyncStart();
   SecureServerSocket.bind("8.8.8.8", 0, serverContext).then((_) {
     Expect.fail("Failure expected");
diff --git a/tests/standalone/io/socket_invalid_bind_test.dart b/tests/standalone/io/socket_invalid_bind_test.dart
index f19d551..92d1f95 100644
--- a/tests/standalone/io/socket_invalid_bind_test.dart
+++ b/tests/standalone/io/socket_invalid_bind_test.dart
@@ -23,7 +23,7 @@
     asyncEnd();
   });
 
-  // Bind to an unavaliable IP-address.
+  // Bind to an unavailable IP-address.
   asyncStart();
   ServerSocket.bind("8.8.8.8", 0).then((_) {
     Expect.fail("Failure expected");
diff --git a/tests/standalone/priority_queue_stress_test.dart b/tests/standalone/priority_queue_stress_test.dart
index 4f70334..aab8bfa 100644
--- a/tests/standalone/priority_queue_stress_test.dart
+++ b/tests/standalone/priority_queue_stress_test.dart
@@ -83,7 +83,7 @@
  * The queue guarantees that nodes are returned in the same order they
  * are added for a given priority.
  * For type safety this queue is guarded by the elements being subclasses of
- * TypedElement - this is not strictly neccesary since we never actually
+ * TypedElement - this is not strictly necessary since we never actually
  * use the value or type of the nodes.
  */
 class PriorityQueue<N extends TypedElement, P extends Priority> {
@@ -152,7 +152,7 @@
 
 /**
  * Implements a specialized priority queue that efficiently allows getting
- * the highest priorized node that adheres to a set of restrictions.
+ * the highest prioritized node that adheres to a set of restrictions.
  * Most notably it allows to get the highest priority node where the node's
  * type is not in an exclude list.
  * In addition, the queue has a number of properties:
@@ -167,7 +167,7 @@
  */
 class RestrictViewPriorityQueue<N extends TypedElement, P extends Priority> {
   // We can't use the basic dart priority queue since it does not guarantee
-  // FIFO for items with the same order. This is currently not uptimized for
+  // FIFO for items with the same order. This is currently not optimized for
   // different N, if many different N is expected here we should have a
   // priority queue instead of a list.
   List<PriorityQueue<N, P>> restrictedQueues = <PriorityQueue<N, P>>[];
diff --git a/tests/standalone_2/io/raw_secure_server_socket_test.dart b/tests/standalone_2/io/raw_secure_server_socket_test.dart
index 7c1c749..030d3e2 100644
--- a/tests/standalone_2/io/raw_secure_server_socket_test.dart
+++ b/tests/standalone_2/io/raw_secure_server_socket_test.dart
@@ -56,7 +56,7 @@
     asyncEnd();
   });
 
-  // Bind to an unavaliable IP-address.
+  // Bind to an unavailable IP-address.
   asyncStart();
   print("asyncStart testInvalidBind 2");
   RawSecureServerSocket.bind("8.8.8.8", 0, serverContext).then((_) {
diff --git a/tests/standalone_2/io/raw_socket_test.dart b/tests/standalone_2/io/raw_socket_test.dart
index 97a7d03b..9b3715d 100644
--- a/tests/standalone_2/io/raw_socket_test.dart
+++ b/tests/standalone_2/io/raw_socket_test.dart
@@ -40,7 +40,7 @@
     asyncEnd();
   });
 
-  // Bind to an unavaliable IP-address.
+  // Bind to an unavailable IP-address.
   asyncStart();
   RawServerSocket.bind("8.8.8.8", 0).then((_) {
     Expect.fail("Failure expected");
diff --git a/tests/standalone_2/io/raw_synchronous_socket_test.dart b/tests/standalone_2/io/raw_synchronous_socket_test.dart
index 3e8a86b..09f8b01 100644
--- a/tests/standalone_2/io/raw_synchronous_socket_test.dart
+++ b/tests/standalone_2/io/raw_synchronous_socket_test.dart
@@ -37,7 +37,7 @@
     Expect.isTrue(e is SocketException);
   }
 
-  // Connect to an unavaliable IP-address.
+  // Connect to an unavailable IP-address.
   try {
     var socket = RawSynchronousSocket.connectSync("1.2.3.4", 0);
     Expect.fail("Failure expected");
diff --git a/tests/standalone_2/io/secure_server_socket_test.dart b/tests/standalone_2/io/secure_server_socket_test.dart
index 010b8ac6..6fa2ccd 100644
--- a/tests/standalone_2/io/secure_server_socket_test.dart
+++ b/tests/standalone_2/io/secure_server_socket_test.dart
@@ -51,7 +51,7 @@
     asyncEnd();
   });
 
-  // Bind to an unavaliable IP-address.
+  // Bind to an unavailable IP-address.
   asyncStart();
   SecureServerSocket.bind("8.8.8.8", 0, serverContext).then((_) {
     Expect.fail("Failure expected");
diff --git a/tests/standalone_2/io/socket_invalid_bind_test.dart b/tests/standalone_2/io/socket_invalid_bind_test.dart
index efa9e65..c5a1fe88 100644
--- a/tests/standalone_2/io/socket_invalid_bind_test.dart
+++ b/tests/standalone_2/io/socket_invalid_bind_test.dart
@@ -25,7 +25,7 @@
     asyncEnd();
   });
 
-  // Bind to an unavaliable IP-address.
+  // Bind to an unavailable IP-address.
   asyncStart();
   ServerSocket.bind("8.8.8.8", 0).then((_) {
     Expect.fail("Failure expected");
diff --git a/tests/standalone_2/priority_queue_stress_test.dart b/tests/standalone_2/priority_queue_stress_test.dart
index 8b3e6b8..b991dc5 100644
--- a/tests/standalone_2/priority_queue_stress_test.dart
+++ b/tests/standalone_2/priority_queue_stress_test.dart
@@ -85,7 +85,7 @@
  * The queue guarantees that nodes are returned in the same order they
  * are added for a given priority.
  * For type safety this queue is guarded by the elements being subclasses of
- * TypedElement - this is not strictly neccesary since we never actually
+ * TypedElement - this is not strictly necessary since we never actually
  * use the value or type of the nodes.
  */
 class PriorityQueue<N extends TypedElement, P extends Priority> {
@@ -154,7 +154,7 @@
 
 /**
  * Implements a specialized priority queue that efficiently allows getting
- * the highest priorized node that adheres to a set of restrictions.
+ * the highest prioritized node that adheres to a set of restrictions.
  * Most notably it allows to get the highest priority node where the node's
  * type is not in an exclude list.
  * In addition, the queue has a number of properties:
@@ -169,7 +169,7 @@
  */
 class RestrictViewPriorityQueue<N extends TypedElement, P extends Priority> {
   // We can't use the basic dart priority queue since it does not guarantee
-  // FIFO for items with the same order. This is currently not uptimized for
+  // FIFO for items with the same order. This is currently not optimized for
   // different N, if many different N is expected here we should have a
   // priority queue instead of a list.
   List<PriorityQueue<N, P>> restrictedQueues = new List<PriorityQueue<N, P>>();
diff --git a/tests/web/regress/issue/40349_test.dart b/tests/web/regress/issue/40349_test.dart
index 83b8797..c47bb54 100644
--- a/tests/web/regress/issue/40349_test.dart
+++ b/tests/web/regress/issue/40349_test.dart
@@ -13,7 +13,7 @@
 /// a broken invariant of the SSA generate-at-use logic.
 
 void main() {
-  // `x` which is used multiple times after inilining, so a temporary is used.
+  // `x` which is used multiple times after inlining, so a temporary is used.
   x.method(40);
 }
 
diff --git a/tests/web/regress/issue/49287_test.dart b/tests/web/regress/issue/49287_test.dart
index 08e94e7..05d2ef1 100644
--- a/tests/web/regress/issue/49287_test.dart
+++ b/tests/web/regress/issue/49287_test.dart
@@ -10,7 +10,7 @@
 
 // This test contains a huge number of large strings that are predominantly code
 // points that require surrogate pairs. The hope is that if there is an encoding
-// issue like #49287 where a split surrgote pair is converted to U+FFFD
+// issue like #49287 where a split surrogate pair is converted to U+FFFD
 // REPLACEMENT CHARACTER, this will appear in the constructed string that
 // otherwise does not contain U+FFFD.
 
diff --git a/tests/web_2/regress/issue/40349_test.dart b/tests/web_2/regress/issue/40349_test.dart
index 50316bc..2827ac3 100644
--- a/tests/web_2/regress/issue/40349_test.dart
+++ b/tests/web_2/regress/issue/40349_test.dart
@@ -15,7 +15,7 @@
 /// a broken invariant of the SSA generate-at-use logic.
 
 void main() {
-  // `x` which is used multiple times after inilining, so a temporary is used.
+  // `x` which is used multiple times after inlining, so a temporary is used.
   x.method(40);
 }
 
diff --git a/tools/VERSION b/tools/VERSION
index 8251f4b..d5426d3 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 19
 PATCH 0
-PRERELEASE 33
+PRERELEASE 34
 PRERELEASE_PATCH 0
\ No newline at end of file