Version 2.18.0-69.0.dev

Merge commit 'c4c9dc599451f95cc0f845cc4d15387ec7310621' into 'dev'
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 435f11f..a446cae 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -84,7 +84,7 @@
 /// TODO(scheglov) Clean up the list of implicitly analyzed files.
 class AnalysisDriver implements AnalysisDriverGeneric {
   /// The version of data format, should be incremented on every format change.
-  static const int DATA_VERSION = 216;
+  static const int DATA_VERSION = 217;
 
   /// The number of exception contexts allowed to write. Once this field is
   /// zero, we stop writing any new exception contexts in this process.
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index c203686..cf1c0fb 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -2343,6 +2343,14 @@
     setModifier(Modifier.SYNTHETIC, isSynthetic);
   }
 
+  bool get isTempAugmentation {
+    return hasModifier(Modifier.TEMP_AUGMENTATION);
+  }
+
+  set isTempAugmentation(bool value) {
+    setModifier(Modifier.TEMP_AUGMENTATION, value);
+  }
+
   @override
   LibraryElementImpl? get library => thisOrAncestorOfType();
 
@@ -4373,6 +4381,10 @@
   /// will be marked as being synthetic.
   static const Modifier SYNTHETIC = Modifier('SYNTHETIC', 24);
 
+  /// Indicates that the element was appended to this enclosing element to
+  /// simulate temporary the effect of applying augmentation.
+  static const Modifier TEMP_AUGMENTATION = Modifier('TEMP_AUGMENTATION', 25);
+
   static const List<Modifier> values = [
     ABSTRACT,
     ASYNCHRONOUS,
@@ -4396,7 +4408,8 @@
     SETTER,
     STATIC,
     SIMPLY_BOUNDED,
-    SYNTHETIC
+    SYNTHETIC,
+    TEMP_AUGMENTATION,
   ];
 
   /// The name of this modifier.
diff --git a/pkg/analyzer/lib/src/summary2/element_flags.dart b/pkg/analyzer/lib/src/summary2/element_flags.dart
index b489c33..9481899 100644
--- a/pkg/analyzer/lib/src/summary2/element_flags.dart
+++ b/pkg/analyzer/lib/src/summary2/element_flags.dart
@@ -35,6 +35,7 @@
   static const int _isExternal = 1 << 1;
   static const int _isFactory = 1 << 2;
   static const int _isSynthetic = 1 << 3;
+  static const int _isTempAugmentation = 1 << 4;
 
   static void read(SummaryDataReader reader, ConstructorElementImpl element) {
     var byte = reader.readByte();
@@ -42,6 +43,7 @@
     element.isExternal = (byte & _isExternal) != 0;
     element.isFactory = (byte & _isFactory) != 0;
     element.isSynthetic = (byte & _isSynthetic) != 0;
+    element.isTempAugmentation = (byte & _isTempAugmentation) != 0;
   }
 
   static void write(BufferedSink sink, ConstructorElementImpl element) {
@@ -50,6 +52,7 @@
     result |= element.isExternal ? _isExternal : 0;
     result |= element.isFactory ? _isFactory : 0;
     result |= element.isSynthetic ? _isSynthetic : 0;
+    result |= element.isTempAugmentation ? _isTempAugmentation : 0;
     sink.writeByte(result);
   }
 }
@@ -82,6 +85,7 @@
   static const int _isLate = 1 << 9;
   static const int _isStatic = 1 << 10;
   static const int _isSynthetic = 1 << 11;
+  static const int _isTempAugmentation = 1 << 12;
 
   static void read(SummaryDataReader reader, FieldElementImpl element) {
     var byte = reader.readUInt30();
@@ -97,6 +101,7 @@
     element.isLate = (byte & _isLate) != 0;
     element.isStatic = (byte & _isStatic) != 0;
     element.isSynthetic = (byte & _isSynthetic) != 0;
+    element.isTempAugmentation = (byte & _isTempAugmentation) != 0;
   }
 
   static void write(BufferedSink sink, FieldElementImpl element) {
@@ -113,6 +118,7 @@
     result |= element.isLate ? _isLate : 0;
     result |= element.isStatic ? _isStatic : 0;
     result |= element.isSynthetic ? _isSynthetic : 0;
+    result |= element.isTempAugmentation ? _isTempAugmentation : 0;
     sink.writeUInt30(result);
   }
 }
@@ -265,6 +271,7 @@
   static const int _isExternal = 1 << 6;
   static const int _isGenerator = 1 << 7;
   static const int _isStatic = 1 << 8;
+  static const int _isTempAugmentation = 1 << 9;
 
   static void read(
     SummaryDataReader reader,
@@ -280,6 +287,7 @@
     element.isExternal = (byte & _isExternal) != 0;
     element.isGenerator = (byte & _isGenerator) != 0;
     element.isStatic = (byte & _isStatic) != 0;
+    element.isTempAugmentation = (byte & _isTempAugmentation) != 0;
   }
 
   static void write(BufferedSink sink, PropertyAccessorElementImpl element) {
@@ -293,6 +301,7 @@
     result |= element.isExternal ? _isExternal : 0;
     result |= element.isGenerator ? _isGenerator : 0;
     result |= element.isStatic ? _isStatic : 0;
+    result |= element.isTempAugmentation ? _isTempAugmentation : 0;
     sink.writeUInt30(result);
   }
 }
diff --git a/pkg/analyzer/lib/src/summary2/library_builder.dart b/pkg/analyzer/lib/src/summary2/library_builder.dart
index 8864dac..7fcbfcc 100644
--- a/pkg/analyzer/lib/src/summary2/library_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/library_builder.dart
@@ -6,6 +6,7 @@
 import 'package:analyzer/dart/analysis/utilities.dart';
 import 'package:analyzer/dart/ast/ast.dart' as ast;
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/visitor.dart';
 import 'package:analyzer/src/dart/ast/ast.dart' as ast;
 import 'package:analyzer/src/dart/ast/mixin_super_invoked_names.dart';
 import 'package:analyzer/src/dart/element/element.dart';
@@ -53,6 +54,19 @@
 
   final List<Export> exporters = [];
 
+  late final LibraryMacroApplier? _macroApplier = () {
+    if (!element.featureSet.isEnabled(Feature.macros)) {
+      return null;
+    }
+
+    final macroExecutor = linker.macroExecutor;
+    if (macroExecutor == null) {
+      return null;
+    }
+
+    return LibraryMacroApplier(macroExecutor, this);
+  }();
+
   LibraryBuilder._({
     required this.linker,
     required this.uri,
@@ -177,19 +191,85 @@
     }
   }
 
+  Future<void> executeMacroDeclarationsPhase() async {
+    final macroApplier = _macroApplier;
+    if (macroApplier == null) {
+      return;
+    }
+
+    final augmentationLibrary = await macroApplier.executeDeclarationsPhase();
+    if (augmentationLibrary == null) {
+      return;
+    }
+
+    final parseResult = parseString(
+      content: augmentationLibrary,
+      featureSet: element.featureSet,
+      throwIfDiagnostics: false,
+    );
+    final unitNode = parseResult.unit as ast.CompilationUnitImpl;
+
+    // We don't actually keep this unit, but we need it for now as a container.
+    // Eventually we will use actual augmentation libraries.
+    final unitUri = uri.resolve('_macro_declarations.dart');
+    final unitReference = reference.getChild('@unit').getChild('$unitUri');
+    final unitElement = CompilationUnitElementImpl(
+      source: _sourceFactory.forUri2(unitUri)!,
+      librarySource: element.source,
+      lineInfo: parseResult.lineInfo,
+    )
+      ..enclosingElement = element
+      ..isSynthetic = true
+      ..uri = unitUri.toString();
+
+    final elementBuilder = ElementBuilder(
+      libraryBuilder: this,
+      unitReference: unitReference,
+      unitElement: unitElement,
+    );
+    elementBuilder.buildDeclarationElements(unitNode);
+
+    // We move elements, so they don't have real offsets.
+    unitElement.accept(_FlushElementOffsets());
+
+    final nodesToBuildType = NodesToBuildType();
+    final resolver = ReferenceResolver(linker, nodesToBuildType, element);
+    unitNode.accept(resolver);
+    TypesBuilder(linker).build(nodesToBuildType);
+
+    // Transplant built elements as if the augmentation was applied.
+    for (final augmentation in unitElement.classes) {
+      // TODO(scheglov) if augmentation
+      final augmented = element.getType(augmentation.name);
+      if (augmented is ClassElementImpl) {
+        augmented.accessors = [
+          ...augmented.accessors,
+          ...augmentation.accessors,
+        ];
+        augmented.constructors = [
+          ...augmented.constructors,
+          ...augmentation.constructors.where((e) => !e.isSynthetic),
+        ];
+        augmented.fields = [
+          ...augmented.fields,
+          ...augmentation.fields,
+        ];
+        augmented.methods = [
+          ...augmented.methods,
+          ...augmentation.methods,
+        ];
+      }
+    }
+  }
+
   Future<void> executeMacroTypesPhase() async {
-    if (!element.featureSet.isEnabled(Feature.macros)) {
+    final macroApplier = _macroApplier;
+    if (macroApplier == null) {
       return;
     }
 
-    final macroExecutor = linker.macroExecutor;
-    if (macroExecutor == null) {
-      return;
-    }
-
-    var applier = LibraryMacroApplier(macroExecutor, this);
-    await applier.buildApplications();
-    var augmentationLibrary = await applier.executeTypesPhase();
+    await macroApplier.buildApplications();
+    var augmentationLibrary = await macroApplier.executeTypesPhase();
     if (augmentationLibrary == null) {
       return;
     }
@@ -395,3 +475,16 @@
     required this.element,
   });
 }
+
+class _FlushElementOffsets extends GeneralizingElementVisitor<void> {
+  @override
+  void visitElement(covariant ElementImpl element) {
+    element.isTempAugmentation = true;
+    element.nameOffset = -1;
+    if (element is ConstructorElementImpl) {
+      element.periodOffset = null;
+      element.nameEnd = null;
+    }
+    super.visitElement(element);
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary2/link.dart b/pkg/analyzer/lib/src/summary2/link.dart
index b68a8cf..7c4a048 100644
--- a/pkg/analyzer/lib/src/summary2/link.dart
+++ b/pkg/analyzer/lib/src/summary2/link.dart
@@ -98,6 +98,7 @@
     _createTypeSystem();
     _resolveTypes();
     _buildEnumChildren();
+    await _executeMacroDeclarationsPhase();
     SuperConstructorResolver(this).perform();
     _performTopLevelInference();
     _resolveConstructors();
@@ -195,6 +196,12 @@
     }
   }
 
+  Future<void> _executeMacroDeclarationsPhase() async {
+    for (final library in builders.values) {
+      await library.executeMacroDeclarationsPhase();
+    }
+  }
+
   void _performTopLevelInference() {
     TopLevelInference(this).infer();
   }
diff --git a/pkg/analyzer/lib/src/summary2/macro.dart b/pkg/analyzer/lib/src/summary2/macro.dart
index c9931b4..a87f832 100644
--- a/pkg/analyzer/lib/src/summary2/macro.dart
+++ b/pkg/analyzer/lib/src/summary2/macro.dart
@@ -94,6 +94,15 @@
     this._declaration,
   );
 
+  Future<macro.MacroExecutionResult> executeDeclarationsPhase({
+    required macro.TypeResolver typeResolver,
+    required macro.ClassIntrospector classIntrospector,
+  }) async {
+    macro.MacroExecutor executor = _bundleExecutor.macroExecutor;
+    return await executor.executeDeclarationsPhase(_instanceIdentifier,
+        _declaration, _identifierResolver, typeResolver, classIntrospector);
+  }
+
   Future<macro.MacroExecutionResult> executeTypesPhase() async {
     macro.MacroExecutor executor = _bundleExecutor.macroExecutor;
     return await executor.executeTypesPhase(
diff --git a/pkg/analyzer/lib/src/summary2/macro_application.dart b/pkg/analyzer/lib/src/summary2/macro_application.dart
index 15da245..d18910f 100644
--- a/pkg/analyzer/lib/src/summary2/macro_application.dart
+++ b/pkg/analyzer/lib/src/summary2/macro_application.dart
@@ -27,6 +27,10 @@
 
   final Map<ClassDeclaration, macro.ClassDeclaration> _classDeclarations = {};
 
+  final macro.TypeResolver _typeResolver = _TypeResolver();
+
+  final macro.ClassIntrospector _classIntrospector = _ClassIntrospector();
+
   LibraryMacroApplier(this.macroExecutor, this.libraryBuilder);
 
   Linker get _linker => libraryBuilder.linker;
@@ -49,8 +53,51 @@
     }
   }
 
+  Future<String?> executeDeclarationsPhase() async {
+    final results = <macro.MacroExecutionResult>[];
+    for (final unitElement in libraryBuilder.element.units) {
+      for (final classElement in unitElement.classes) {
+        classElement as ClassElementImpl;
+        final applications = _applications[classElement];
+        if (applications != null) {
+          for (final application in applications) {
+            if (application.shouldExecute(macro.Phase.declarations)) {
+              await _runWithCatchingExceptions(
+                () async {
+                  final result =
+                      await application.instance.executeDeclarationsPhase(
+                    typeResolver: _typeResolver,
+                    classIntrospector: _classIntrospector,
+                  );
+                  if (result.isNotEmpty) {
+                    results.add(result);
+                  }
+                },
+                annotationIndex: application.annotationIndex,
+                onError: (error) {
+                  classElement.macroApplicationErrors.add(error);
+                },
+              );
+            }
+          }
+        }
+      }
+    }
+
+    if (results.isNotEmpty) {
+      final code = macroExecutor.buildAugmentationLibrary(
+        results,
+        _resolveIdentifier,
+        _inferOmittedType,
+      );
+      return code.trim();
+    }
+    return null;
+  }
+
   Future<String?> executeTypesPhase() async {
     final results = <macro.MacroExecutionResult>[];
+    // TODO(scheglov) Share the elements iteration logic.
     for (final unitElement in libraryBuilder.element.units) {
       for (final classElement in unitElement.classes) {
         classElement as ClassElementImpl;
@@ -121,7 +168,7 @@
                 className: macroElement.name,
                 constructorName: '', // TODO
                 arguments: arguments,
-                identifierResolver: _FakeIdentifierResolver(),
+                identifierResolver: _IdentifierResolver(),
                 declarationKind: macro.DeclarationKind.clazz,
                 declaration: declaration,
               );
@@ -448,10 +495,45 @@
   }
 }
 
-class _FakeIdentifierResolver extends macro.IdentifierResolver {
+class _ClassIntrospector implements macro.ClassIntrospector {
   @override
-  Future<macro.Identifier> resolveIdentifier(Uri library, String name) {
-    // TODO: implement resolveIdentifier
+  Future<List<macro.ConstructorDeclaration>> constructorsOf(
+      covariant macro.ClassDeclaration clazz) {
+    // TODO: implement constructorsOf
+    throw UnimplementedError();
+  }
+
+  @override
+  Future<List<macro.FieldDeclaration>> fieldsOf(macro.ClassDeclaration clazz) {
+    // TODO: implement fieldsOf
+    throw UnimplementedError();
+  }
+
+  @override
+  Future<List<macro.ClassDeclaration>> interfacesOf(
+      covariant macro.ClassDeclaration clazz) {
+    // TODO: implement interfacesOf
+    throw UnimplementedError();
+  }
+
+  @override
+  Future<List<macro.MethodDeclaration>> methodsOf(
+      covariant macro.ClassDeclaration clazz) {
+    // TODO: implement methodsOf
+    throw UnimplementedError();
+  }
+
+  @override
+  Future<List<macro.ClassDeclaration>> mixinsOf(
+      covariant macro.ClassDeclaration clazz) {
+    // TODO: implement mixinsOf
+    throw UnimplementedError();
+  }
+
+  @override
+  Future<macro.ClassDeclaration?> superclassOf(
+      covariant macro.ClassDeclaration clazz) {
+    // TODO: implement superclassOf
     throw UnimplementedError();
   }
 }
@@ -461,6 +543,22 @@
       : super(id: id, name: name);
 }
 
+class _IdentifierResolver extends macro.IdentifierResolver {
+  @override
+  Future<macro.Identifier> resolveIdentifier(Uri library, String name) {
+    // TODO: implement resolveIdentifier
+    throw UnimplementedError();
+  }
+}
+
+class _TypeResolver implements macro.TypeResolver {
+  @override
+  Future<macro.StaticType> resolve(macro.TypeAnnotationCode type) {
+    // TODO: implement resolve
+    throw UnimplementedError();
+  }
+}
+
 extension on macro.MacroExecutionResult {
   bool get isNotEmpty =>
       libraryAugmentations.isNotEmpty || classAugmentations.isNotEmpty;
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index cfe45a8..e162fb4 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -415,7 +415,9 @@
       expect(e.nameOffset, -1);
       expect(e.nonSynthetic, same(e.enclosingElement));
     } else {
-      expect(e.nameOffset, isPositive);
+      if (!e.isTempAugmentation) {
+        expect(e.nameOffset, isPositive);
+      }
     }
   }
 
@@ -689,6 +691,8 @@
   }
 
   void _writePropertyAccessorElement(PropertyAccessorElement e) {
+    e as PropertyAccessorElementImpl;
+
     PropertyInducingElement variable = e.variable;
     expect(variable, isNotNull);
 
@@ -714,7 +718,9 @@
     if (e.isSynthetic) {
       expect(e.nameOffset, -1);
     } else {
-      expect(e.nameOffset, isPositive);
+      if (!e.isTempAugmentation) {
+        expect(e.nameOffset, isPositive);
+      }
       _assertNonSyntheticElementSelf(e);
     }
 
@@ -747,6 +753,8 @@
   }
 
   void _writePropertyInducingElement(PropertyInducingElement e) {
+    e as PropertyInducingElementImpl;
+
     DartType type = e.type;
     expect(type, isNotNull);
 
@@ -760,7 +768,9 @@
         _assertSyntheticAccessorEnclosing(e, e.setter!);
       }
 
-      expect(e.nameOffset, isPositive);
+      if (!e.isTempAugmentation) {
+        expect(e.nameOffset, isPositive);
+      }
       _assertNonSyntheticElementSelf(e);
     }
 
diff --git a/pkg/analyzer/test/src/summary/macro_test.dart b/pkg/analyzer/test/src/summary/macro_test.dart
index e073d88..1fdc7e6 100644
--- a/pkg/analyzer/test/src/summary/macro_test.dart
+++ b/pkg/analyzer/test/src/summary/macro_test.dart
@@ -384,6 +384,279 @@
     );
   }
 
+  /// TODO(scheglov) Not quite correct - we should not add a synthetic one.
+  /// Fix it when adding actual augmentation libraries.
+  test_declarationsPhase_class_constructor() async {
+    newFile('$testPackageLibPath/a.dart', r'''
+import 'package:_fe_analyzer_shared/src/macros/api.dart';
+
+macro class MyMacro implements ClassDeclarationsMacro {
+  const MyMacro();
+
+  buildDeclarationsForClass(clazz, builder) async {
+    builder.declareInClass(
+      DeclarationCode.fromString('A.named(int a);'),
+    );
+  }
+}
+''');
+
+    var library = await buildLibrary(r'''
+import 'a.dart';
+
+@MyMacro()
+class A {}
+''', preBuildSequence: [
+      {'package:test/a.dart'}
+    ]);
+
+    checkElementText(library, r'''
+library
+  imports
+    package:test/a.dart
+  definingUnit
+    classes
+      class A @35
+        metadata
+          Annotation
+            atSign: @ @18
+            name: SimpleIdentifier
+              token: MyMacro @19
+              staticElement: package:test/a.dart::@class::MyMacro
+              staticType: null
+            arguments: ArgumentList
+              leftParenthesis: ( @26
+              rightParenthesis: ) @27
+            element: package:test/a.dart::@class::MyMacro::@constructor::•
+        constructors
+          synthetic @-1
+          named @-1
+            parameters
+              requiredPositional a @-1
+                type: int
+''');
+  }
+
+  test_declarationsPhase_class_field() async {
+    newFile('$testPackageLibPath/a.dart', r'''
+import 'package:_fe_analyzer_shared/src/macros/api.dart';
+
+macro class MyMacro implements ClassDeclarationsMacro {
+  const MyMacro();
+
+  buildDeclarationsForClass(clazz, builder) async {
+    builder.declareInClass(
+      DeclarationCode.fromString('int foo = 0;'),
+    );
+  }
+}
+''');
+
+    var library = await buildLibrary(r'''
+import 'a.dart';
+
+@MyMacro()
+class A {}
+''', preBuildSequence: [
+      {'package:test/a.dart'}
+    ]);
+
+    checkElementText(library, r'''
+library
+  imports
+    package:test/a.dart
+  definingUnit
+    classes
+      class A @35
+        metadata
+          Annotation
+            atSign: @ @18
+            name: SimpleIdentifier
+              token: MyMacro @19
+              staticElement: package:test/a.dart::@class::MyMacro
+              staticType: null
+            arguments: ArgumentList
+              leftParenthesis: ( @26
+              rightParenthesis: ) @27
+            element: package:test/a.dart::@class::MyMacro::@constructor::•
+        fields
+          foo @-1
+            type: int
+        constructors
+          synthetic @-1
+        accessors
+          synthetic get foo @-1
+            returnType: int
+          synthetic set foo @-1
+            parameters
+              requiredPositional _foo @-1
+                type: int
+            returnType: void
+''');
+  }
+
+  test_declarationsPhase_class_getter() async {
+    newFile('$testPackageLibPath/a.dart', r'''
+import 'package:_fe_analyzer_shared/src/macros/api.dart';
+
+macro class MyMacro implements ClassDeclarationsMacro {
+  const MyMacro();
+
+  buildDeclarationsForClass(clazz, builder) async {
+    builder.declareInClass(
+      DeclarationCode.fromString('int get foo => 0;'),
+    );
+  }
+}
+''');
+
+    var library = await buildLibrary(r'''
+import 'a.dart';
+
+@MyMacro()
+class A {}
+''', preBuildSequence: [
+      {'package:test/a.dart'}
+    ]);
+
+    checkElementText(library, r'''
+library
+  imports
+    package:test/a.dart
+  definingUnit
+    classes
+      class A @35
+        metadata
+          Annotation
+            atSign: @ @18
+            name: SimpleIdentifier
+              token: MyMacro @19
+              staticElement: package:test/a.dart::@class::MyMacro
+              staticType: null
+            arguments: ArgumentList
+              leftParenthesis: ( @26
+              rightParenthesis: ) @27
+            element: package:test/a.dart::@class::MyMacro::@constructor::•
+        fields
+          synthetic foo @-1
+            type: int
+        constructors
+          synthetic @-1
+        accessors
+          get foo @-1
+            returnType: int
+''');
+  }
+
+  test_declarationsPhase_class_method() async {
+    newFile('$testPackageLibPath/a.dart', r'''
+import 'package:_fe_analyzer_shared/src/macros/api.dart';
+
+macro class MyMacro implements ClassDeclarationsMacro {
+  const MyMacro();
+
+  buildDeclarationsForClass(clazz, builder) async {
+    builder.declareInClass(
+      DeclarationCode.fromString('int foo(double a) => 0;'),
+    );
+  }
+}
+''');
+
+    var library = await buildLibrary(r'''
+import 'a.dart';
+
+@MyMacro()
+class A {}
+''', preBuildSequence: [
+      {'package:test/a.dart'}
+    ]);
+
+    checkElementText(library, r'''
+library
+  imports
+    package:test/a.dart
+  definingUnit
+    classes
+      class A @35
+        metadata
+          Annotation
+            atSign: @ @18
+            name: SimpleIdentifier
+              token: MyMacro @19
+              staticElement: package:test/a.dart::@class::MyMacro
+              staticType: null
+            arguments: ArgumentList
+              leftParenthesis: ( @26
+              rightParenthesis: ) @27
+            element: package:test/a.dart::@class::MyMacro::@constructor::•
+        constructors
+          synthetic @-1
+        methods
+          foo @-1
+            parameters
+              requiredPositional a @-1
+                type: double
+            returnType: int
+''');
+  }
+
+  test_declarationsPhase_class_setter() async {
+    newFile('$testPackageLibPath/a.dart', r'''
+import 'package:_fe_analyzer_shared/src/macros/api.dart';
+
+macro class MyMacro implements ClassDeclarationsMacro {
+  const MyMacro();
+
+  buildDeclarationsForClass(clazz, builder) async {
+    builder.declareInClass(
+      DeclarationCode.fromString('set foo(int a) {}'),
+    );
+  }
+}
+''');
+
+    var library = await buildLibrary(r'''
+import 'a.dart';
+
+@MyMacro()
+class A {}
+''', preBuildSequence: [
+      {'package:test/a.dart'}
+    ]);
+
+    checkElementText(library, r'''
+library
+  imports
+    package:test/a.dart
+  definingUnit
+    classes
+      class A @35
+        metadata
+          Annotation
+            atSign: @ @18
+            name: SimpleIdentifier
+              token: MyMacro @19
+              staticElement: package:test/a.dart::@class::MyMacro
+              staticType: null
+            arguments: ArgumentList
+              leftParenthesis: ( @26
+              rightParenthesis: ) @27
+            element: package:test/a.dart::@class::MyMacro::@constructor::•
+        fields
+          synthetic foo @-1
+            type: int
+        constructors
+          synthetic @-1
+        accessors
+          set foo @-1
+            parameters
+              requiredPositional a @-1
+                type: int
+            returnType: void
+''');
+  }
+
   test_introspect_types_ClassDeclaration_interfaces() async {
     await _assertTypesPhaseIntrospectionText(r'''
 class A implements B, C<int, String> {}
@@ -535,7 +808,38 @@
 ''');
   }
 
-  test_macroApplicationErrors_compileTimeError() async {
+  test_macroApplicationErrors_declarationsPhase_throwsException() async {
+    newFile('$testPackageLibPath/a.dart', r'''
+import 'package:_fe_analyzer_shared/src/macros/api.dart';
+
+macro class MyMacro implements ClassDeclarationsMacro {
+  const MyMacro();
+
+  buildDeclarationsForClass(clazz, builder) async {
+    throw 'foo bar';
+  }
+}
+''');
+
+    final library = await buildLibrary(r'''
+import 'a.dart';
+
+@MyMacro()
+class A {}
+''', preBuildSequence: [
+      {'package:test/a.dart'}
+    ]);
+
+    final A = library.getType('A') as ClassElementImpl;
+    final error = A.macroApplicationErrors.single;
+    error as UnknownMacroApplicationError;
+
+    expect(error.annotationIndex, 0);
+    expect(error.message, 'foo bar');
+    expect(error.stackTrace, contains('MyMacro.buildDeclarationsForClass'));
+  }
+
+  test_macroApplicationErrors_typedPhase_compileTimeError() async {
     newFile('$testPackageLibPath/a.dart', r'''
 import 'package:_fe_analyzer_shared/src/macros/api.dart';
 
@@ -564,7 +868,7 @@
     expect(error.stackTrace, contains('executeTypesMacro'));
   }
 
-  test_macroApplicationErrors_throwsException() async {
+  test_macroApplicationErrors_typesPhase_throwsException() async {
     newFile('$testPackageLibPath/a.dart', r'''
 import 'package:_fe_analyzer_shared/src/macros/api.dart';
 
diff --git a/pkg/compiler/lib/src/elements/entities.dart b/pkg/compiler/lib/src/elements/entities.dart
index 5a4ac84..e55bd41 100644
--- a/pkg/compiler/lib/src/elements/entities.dart
+++ b/pkg/compiler/lib/src/elements/entities.dart
@@ -8,9 +8,11 @@
 
 // TODO(48820): Spannable was imported from `../common.dart`.
 import '../diagnostics/spannable.dart' show Spannable;
+import '../serialization/serialization_interfaces.dart';
 import '../universe/call_structure.dart' show CallStructure;
 import '../util/util.dart';
 import 'names.dart';
+import 'types.dart' show FunctionType;
 
 /// Abstract interface for entities.
 ///
@@ -352,6 +354,46 @@
     );
   }
 
+  static ParameterStructure fromType(FunctionType type) {
+    return ParameterStructure(
+        type.parameterTypes.length,
+        type.parameterTypes.length + type.optionalParameterTypes.length,
+        type.namedParameters,
+        type.requiredNamedParameters,
+        type.typeVariables.length);
+  }
+
+  /// Deserializes a [ParameterStructure] object from [source].
+  static readFromDataSource(DataSourceReader source) {
+    final tag = ParameterStructure.tag;
+    source.begin(tag);
+    int requiredPositionalParameters = source.readInt();
+    int positionalParameters = source.readInt();
+    List<String> namedParameters = source.readStrings()!;
+    Set<String> requiredNamedParameters =
+        source.readStrings(emptyAsNull: true)?.toSet() ?? const <String>{};
+    int typeParameters = source.readInt();
+    source.end(tag);
+    return ParameterStructure(
+        requiredPositionalParameters,
+        positionalParameters,
+        namedParameters,
+        requiredNamedParameters,
+        typeParameters);
+  }
+
+  /// Serializes this [ParameterStructure] to [sink].
+  void writeToDataSink(DataSinkWriter sink) {
+    final tag = ParameterStructure.tag;
+    sink.begin(tag);
+    sink.writeInt(requiredPositionalParameters);
+    sink.writeInt(positionalParameters);
+    sink.writeStrings(namedParameters);
+    sink.writeStrings(requiredNamedParameters);
+    sink.writeInt(typeParameters);
+    sink.end(tag);
+  }
+
   /// The number of optional parameters (positional or named).
   int get optionalParameters =>
       (positionalParameters - requiredPositionalParameters) +
diff --git a/pkg/compiler/lib/src/elements/entities_parameter_structure_methods.dart b/pkg/compiler/lib/src/elements/entities_parameter_structure_methods.dart
deleted file mode 100644
index bf75cbe..0000000
--- a/pkg/compiler/lib/src/elements/entities_parameter_structure_methods.dart
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2016, 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.10
-
-/// Methods for [ParameterStructure] that have not yet been migrated to null
-/// safety.
-// TODO(48820): Move these methods back to [ParameterStructure].
-library entities.parameter_structure_methods;
-
-import '../serialization/serialization.dart';
-import 'entities.dart';
-import 'types.dart' show FunctionType;
-
-extension UnmigratedParameterStructureInstanceMethods on ParameterStructure {
-  /// Serializes this [ParameterStructure] to [sink].
-  void writeToDataSink(DataSinkWriter sink) {
-    final tag = ParameterStructure.tag;
-    sink.begin(tag);
-    sink.writeInt(requiredPositionalParameters);
-    sink.writeInt(positionalParameters);
-    sink.writeStrings(namedParameters);
-    sink.writeStrings(requiredNamedParameters);
-    sink.writeInt(typeParameters);
-    sink.end(tag);
-  }
-}
-
-class ParameterStructureMethods {
-  static ParameterStructure fromType(FunctionType type) {
-    return ParameterStructure(
-        type.parameterTypes.length,
-        type.parameterTypes.length + type.optionalParameterTypes.length,
-        type.namedParameters,
-        type.requiredNamedParameters,
-        type.typeVariables.length);
-  }
-
-  /// Deserializes a [ParameterStructure] object from [source].
-  static readFromDataSource(DataSourceReader source) {
-    final tag = ParameterStructure.tag;
-    source.begin(tag);
-    int requiredPositionalParameters = source.readInt();
-    int positionalParameters = source.readInt();
-    List<String> namedParameters = source.readStrings() /*!*/;
-    Set<String> requiredNamedParameters =
-        source.readStrings(emptyAsNull: true)?.toSet() ?? const <String>{};
-    int typeParameters = source.readInt();
-    source.end(tag);
-    return ParameterStructure(
-        requiredPositionalParameters,
-        positionalParameters,
-        namedParameters,
-        requiredNamedParameters,
-        typeParameters);
-  }
-}
diff --git a/pkg/compiler/lib/src/ir/closure.dart b/pkg/compiler/lib/src/ir/closure.dart
index 20c6948..d409cb6 100644
--- a/pkg/compiler/lib/src/ir/closure.dart
+++ b/pkg/compiler/lib/src/ir/closure.dart
@@ -2,8 +2,6 @@
 // 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.10
-
 import 'package:kernel/ast.dart' as ir;
 import 'package:kernel/src/printer.dart' as ir;
 import 'package:kernel/text/ast_to_text.dart' as ir show debugNodeToString;
@@ -11,7 +9,7 @@
 /// Collection of scope data collected for a single member.
 class ClosureScopeModel {
   /// Collection [ScopeInfo] data for the member.
-  KernelScopeInfo scopeInfo;
+  KernelScopeInfo? scopeInfo;
 
   /// Collected [CapturedScope] data for nodes.
   Map<ir.Node, KernelCapturedScope> capturedScopesMap =
@@ -33,7 +31,7 @@
   final Set<ir.VariableDeclaration> boxedVariables;
   // If boxedVariables is empty, this will be null, because no variables will
   // need to be boxed.
-  final NodeBox capturedVariablesAccessor;
+  final NodeBox? capturedVariablesAccessor;
 
   /// The set of variables that were defined in another scope, but are used in
   /// this scope. The items in this set are either of type VariableDeclaration
@@ -101,7 +99,7 @@
 class KernelCapturedScope extends KernelScopeInfo {
   KernelCapturedScope(
       Set<ir.VariableDeclaration> boxedVariables,
-      NodeBox capturedVariablesAccessor,
+      NodeBox? capturedVariablesAccessor,
       Set<ir.VariableDeclaration> localsUsedInTryOrSync,
       Set<ir.Node /* VariableDeclaration | TypeVariableTypeWithContext */ >
           freeVariables,
@@ -126,8 +124,8 @@
             _empty,
             null,
             _empty,
-            scope.freeVariables.where(
-                (ir.Node variable) => variable is TypeVariableTypeWithContext),
+            Set.of(scope.freeVariables.where(
+                (ir.Node variable) => variable is TypeVariableTypeWithContext)),
             scope.freeVariablesForRti,
             scope.thisUsedAsFreeVariable,
             scope.thisUsedAsFreeVariableIfNeedsRti,
@@ -144,7 +142,7 @@
 
   KernelCapturedLoopScope(
       Set<ir.VariableDeclaration> boxedVariables,
-      NodeBox capturedVariablesAccessor,
+      NodeBox? capturedVariablesAccessor,
       this.boxedLoopVariables,
       Set<ir.VariableDeclaration> localsUsedInTryOrSync,
       Set<ir.Node /* VariableDeclaration | TypeVariableTypeWithContext */ >
@@ -230,10 +228,10 @@
 
 class VariableUse {
   final VariableUseKind kind;
-  final ir.Member member;
-  final ir.LocalFunction localFunction;
-  final ir.Expression invocation;
-  final ir.Instantiation instantiation;
+  final ir.Member? member;
+  final ir.LocalFunction? localFunction;
+  final ir.Expression? invocation;
+  final ir.Instantiation? instantiation;
 
   const VariableUse._simple(this.kind)
       : this.member = null,
@@ -345,48 +343,51 @@
 /// A fake ir.Node that holds the TypeParameterType as well as the context in
 /// which it occurs.
 class TypeVariableTypeWithContext implements ir.Node {
-  final ir.TreeNode context;
+  final ir.TreeNode? context;
   final ir.TypeParameterType type;
   final TypeVariableKind kind;
-  final ir.TreeNode typeDeclaration;
+  final ir.TreeNode? typeDeclaration;
 
   /// [context] can be either an ir.Member or a ir.FunctionDeclaration or
   /// ir.FunctionExpression.
   factory TypeVariableTypeWithContext(
-      ir.TypeParameterType type, ir.TreeNode context) {
+      ir.TypeParameterType type, ir.TreeNode? context) {
     TypeVariableKind kind;
-    ir.TreeNode typeDeclaration = type.parameter.parent;
+    ir.TreeNode? typeDeclaration = type.parameter.parent;
     if (typeDeclaration == null) {
       // We have a function type variable, like `T` in `void Function<T>(int)`.
       kind = TypeVariableKind.function;
     } else if (typeDeclaration is ir.Class) {
       // We have a class type variable, like `T` in `class Class<T> { ... }`.
       kind = TypeVariableKind.cls;
-    } else if (typeDeclaration.parent is ir.Member) {
-      ir.Member member = typeDeclaration.parent;
-      if (member is ir.Constructor ||
-          (member is ir.Procedure && member.isFactory)) {
-        // We have a synthesized generic method type variable for a class type
-        // variable.
-        // TODO(johnniwinther): Handle constructor/factory type variables as
-        // method type variables.
-        kind = TypeVariableKind.cls;
-        typeDeclaration = member.enclosingClass;
+    } else {
+      final parent = typeDeclaration.parent;
+      if (parent is ir.Member) {
+        ir.Member member = parent;
+        if (member is ir.Constructor ||
+            (member is ir.Procedure && member.isFactory)) {
+          // We have a synthesized generic method type variable for a class type
+          // variable.
+          // TODO(johnniwinther): Handle constructor/factory type variables as
+          // method type variables.
+          kind = TypeVariableKind.cls;
+          typeDeclaration = member.enclosingClass;
+        } else {
+          // We have a generic method type variable, like `T` in
+          // `m<T>() { ... }`.
+          kind = TypeVariableKind.method;
+          typeDeclaration = parent;
+          context = typeDeclaration;
+        }
       } else {
-        // We have a generic method type variable, like `T` in
-        // `m<T>() { ... }`.
-        kind = TypeVariableKind.method;
-        typeDeclaration = typeDeclaration.parent;
+        // We have a generic local function type variable, like `T` in
+        // `m() { local<T>() { ... } ... }`.
+        assert(parent is ir.LocalFunction,
+            "Unexpected type declaration: $typeDeclaration");
+        kind = TypeVariableKind.local;
+        typeDeclaration = parent;
         context = typeDeclaration;
       }
-    } else {
-      // We have a generic local function type variable, like `T` in
-      // `m() { local<T>() { ... } ... }`.
-      assert(typeDeclaration.parent is ir.LocalFunction,
-          "Unexpected type declaration: $typeDeclaration");
-      kind = TypeVariableKind.local;
-      typeDeclaration = typeDeclaration.parent;
-      context = typeDeclaration;
     }
     return TypeVariableTypeWithContext.internal(
         type, context, kind, typeDeclaration);
@@ -424,8 +425,8 @@
 
   @override
   String toStringInternal() =>
-      'type=${type.toStringInternal()},context=${context.toStringInternal()},'
-      'kind=$kind,typeDeclaration=${typeDeclaration.toStringInternal()}';
+      'type=${type.toStringInternal()},context=${context!.toStringInternal()},'
+      'kind=$kind,typeDeclaration=${typeDeclaration!.toStringInternal()}';
 
   @override
   String toText(ir.AstTextStrategy strategy) => type.toText(strategy);
diff --git a/pkg/compiler/lib/src/ir/constants.dart b/pkg/compiler/lib/src/ir/constants.dart
index e799ea2..32c12a0 100644
--- a/pkg/compiler/lib/src/ir/constants.dart
+++ b/pkg/compiler/lib/src/ir/constants.dart
@@ -2,8 +2,6 @@
 // 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.10
-
 import 'package:front_end/src/api_prototype/constant_evaluator.dart' as ir;
 import 'package:front_end/src/api_unstable/dart2js.dart' as ir;
 import 'package:kernel/ast.dart' as ir;
@@ -14,20 +12,18 @@
 import '../kernel/dart2js_target.dart';
 
 typedef ReportErrorFunction = void Function(
-    ir.LocatedMessage message, List<ir.LocatedMessage> context);
+    ir.LocatedMessage message, List<ir.LocatedMessage>? context);
 
 class Dart2jsConstantEvaluator extends ir.ConstantEvaluator {
   final bool _supportReevaluationForTesting;
 
-  bool requiresConstant;
-
   Dart2jsConstantEvaluator(ir.Component component,
       ir.TypeEnvironment typeEnvironment, ReportErrorFunction reportError,
-      {Environment environment,
+      {Environment? environment,
       bool supportReevaluationForTesting = false,
-      ir.EvaluationMode evaluationMode})
+      required ir.EvaluationMode evaluationMode})
       : _supportReevaluationForTesting = supportReevaluationForTesting,
-        assert(evaluationMode != null),
+        assert((evaluationMode as dynamic) != null),
         super(
             const Dart2jsDartLibrarySupport(),
             const Dart2jsConstantsBackend(supportsUnevaluatedConstants: false),
@@ -39,7 +35,20 @@
             evaluationMode: evaluationMode);
 
   @override
-  ErrorReporter get errorReporter => super.errorReporter;
+  ErrorReporter get errorReporter => super.errorReporter as ErrorReporter;
+  // TODO(48820): ^Store another reference to the error reporter with the
+  // refined type and use that.
+
+  // We can't override [ir.ConstantEvaluator.evaluate] and have a nullable
+  // return type.
+  // TODO(48820): Consider using composition. We will need to ensure that
+  // [Dart2jsConstantEvaluator] is not referenced via [ir.ConstantEvaluator].
+  @override
+  ir.Constant evaluate(
+      ir.StaticTypeContext staticTypeContext, ir.Expression node,
+      {ir.TreeNode? contextNode}) {
+    return evaluateOrNull(staticTypeContext, node, contextNode: contextNode)!;
+  }
 
   /// Evaluates [node] to a constant in the given [staticTypeContext].
   ///
@@ -50,10 +59,9 @@
   /// expression but evaluates to a constant, [node] is replaced with an
   /// [ir.ConstantExpression] holding the constant. Otherwise the [node] is not
   /// replaced even when it evaluated to a constant.
-  @override
-  ir.Constant evaluate(
+  ir.Constant? evaluateOrNull(
       ir.StaticTypeContext staticTypeContext, ir.Expression node,
-      {ir.TreeNode contextNode,
+      {ir.TreeNode? contextNode,
       bool requireConstant = true,
       bool replaceImplicitConstant = true}) {
     errorReporter.requiresConstant = requireConstant;
@@ -84,7 +92,7 @@
             constant.expression is ir.InvalidExpression) {
           return null;
         }
-        if (constant != null && replaceImplicitConstant) {
+        if (replaceImplicitConstant) {
           // Note: Using [replaceWith] is slow and should be avoided.
           node.replaceWith(ir.ConstantExpression(
               constant, node.getStaticType(staticTypeContext))
@@ -100,12 +108,12 @@
 
 class ErrorReporter implements ir.ErrorReporter {
   final ReportErrorFunction _reportError;
-  bool requiresConstant;
+  late bool requiresConstant;
 
   ErrorReporter(this._reportError);
 
   @override
-  void report(ir.LocatedMessage message, [List<ir.LocatedMessage> context]) {
+  void report(ir.LocatedMessage message, [List<ir.LocatedMessage>? context]) {
     if (requiresConstant) {
       _reportError(message, context);
     }
diff --git a/pkg/compiler/lib/src/ir/scope.dart b/pkg/compiler/lib/src/ir/scope.dart
index cfd2ec9..6f2deb9 100644
--- a/pkg/compiler/lib/src/ir/scope.dart
+++ b/pkg/compiler/lib/src/ir/scope.dart
@@ -2,29 +2,28 @@
 // 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.10
-
 import 'package:kernel/ast.dart' as ir;
 import 'closure.dart';
+import 'constants.dart' show Dart2jsConstantEvaluator;
 import 'scope_visitor.dart';
 import 'package:front_end/src/api_prototype/constant_evaluator.dart' as ir;
 
 class ScopeModel {
-  final ClosureScopeModel closureScopeModel;
-  final VariableScopeModel variableScopeModel;
+  final ClosureScopeModel? closureScopeModel;
+  final VariableScopeModel? variableScopeModel;
   final EvaluationComplexity initializerComplexity;
 
   const ScopeModel(
       {this.closureScopeModel,
       this.variableScopeModel,
-      this.initializerComplexity})
-      : assert(initializerComplexity != null);
+      required this.initializerComplexity});
 
   /// Inspect members and mark if those members capture any state that needs to
   /// be marked as free variables.
   factory ScopeModel.from(
       ir.Member node, ir.ConstantEvaluator constantEvaluator) {
-    ScopeModelBuilder builder = ScopeModelBuilder(constantEvaluator);
+    ScopeModelBuilder builder =
+        ScopeModelBuilder(constantEvaluator as Dart2jsConstantEvaluator);
     return builder.computeModel(node);
   }
 }
@@ -36,21 +35,20 @@
 }
 
 class VariableScopeModelImpl implements VariableScopeModel {
-  final Map<ir.TreeNode, VariableScope> _scopeMap = {};
-  Set<ir.VariableDeclaration> _assignedVariables;
+  final Map<ir.TreeNode, VariableScopeImpl> _scopeMap = {};
+  Set<ir.VariableDeclaration>? _assignedVariables;
 
-  VariableScope createScopeFor(ir.TreeNode node) {
+  VariableScopeImpl createScopeFor(ir.TreeNode node) {
     return _scopeMap[node] ??= VariableScopeImpl();
   }
 
   void registerAssignedVariable(ir.VariableDeclaration node) {
-    _assignedVariables ??= Set<ir.VariableDeclaration>();
-    _assignedVariables.add(node);
+    (_assignedVariables ??= {}).add(node);
   }
 
   @override
   VariableScope getScopeFor(ir.TreeNode node) {
-    return _scopeMap[node];
+    return _scopeMap[node]!;
   }
 
   @override
@@ -59,7 +57,7 @@
 
   @override
   bool isEffectivelyFinal(ir.VariableDeclaration node) {
-    return _assignedVariables == null || !_assignedVariables.contains(node);
+    return _assignedVariables == null || !_assignedVariables!.contains(node);
   }
 }
 
@@ -74,28 +72,28 @@
 }
 
 class VariableScopeImpl implements VariableScope {
-  List<VariableScope> _subScopes;
-  Set<ir.VariableDeclaration> _assignedVariables;
+  List<VariableScope>? _subScopes;
+  Set<ir.VariableDeclaration>? _assignedVariables;
   @override
   bool hasContinueSwitch = false;
 
   void addSubScope(VariableScope scope) {
     _subScopes ??= <VariableScope>[];
-    _subScopes.add(scope);
+    _subScopes!.add(scope);
   }
 
   void registerAssignedVariable(ir.VariableDeclaration variable) {
     _assignedVariables ??= Set<ir.VariableDeclaration>();
-    _assignedVariables.add(variable);
+    _assignedVariables!.add(variable);
   }
 
   @override
   Iterable<ir.VariableDeclaration> get assignedVariables sync* {
     if (_assignedVariables != null) {
-      yield* _assignedVariables;
+      yield* _assignedVariables!;
     }
     if (_subScopes != null) {
-      for (VariableScope subScope in _subScopes) {
+      for (VariableScope subScope in _subScopes!) {
         yield* subScope.assignedVariables;
       }
     }
@@ -103,13 +101,14 @@
 }
 
 abstract class VariableCollectorMixin {
-  VariableScopeImpl currentVariableScope;
+  VariableScopeImpl? currentVariableScope;
   VariableScopeModelImpl variableScopeModel = VariableScopeModelImpl();
 
   void visitInVariableScope(ir.TreeNode root, void f()) {
-    VariableScopeImpl oldScope = currentVariableScope;
-    currentVariableScope = variableScopeModel.createScopeFor(root);
-    oldScope?.addSubScope(currentVariableScope);
+    VariableScopeImpl? oldScope = currentVariableScope;
+    final newScope =
+        currentVariableScope = variableScopeModel.createScopeFor(root);
+    oldScope?.addSubScope(newScope);
     f();
     currentVariableScope = oldScope;
   }
diff --git a/pkg/compiler/lib/src/ir/scope_visitor.dart b/pkg/compiler/lib/src/ir/scope_visitor.dart
index 4d1e7f4..7a3863f 100644
--- a/pkg/compiler/lib/src/ir/scope_visitor.dart
+++ b/pkg/compiler/lib/src/ir/scope_visitor.dart
@@ -2,8 +2,6 @@
 // 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.10
-
 import 'package:kernel/ast.dart' as ir;
 import 'package:kernel/core_types.dart' as ir;
 import 'package:kernel/type_environment.dart' as ir;
@@ -17,9 +15,9 @@
 /// a [VariableScopeModel] that can respond to queries about how a particular
 /// variable is being used at any point in the code.
 class ScopeModelBuilder extends ir.Visitor<EvaluationComplexity>
-    with VariableCollectorMixin, ir.VisitorNullMixin<EvaluationComplexity> {
+    with VariableCollectorMixin, ir.VisitorThrowingMixin<EvaluationComplexity> {
   final Dart2jsConstantEvaluator _constantEvaluator;
-  ir.StaticTypeContext _staticTypeContext;
+  late final ir.StaticTypeContext _staticTypeContext;
 
   ir.TypeEnvironment get _typeEnvironment => _constantEvaluator.typeEnvironment;
   ir.CoreTypes get _coreTypes => _typeEnvironment.coreTypes;
@@ -40,25 +38,26 @@
       _model.closuresToGenerate;
 
   /// The local variables that have been declared in the current scope.
+  // Initialized to a const value since it should be assigned in `enterNewScope`
+  // before collecting variables.
   List<ir.Node /* ir.VariableDeclaration | TypeParameterTypeWithContext */ >
-      _scopeVariables;
+      _scopeVariables = const [];
 
   /// Pointer to the context in which this closure is executed.
   /// For example, in the expression `var foo = () => 3 + i;`, the executable
   /// context as we walk the nodes in that expression is the ir.Field `foo`.
-  ir.TreeNode _executableContext;
+  ir.TreeNode? _executableContext;
 
   /// A flag to indicate if we are currently inside a closure.
   bool _isInsideClosure = false;
 
   /// Pointer to the original node where this closure builder started.
-  ir.Node _outermostNode;
+  ir.TreeNode? _outermostNode;
 
   /// Keep track of the mutated local variables so that we don't need to box
   /// non-mutated variables. We know these are only VariableDeclarations because
   /// type variable types and `this` types can't be mutated!
-  final Set<ir.VariableDeclaration> _mutatedVariables =
-      Set<ir.VariableDeclaration>();
+  final Set<ir.VariableDeclaration> _mutatedVariables = {};
 
   /// The set of variables that are accessed in some form, whether they are
   /// mutated or not.
@@ -71,9 +70,10 @@
   bool _inTry = false;
 
   /// The current scope we are in.
-  KernelScopeInfo _currentScopeInfo;
+  KernelScopeInfo? __currentScopeInfo;
+  KernelScopeInfo get _currentScopeInfo => __currentScopeInfo!;
 
-  bool _hasThisLocal;
+  bool _hasThisLocal = false;
 
   /// Keeps track of the number of boxes that we've created so that they each
   /// have unique names.
@@ -84,7 +84,7 @@
   /// This is updated in the visitor to distinguish between unconditional
   /// type variable usage, such as type literals and is tests, and conditional
   /// type variable usage, such as type argument in method invocations.
-  VariableUse _currentTypeUsage;
+  VariableUse? _currentTypeUsage;
 
   ScopeModelBuilder(this._constantEvaluator);
 
@@ -133,7 +133,7 @@
       throw UnsupportedError('Unhandled node $node (${node.runtimeType})');
 
   EvaluationComplexity visitNode(ir.Node node) {
-    return node?.accept(this);
+    return node.accept(this);
   }
 
   /// Tries to evaluate [node] as a constant expression.
@@ -158,7 +158,8 @@
   /// the children of the parent node, which lead to a O(n^2) complexity that
   /// is severe and observable for instance for large list literals.
   EvaluationComplexity _evaluateImplicitConstant(ir.Expression node) {
-    ir.Constant constant = _constantEvaluator.evaluate(_staticTypeContext, node,
+    ir.Constant? constant = _constantEvaluator.evaluateOrNull(
+        _staticTypeContext, node,
         requireConstant: false, replaceImplicitConstant: false);
     if (constant != null) {
       return EvaluationComplexity.constant(constant);
@@ -167,7 +168,13 @@
   }
 
   /// The evaluation complexity of the last visited expression.
-  EvaluationComplexity _lastExpressionComplexity;
+  // TODO(48820): Pre-NNBD we gained some benefit from the `null` default
+  // value. It is too painful to add `!` after every access so this is
+  // initialized to a 'harmless' value.  Should we add an invalid value
+  // 'ExpressionComplexity.invalid()` and check in the combiner and other
+  // use-sites that the value is not 'invalid'?
+  EvaluationComplexity _lastExpressionComplexity =
+      const EvaluationComplexity.constant();
 
   /// Visit [node] and returns the corresponding `ConstantExpression` if [node]
   /// evaluated to a constant.
@@ -182,7 +189,7 @@
   ir.Expression _handleExpression(ir.Expression node) {
     _lastExpressionComplexity = visitNode(node);
     if (_lastExpressionComplexity.isFreshConstant) {
-      return ir.ConstantExpression(_lastExpressionComplexity.constant,
+      return ir.ConstantExpression(_lastExpressionComplexity.constant!,
           node.getStaticType(_staticTypeContext))
         ..fileOffset = node.fileOffset
         ..parent = node.parent;
@@ -232,10 +239,10 @@
     }
     if (!capturedVariablesForScope.isEmpty) {
       assert(_model.scopeInfo != null);
-      KernelScopeInfo from = _model.scopeInfo;
+      KernelScopeInfo from = _model.scopeInfo!;
 
       KernelCapturedScope capturedScope;
-      var nodeBox = NodeBox(getBoxName(), _executableContext);
+      var nodeBox = NodeBox(getBoxName(), _executableContext!);
       if (node is ir.ForStatement ||
           node is ir.ForInStatement ||
           node is ir.WhileStatement ||
@@ -281,7 +288,7 @@
 
   /// Perform book-keeping with the current set of local variables that have
   /// been seen thus far before entering this new scope.
-  void enterNewScope(ir.Node node, void visitNewScope()) {
+  void enterNewScope(ir.TreeNode node, void visitNewScope()) {
     List<ir.Node> oldScopeVariables = _scopeVariables;
     _scopeVariables = <ir.Node>[];
     visitNewScope();
@@ -345,7 +352,7 @@
 
     visitInContext(node.type, usage);
     if (node.initializer != null) {
-      node.initializer = _handleExpression(node.initializer);
+      node.initializer = _handleExpression(node.initializer!);
     }
   }
 
@@ -365,7 +372,7 @@
       VariableUse usage) {
     assert(variable is ir.VariableDeclaration ||
         variable is TypeVariableTypeWithContext);
-    assert(usage != null);
+    assert((usage as dynamic) != null); // TODO(48820): Remove.
     if (_isInsideClosure && !_inCurrentContext(variable)) {
       // If the element is not declared in the current function and the element
       // is not the closure itself we need to mark the element as free variable.
@@ -377,7 +384,8 @@
         _currentScopeInfo.freeVariables.add(variable);
       } else {
         _currentScopeInfo.freeVariablesForRti
-            .putIfAbsent(variable, () => Set<VariableUse>())
+            .putIfAbsent(variable as TypeVariableTypeWithContext,
+                () => Set<VariableUse>())
             .add(usage);
       }
     }
@@ -405,13 +413,13 @@
             // context in that case.
             typeParameter.parent?.parent);
 
-    ir.TreeNode context = _executableContext;
+    ir.TreeNode? context = _executableContext;
     if (_isInsideClosure && context is ir.Procedure && context.isFactory) {
       // This is a closure in a factory constructor.  Since there is no
       // [:this:], we have to mark the type arguments as free variables to
       // capture them in the closure.
       _useTypeVariableAsLocal(
-          typeVariable(context.enclosingLibrary), _currentTypeUsage);
+          typeVariable(context.enclosingLibrary), _currentTypeUsage!);
     }
 
     if (context is ir.Member && context is! ir.Field) {
@@ -422,10 +430,10 @@
       // the type arguments are available in locals.
 
       if (_hasThisLocal) {
-        _registerNeedsThis(_currentTypeUsage);
+        _registerNeedsThis(_currentTypeUsage!);
       } else {
         _useTypeVariableAsLocal(
-            typeVariable(context.enclosingLibrary), _currentTypeUsage);
+            typeVariable(context.enclosingLibrary), _currentTypeUsage!);
       }
     }
 
@@ -517,7 +525,7 @@
       // condition or body are indeed flagged as mutated.
       visitInVariableScope(node, () {
         if (node.condition != null) {
-          node.condition = _handleExpression(node.condition);
+          node.condition = _handleExpression(node.condition!);
         }
         visitNode(node.body);
       });
@@ -532,7 +540,7 @@
         }
       }
     });
-    KernelCapturedScope scope = _scopesCapturedInClosureMap[node];
+    KernelCapturedScope? scope = _scopesCapturedInClosureMap[node];
     if (scope != null) {
       _scopesCapturedInClosureMap[node] = KernelCapturedLoopScope(
           scope.boxedVariables,
@@ -582,15 +590,15 @@
   void visitInvokable(ir.TreeNode node, void f()) {
     assert(node is ir.Member || node is ir.LocalFunction);
     bool oldIsInsideClosure = _isInsideClosure;
-    ir.TreeNode oldExecutableContext = _executableContext;
-    KernelScopeInfo oldScopeInfo = _currentScopeInfo;
+    ir.TreeNode? oldExecutableContext = _executableContext;
+    KernelScopeInfo? oldScopeInfo = __currentScopeInfo;
 
     // _outermostNode is only null the first time we enter the body of the
     // field, constructor, or method that is being analyzed.
     _isInsideClosure = _outermostNode != null;
     _executableContext = node;
 
-    _currentScopeInfo = KernelScopeInfo(_hasThisLocal);
+    __currentScopeInfo = KernelScopeInfo(_hasThisLocal);
 
     if (_isInsideClosure) {
       _closuresToGenerate[node] = _currentScopeInfo;
@@ -606,7 +614,7 @@
 
     // Restore old values.
     _isInsideClosure = oldIsInsideClosure;
-    _currentScopeInfo = oldScopeInfo;
+    __currentScopeInfo = oldScopeInfo;
     _executableContext = oldExecutableContext;
 
     // Mark all free variables as captured and expect to encounter them in the
@@ -641,9 +649,9 @@
     if (variable is TypeVariableTypeWithContext) {
       return variable.context == _executableContext;
     }
-    ir.TreeNode node = variable;
+    ir.TreeNode? node = variable as ir.TreeNode;
     while (node != _outermostNode && node != _executableContext) {
-      node = node.parent;
+      node = node!.parent;
     }
     return node == _executableContext;
   }
@@ -651,9 +659,10 @@
   @override
   EvaluationComplexity visitField(ir.Field node) {
     _currentTypeUsage = VariableUse.fieldType;
-    EvaluationComplexity complexity;
+    late final EvaluationComplexity complexity;
     visitInvokable(node, () {
-      node.initializer = _handleExpression(node.initializer);
+      assert(node.initializer != null);
+      node.initializer = _handleExpression(node.initializer!);
       complexity = _lastExpressionComplexity;
     });
     _currentTypeUsage = null;
@@ -742,12 +751,12 @@
 
   @override
   EvaluationComplexity visitTypeParameterType(ir.TypeParameterType node) {
-    _analyzeTypeVariable(node, _currentTypeUsage);
+    _analyzeTypeVariable(node, _currentTypeUsage!);
     return const EvaluationComplexity.lazy();
   }
 
   EvaluationComplexity visitInContext(ir.Node node, VariableUse use) {
-    VariableUse oldCurrentTypeUsage = _currentTypeUsage;
+    VariableUse? oldCurrentTypeUsage = _currentTypeUsage;
     _currentTypeUsage = use;
     EvaluationComplexity complexity = visitNode(node);
     _currentTypeUsage = oldCurrentTypeUsage;
@@ -756,7 +765,7 @@
 
   EvaluationComplexity visitNodesInContext(
       List<ir.Node> nodes, VariableUse use) {
-    VariableUse oldCurrentTypeUsage = _currentTypeUsage;
+    VariableUse? oldCurrentTypeUsage = _currentTypeUsage;
     _currentTypeUsage = use;
     EvaluationComplexity complexity = visitNodes(nodes);
     _currentTypeUsage = oldCurrentTypeUsage;
@@ -829,7 +838,7 @@
     final parent = node.parent;
     VariableUse parameterUsage = parent is ir.Member
         ? VariableUse.memberParameter(parent)
-        : VariableUse.localParameter(parent);
+        : VariableUse.localParameter(parent as ir.LocalFunction?);
     visitNodesInContext(node.typeParameters, parameterUsage);
     for (ir.VariableDeclaration declaration in node.positionalParameters) {
       _handleVariableDeclaration(declaration, parameterUsage);
@@ -841,9 +850,9 @@
         node.returnType,
         parent is ir.Member
             ? VariableUse.memberReturnType(parent)
-            : VariableUse.localReturnType(parent));
+            : VariableUse.localReturnType(parent as ir.LocalFunction));
     if (node.body != null) {
-      visitNode(node.body);
+      visitNode(node.body!);
     }
     return const EvaluationComplexity.lazy();
   }
@@ -1264,10 +1273,10 @@
   EvaluationComplexity visitCatch(ir.Catch node) {
     visitInContext(node.guard, VariableUse.explicit);
     if (node.exception != null) {
-      visitNode(node.exception);
+      visitNode(node.exception!);
     }
     if (node.stackTrace != null) {
-      visitNode(node.stackTrace);
+      visitNode(node.stackTrace!);
     }
     visitInVariableScope(node, () {
       visitNode(node.body);
@@ -1311,7 +1320,7 @@
     visitInVariableScope(node, () {
       node.condition = _handleExpression(node.condition);
       if (node.message != null) {
-        node.message = _handleExpression(node.message);
+        node.message = _handleExpression(node.message!);
       }
     });
     return const EvaluationComplexity.lazy();
@@ -1320,7 +1329,7 @@
   @override
   EvaluationComplexity visitReturnStatement(ir.ReturnStatement node) {
     if (node.expression != null) {
-      node.expression = _handleExpression(node.expression);
+      node.expression = _handleExpression(node.expression!);
     }
     return const EvaluationComplexity.lazy();
   }
@@ -1377,7 +1386,9 @@
 
   @override
   EvaluationComplexity visitLocalInitializer(ir.LocalInitializer node) {
-    node.variable.initializer = _handleExpression(node.variable.initializer);
+    if (node.variable.initializer != null) {
+      node.variable.initializer = _handleExpression(node.variable.initializer!);
+    }
     return const EvaluationComplexity.lazy();
   }
 
@@ -1414,7 +1425,7 @@
     if (conditionComplexity.isFreshConstant) {}
     visitNode(node.then);
     if (node.otherwise != null) {
-      visitNode(node.otherwise);
+      visitNode(node.otherwise!);
     }
     return const EvaluationComplexity.lazy();
   }
@@ -1435,13 +1446,14 @@
       (node is ir.Procedure && node.isFactory);
 
   void _analyzeTypeVariable(ir.TypeParameterType type, VariableUse usage) {
-    assert(usage != null);
-    if (_outermostNode is ir.Member) {
+    assert((usage as dynamic) != null); // TODO(48820): Remove.
+    final outermost = _outermostNode;
+    if (outermost is ir.Member) {
       TypeVariableTypeWithContext typeVariable =
-          TypeVariableTypeWithContext(type, _outermostNode);
+          TypeVariableTypeWithContext(type, outermost);
       switch (typeVariable.kind) {
         case TypeVariableKind.cls:
-          if (_isFieldOrConstructor(_outermostNode)) {
+          if (_isFieldOrConstructor(outermost)) {
             // Class type variable used in a field or constructor.
             _useTypeVariableAsLocal(typeVariable, usage);
           } else {
@@ -1479,8 +1491,8 @@
 
 class EvaluationComplexity {
   final ComplexityLevel level;
-  final Set<ir.Field> fields;
-  final ir.Constant constant;
+  final Set<ir.Field>? fields;
+  final ir.Constant? constant;
 
   const EvaluationComplexity.constant([this.constant])
       : level = ComplexityLevel.constant,
@@ -1504,7 +1516,7 @@
       return const EvaluationComplexity.lazy();
     } else if (isEager || other.isEager) {
       if (fields != null && other.fields != null) {
-        fields.addAll(other.fields);
+        fields!.addAll(other.fields!);
         return this;
       } else if (fields != null) {
         return this;
@@ -1550,7 +1562,7 @@
         sb.write('eager');
         if (fields != null) {
           sb.write('&fields=[');
-          List<String> names = fields.map((f) => f.name.text).toList()..sort();
+          List<String> names = fields!.map((f) => f.name.text).toList()..sort();
           sb.write(names.join(','));
           sb.write(']');
         }
diff --git a/pkg/compiler/lib/src/js/size_estimator.dart b/pkg/compiler/lib/src/js/size_estimator.dart
index 7dc9fdf..e7faf76 100644
--- a/pkg/compiler/lib/src/js/size_estimator.dart
+++ b/pkg/compiler/lib/src/js/size_estimator.dart
@@ -678,6 +678,11 @@
         // We cannot remove parenthesis for "*" because of precision issues.
         rightPrecedenceRequirement = UNARY;
         break;
+      case "**":
+        leftPrecedenceRequirement = EXPONENTIATION;
+        // We cannot remove parenthesis for "**" because of precision issues.
+        rightPrecedenceRequirement = UNARY;
+        break;
       default:
         throw UnsupportedError("Forgot operator: $op");
     }
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart b/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart
index 96d0951..9791f4a 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart
@@ -10,7 +10,6 @@
 import '../common/elements.dart' show CommonElements, ElementEnvironment;
 import '../common/names.dart' show Identifiers;
 import '../elements/entities.dart';
-import '../elements/entities_parameter_structure_methods.dart';
 import '../elements/names.dart';
 import '../elements/types.dart';
 import '../ir/runtime_type_analysis.dart';
@@ -142,8 +141,7 @@
     if (property.memberName != selector.memberName) return false;
     if (type is FunctionType &&
         !selector.callStructure
-            .signatureApplies(ParameterStructureMethods.fromType(type)))
-      return false;
+            .signatureApplies(ParameterStructure.fromType(type))) return false;
     return true;
   }
 
@@ -290,9 +288,8 @@
             instanceName: instanceName,
             isNoSuchMethod: isNoSuchMethod);
       } else {
-        ParameterStructure parameterStructure =
-            ParameterStructureMethods.fromType(
-                _elementEnvironment.getLocalFunctionType(function));
+        ParameterStructure parameterStructure = ParameterStructure.fromType(
+            _elementEnvironment.getLocalFunctionType(function));
         node = MethodNode(function, parameterStructure, isCallTarget: true);
       }
       return node;
@@ -449,7 +446,7 @@
 
     for (GenericInstantiation instantiation in _genericInstantiations) {
       ParameterStructure instantiationParameterStructure =
-          ParameterStructureMethods.fromType(instantiation.functionType);
+          ParameterStructure.fromType(instantiation.functionType);
       ClassEntity implementationClass = _commonElements
           .getInstantiationClass(instantiation.typeArguments.length);
 
diff --git a/pkg/compiler/lib/src/js_model/element_map_impl.dart b/pkg/compiler/lib/src/js_model/element_map_impl.dart
index 6cbb34b..e4ae932 100644
--- a/pkg/compiler/lib/src/js_model/element_map_impl.dart
+++ b/pkg/compiler/lib/src/js_model/element_map_impl.dart
@@ -1492,7 +1492,8 @@
       // computation.
       ir.StaticTypeContext staticTypeContext =
           getStaticTypeContext(memberContext);
-      ir.Constant constant = constantEvaluator.evaluate(staticTypeContext, node,
+      ir.Constant constant = constantEvaluator.evaluateOrNull(
+          staticTypeContext, node,
           requireConstant: requireConstant);
       if (constant == null) {
         if (requireConstant) {
diff --git a/pkg/compiler/lib/src/js_model/elements.dart b/pkg/compiler/lib/src/js_model/elements.dart
index 9d3517e..915558b 100644
--- a/pkg/compiler/lib/src/js_model/elements.dart
+++ b/pkg/compiler/lib/src/js_model/elements.dart
@@ -10,7 +10,6 @@
 import '../elements/entities.dart';
 import '../elements/indexed.dart';
 import '../elements/names.dart';
-import '../elements/entities_parameter_structure_methods.dart';
 import '../elements/types.dart';
 import '../serialization/serialization.dart';
 import '../universe/class_set.dart' show ClassHierarchyNodesMapKey;
@@ -280,7 +279,7 @@
     JClass enclosingClass = source.readClass();
     String name = source.readString();
     ParameterStructure parameterStructure =
-        ParameterStructureMethods.readFromDataSource(source);
+        ParameterStructure.readFromDataSource(source);
     bool isExternal = source.readBool();
     bool isConst = source.readBool();
     source.end(tag);
@@ -329,7 +328,7 @@
     JClass enclosingClass = source.readClass();
     String name = source.readString();
     ParameterStructure parameterStructure =
-        ParameterStructureMethods.readFromDataSource(source);
+        ParameterStructure.readFromDataSource(source);
     bool isExternal = source.readBool();
     bool isConst = source.readBool();
     bool isFromEnvironmentConstructor = source.readBool();
@@ -378,7 +377,7 @@
     source.begin(tag);
     JConstructor constructor = source.readMember();
     ParameterStructure parameterStructure =
-        ParameterStructureMethods.readFromDataSource(source);
+        ParameterStructure.readFromDataSource(source);
     source.end(tag);
     return JConstructorBody(constructor, parameterStructure);
   }
@@ -426,7 +425,7 @@
     }
     String name = source.readString();
     ParameterStructure parameterStructure =
-        ParameterStructureMethods.readFromDataSource(source);
+        ParameterStructure.readFromDataSource(source);
     AsyncMarker asyncMarker = source.readEnum(AsyncMarker.values);
     bool isStatic = source.readBool();
     bool isExternal = source.readBool();
@@ -708,7 +707,7 @@
     source.begin(tag);
     JClass enclosingClass = source.readClass();
     ParameterStructure parameterStructure =
-        ParameterStructureMethods.readFromDataSource(source);
+        ParameterStructure.readFromDataSource(source);
     AsyncMarker asyncMarker = source.readEnum(AsyncMarker.values);
     source.end(tag);
     return JClosureCallMethod(enclosingClass, parameterStructure, asyncMarker);
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index a3a0c0c..476b906 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -1144,7 +1144,8 @@
       }
       return NullConstantValue();
     }
-    ir.Constant constant = constantEvaluator.evaluate(staticTypeContext, node,
+    ir.Constant constant = constantEvaluator.evaluateOrNull(
+        staticTypeContext, node,
         requireConstant: requireConstant);
     if (constant == null) {
       if (requireConstant) {
diff --git a/pkg/compiler/test/js/js_parser_test.dart b/pkg/compiler/test/js/js_parser_test.dart
index abbed83..6cc7a3f 100644
--- a/pkg/compiler/test/js/js_parser_test.dart
+++ b/pkg/compiler/test/js/js_parser_test.dart
@@ -258,4 +258,12 @@
   bar() {
   }
 }""");
+
+  // Exponentiation operator.
+  testExpression("a ** b");
+  //* Parsed with incorrect association:
+  testExpression("a ** b ** c", "(a ** b) ** c");
+  testExpression("(a ** b) ** c", "(a ** b) ** c");
+  testExpression("a ** (b ** c)", "a ** b ** c");
+  testExpression("a **= b");
 }
diff --git a/pkg/dev_compiler/lib/src/js_ast/builder.dart b/pkg/dev_compiler/lib/src/js_ast/builder.dart
index 98c70eb..0ee9e63 100644
--- a/pkg/dev_compiler/lib/src/js_ast/builder.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/builder.dart
@@ -609,6 +609,7 @@
     '<<=': 17,
     '>>=': 17,
     '>>>=': 17,
+    '**=': 17,
     '=': 17,
     '||': 14,
     '&&': 13,
@@ -632,7 +633,8 @@
     '-': 6,
     '*': 5,
     '/': 5,
-    '%': 5
+    '%': 5,
+    '**': 4,
   };
   static final UNARY_OPERATORS = {
     '++',
diff --git a/pkg/dev_compiler/lib/src/js_ast/nodes.dart b/pkg/dev_compiler/lib/src/js_ast/nodes.dart
index c64ff60..89f22da 100644
--- a/pkg/dev_compiler/lib/src/js_ast/nodes.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/nodes.dart
@@ -1291,6 +1291,8 @@
   int get precedenceLevel {
     // TODO(floitsch): switch to constant map.
     switch (op) {
+      case '**':
+        return EXPONENTIATION;
       case '*':
       case '/':
       case '%':
diff --git a/pkg/dev_compiler/lib/src/js_ast/precedence.dart b/pkg/dev_compiler/lib/src/js_ast/precedence.dart
index f149dc2..3f3ea76 100644
--- a/pkg/dev_compiler/lib/src/js_ast/precedence.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/precedence.dart
@@ -28,7 +28,8 @@
 const SHIFT = RELATIONAL + 1;
 const ADDITIVE = SHIFT + 1;
 const MULTIPLICATIVE = ADDITIVE + 1;
-const UNARY = MULTIPLICATIVE + 1;
+const EXPONENTIATION = MULTIPLICATIVE + 1;
+const UNARY = EXPONENTIATION + 1;
 const LEFT_HAND_SIDE = UNARY + 1;
 const CALL = LEFT_HAND_SIDE;
 // We always emit `new` with parenthesis, so it uses ACCESS as its precedence.
diff --git a/pkg/dev_compiler/lib/src/js_ast/printer.dart b/pkg/dev_compiler/lib/src/js_ast/printer.dart
index 88434f0..911327c 100644
--- a/pkg/dev_compiler/lib/src/js_ast/printer.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/printer.dart
@@ -856,6 +856,12 @@
         // We cannot remove parenthesis for "*" because of precision issues.
         rightPrecedenceRequirement = UNARY;
         break;
+      case '**':
+        // 'a ** b ** c' parses as 'a ** (b ** c)', so the left must have higher
+        // precedence.
+        leftPrecedenceRequirement = UNARY;
+        rightPrecedenceRequirement = EXPONENTIATION;
+        break;
       default:
         leftPrecedenceRequirement = EXPRESSION;
         rightPrecedenceRequirement = EXPRESSION;
diff --git a/pkg/frontend_server/lib/frontend_server.dart b/pkg/frontend_server/lib/frontend_server.dart
index 710ba19..ca5700a 100644
--- a/pkg/frontend_server/lib/frontend_server.dart
+++ b/pkg/frontend_server/lib/frontend_server.dart
@@ -540,7 +540,7 @@
       nullSafety: compilerOptions.nnbdMode == NnbdMode.Strong,
       supportMirrors: options['support-mirrors'] ??
           !(options['aot'] || options['minimal-kernel']),
-      compactAsync: options['compact-async'] ?? false /*options['aot']*/,
+      compactAsync: options['compact-async'] ?? options['aot'],
     );
     if (compilerOptions.target == null) {
       print('Failed to create front-end target ${options['target']}.');
diff --git a/pkg/js_ast/lib/src/builder.dart b/pkg/js_ast/lib/src/builder.dart
index fc04678..db39a15 100644
--- a/pkg/js_ast/lib/src/builder.dart
+++ b/pkg/js_ast/lib/src/builder.dart
@@ -535,6 +535,7 @@
     '<<=': 17,
     '>>=': 17,
     '>>>=': 17,
+    '**=': 17,
     '=': 17,
     '||': 14,
     '&&': 13,
@@ -558,7 +559,8 @@
     '-': 6,
     '*': 5,
     '/': 5,
-    '%': 5
+    '%': 5,
+    '**': 4,
   };
   static final UNARY_OPERATORS = {
     '++',
diff --git a/pkg/js_ast/lib/src/nodes.dart b/pkg/js_ast/lib/src/nodes.dart
index 661efd6..4e7acf0 100644
--- a/pkg/js_ast/lib/src/nodes.dart
+++ b/pkg/js_ast/lib/src/nodes.dart
@@ -1638,6 +1638,8 @@
   int get precedenceLevel {
     // TODO(floitsch): switch to constant map.
     switch (op) {
+      case '**':
+        return EXPONENTIATION;
       case '*':
       case '/':
       case '%':
diff --git a/pkg/js_ast/lib/src/precedence.dart b/pkg/js_ast/lib/src/precedence.dart
index 222f4a8..63bf3b3 100644
--- a/pkg/js_ast/lib/src/precedence.dart
+++ b/pkg/js_ast/lib/src/precedence.dart
@@ -16,7 +16,8 @@
 const SHIFT = RELATIONAL + 1;
 const ADDITIVE = SHIFT + 1;
 const MULTIPLICATIVE = ADDITIVE + 1;
-const UNARY = MULTIPLICATIVE + 1;
+const EXPONENTIATION = MULTIPLICATIVE + 1;
+const UNARY = EXPONENTIATION + 1;
 const CALL = UNARY + 1;
 const LEFT_HAND_SIDE = CALL + 1;
 const PRIMARY = LEFT_HAND_SIDE + 1;
diff --git a/pkg/js_ast/lib/src/printer.dart b/pkg/js_ast/lib/src/printer.dart
index 9f9a3ff..0226894 100644
--- a/pkg/js_ast/lib/src/printer.dart
+++ b/pkg/js_ast/lib/src/printer.dart
@@ -970,6 +970,12 @@
         // We cannot remove parenthesis for "*" because of precision issues.
         rightPrecedenceRequirement = UNARY;
         break;
+      case '**':
+        // 'a ** b ** c' parses as 'a ** (b ** c)', so the left must have higher
+        // precedence.
+        leftPrecedenceRequirement = UNARY;
+        rightPrecedenceRequirement = EXPONENTIATION;
+        break;
       default:
         leftPrecedenceRequirement = EXPRESSION;
         rightPrecedenceRequirement = EXPRESSION;
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index 9ced5db..22c471fb 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -202,7 +202,7 @@
   final String? manifestFilename = options['manifest'];
   final String? dataDir = options['component-name'] ?? options['data-dir'];
   final bool? supportMirrors = options['support-mirrors'];
-  final bool compactAsync = options['compact-async'] ?? false /*aot*/;
+  final bool compactAsync = options['compact-async'] ?? aot;
 
   final bool minimalKernel = options['minimal-kernel'];
   final bool treeShakeWriteOnlyFields = options['tree-shake-write-only-fields'];
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index 8e95dab..a8d862f 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -250,6 +250,7 @@
           MESSAGE_SNAPSHOT_ILLEGAL(Pointer);
           MESSAGE_SNAPSHOT_ILLEGAL(ReceivePort);
           MESSAGE_SNAPSHOT_ILLEGAL(UserTag);
+          MESSAGE_SNAPSHOT_ILLEGAL(SuspendState);
 
         default:
           if (cid >= kNumPredefinedCids) {
diff --git a/runtime/vm/app_snapshot.cc b/runtime/vm/app_snapshot.cc
index ccdda66..a6a4766 100644
--- a/runtime/vm/app_snapshot.cc
+++ b/runtime/vm/app_snapshot.cc
@@ -381,23 +381,22 @@
     stop_index_ = d->next_index();
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
-    ClassTable* table = d->isolate_group()->class_table();
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
 
     for (intptr_t id = predefined_start_index_; id < predefined_stop_index_;
          id++) {
-      ClassPtr cls = static_cast<ClassPtr>(d->Ref(id));
-      ReadFromTo(cls);
-      intptr_t class_id = d->ReadCid();
+      ClassPtr cls = static_cast<ClassPtr>(d.Ref(id));
+      d.ReadFromTo(cls);
+      intptr_t class_id = d.ReadCid();
       cls->untag()->id_ = class_id;
 #if !defined(DART_PRECOMPILED_RUNTIME)
-      if (d->kind() != Snapshot::kFullAOT) {
-        cls->untag()->kernel_offset_ = d->Read<uint32_t>();
-      }
+      ASSERT(d_->kind() != Snapshot::kFullAOT);
+      cls->untag()->kernel_offset_ = d.Read<uint32_t>();
 #endif
       if (!IsInternalVMdefinedClassId(class_id)) {
-        cls->untag()->host_instance_size_in_words_ = d->Read<int32_t>();
-        cls->untag()->host_next_field_offset_in_words_ = d->Read<int32_t>();
+        cls->untag()->host_instance_size_in_words_ = d.Read<int32_t>();
+        cls->untag()->host_next_field_offset_in_words_ = d.Read<int32_t>();
 #if defined(DART_PRECOMPILER)
         // Only one pair is serialized. The target field only exists when
         // DART_PRECOMPILER is defined
@@ -407,48 +406,50 @@
             cls->untag()->host_next_field_offset_in_words_;
 #endif  // defined(DART_PRECOMPILER)
       } else {
-        d->Read<int32_t>();  // Skip.
-        d->Read<int32_t>();  // Skip.
+        d.Read<int32_t>();  // Skip.
+        d.Read<int32_t>();  // Skip.
       }
       cls->untag()->host_type_arguments_field_offset_in_words_ =
-          d->Read<int32_t>();
+          d.Read<int32_t>();
 #if defined(DART_PRECOMPILER)
       cls->untag()->target_type_arguments_field_offset_in_words_ =
           cls->untag()->host_type_arguments_field_offset_in_words_;
 #endif  // defined(DART_PRECOMPILER)
-      cls->untag()->num_type_arguments_ = d->Read<int16_t>();
-      cls->untag()->num_native_fields_ = d->Read<uint16_t>();
+      cls->untag()->num_type_arguments_ = d.Read<int16_t>();
+      cls->untag()->num_native_fields_ = d.Read<uint16_t>();
 #if !defined(DART_PRECOMPILED_RUNTIME)
-      ASSERT(d->kind() != Snapshot::kFullAOT);
-      cls->untag()->token_pos_ = d->ReadTokenPosition();
-      cls->untag()->end_token_pos_ = d->ReadTokenPosition();
+      ASSERT(d_->kind() != Snapshot::kFullAOT);
+      cls->untag()->token_pos_ = d.ReadTokenPosition();
+      cls->untag()->end_token_pos_ = d.ReadTokenPosition();
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
-      cls->untag()->state_bits_ = d->Read<uint32_t>();
+      cls->untag()->state_bits_ = d.Read<uint32_t>();
 
-      if (FLAG_precompiled_mode) {
-        d->ReadUnsigned64();  // Skip unboxed fields bitmap.
-      }
+#if defined(DART_PRECOMPILED_RUNTIME)
+      d.ReadUnsigned64();  // Skip unboxed fields bitmap.
+#endif
     }
 
-    auto shared_class_table = d->isolate_group()->shared_class_table();
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      ClassPtr cls = static_cast<ClassPtr>(d->Ref(id));
+    ClassTable* table = d_->isolate_group()->class_table();
+#if defined(DART_PRECOMPILED_RUNTIME)
+    auto shared_class_table = d_->isolate_group()->shared_class_table();
+#endif
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      ClassPtr cls = static_cast<ClassPtr>(d.Ref(id));
       Deserializer::InitializeHeader(cls, kClassCid, Class::InstanceSize());
-      ReadFromTo(cls);
+      d.ReadFromTo(cls);
 
-      intptr_t class_id = d->ReadCid();
+      intptr_t class_id = d.ReadCid();
       ASSERT(class_id >= kNumPredefinedCids);
       cls->untag()->id_ = class_id;
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-      if (d->kind() != Snapshot::kFullAOT) {
-        cls->untag()->kernel_offset_ = d->Read<uint32_t>();
-      }
+      ASSERT(d_->kind() != Snapshot::kFullAOT);
+      cls->untag()->kernel_offset_ = d.Read<uint32_t>();
 #endif
-      cls->untag()->host_instance_size_in_words_ = d->Read<int32_t>();
-      cls->untag()->host_next_field_offset_in_words_ = d->Read<int32_t>();
+      cls->untag()->host_instance_size_in_words_ = d.Read<int32_t>();
+      cls->untag()->host_next_field_offset_in_words_ = d.Read<int32_t>();
       cls->untag()->host_type_arguments_field_offset_in_words_ =
-          d->Read<int32_t>();
+          d.Read<int32_t>();
 #if defined(DART_PRECOMPILER)
       cls->untag()->target_instance_size_in_words_ =
           cls->untag()->host_instance_size_in_words_;
@@ -457,22 +458,24 @@
       cls->untag()->target_type_arguments_field_offset_in_words_ =
           cls->untag()->host_type_arguments_field_offset_in_words_;
 #endif  // defined(DART_PRECOMPILER)
-      cls->untag()->num_type_arguments_ = d->Read<int16_t>();
-      cls->untag()->num_native_fields_ = d->Read<uint16_t>();
+      cls->untag()->num_type_arguments_ = d.Read<int16_t>();
+      cls->untag()->num_native_fields_ = d.Read<uint16_t>();
 #if !defined(DART_PRECOMPILED_RUNTIME)
-      ASSERT(d->kind() != Snapshot::kFullAOT);
-      cls->untag()->token_pos_ = d->ReadTokenPosition();
-      cls->untag()->end_token_pos_ = d->ReadTokenPosition();
+      ASSERT(d_->kind() != Snapshot::kFullAOT);
+      cls->untag()->token_pos_ = d.ReadTokenPosition();
+      cls->untag()->end_token_pos_ = d.ReadTokenPosition();
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
-      cls->untag()->state_bits_ = d->Read<uint32_t>();
+      cls->untag()->state_bits_ = d.Read<uint32_t>();
 
       table->AllocateIndex(class_id);
       table->SetAt(class_id, cls);
 
-      if (FLAG_precompiled_mode && !ClassTable::IsTopLevelCid(class_id)) {
-        const UnboxedFieldBitmap unboxed_fields_map(d->ReadUnsigned64());
+#if defined(DART_PRECOMPILED_RUNTIME)
+      if (!ClassTable::IsTopLevelCid(class_id)) {
+        const UnboxedFieldBitmap unboxed_fields_map(d.ReadUnsigned64());
         shared_class_table->SetUnboxedFieldsMapAt(class_id, unboxed_fields_map);
       }
+#endif
     }
   }
 
@@ -755,14 +758,15 @@
     ReadAllocFixedSize(d, TypeParameters::InstanceSize());
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
     ASSERT(!is_canonical());  // Never canonical.
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      TypeParametersPtr type_params =
-          static_cast<TypeParametersPtr>(d->Ref(id));
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      TypeParametersPtr type_params = static_cast<TypeParametersPtr>(d.Ref(id));
       Deserializer::InitializeHeader(type_params, kTypeParametersCid,
                                      TypeParameters::InstanceSize());
-      ReadFromTo(type_params);
+      d.ReadFromTo(type_params);
     }
   }
 };
@@ -852,20 +856,23 @@
     BuildCanonicalSetFromLayout(d);
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      TypeArgumentsPtr type_args = static_cast<TypeArgumentsPtr>(d->Ref(id));
-      const intptr_t length = d->ReadUnsigned();
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
+    const bool mark_canonical = primary && is_canonical();
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      TypeArgumentsPtr type_args = static_cast<TypeArgumentsPtr>(d.Ref(id));
+      const intptr_t length = d.ReadUnsigned();
       Deserializer::InitializeHeader(type_args, kTypeArgumentsCid,
                                      TypeArguments::InstanceSize(length),
-                                     primary && is_canonical());
+                                     mark_canonical);
       type_args->untag()->length_ = Smi::New(length);
-      type_args->untag()->hash_ = Smi::New(d->Read<int32_t>());
-      type_args->untag()->nullability_ = Smi::New(d->ReadUnsigned());
-      type_args->untag()->instantiations_ = static_cast<ArrayPtr>(d->ReadRef());
+      type_args->untag()->hash_ = Smi::New(d.Read<int32_t>());
+      type_args->untag()->nullability_ = Smi::New(d.ReadUnsigned());
+      type_args->untag()->instantiations_ = static_cast<ArrayPtr>(d.ReadRef());
       for (intptr_t j = 0; j < length; j++) {
         type_args->untag()->types()[j] =
-            static_cast<AbstractTypePtr>(d->ReadRef());
+            static_cast<AbstractTypePtr>(d.ReadRef());
       }
     }
   }
@@ -878,7 +885,7 @@
       object_store->set_canonical_type_arguments(table_);
     } else if (!primary && is_canonical()) {
       TypeArguments& type_arg = TypeArguments::Handle(d->zone());
-      for (intptr_t i = start_index_; i < stop_index_; i++) {
+      for (intptr_t i = start_index_, n = stop_index_; i < n; i++) {
         type_arg ^= refs.At(i);
         type_arg = type_arg.Canonicalize(d->thread(), nullptr);
         refs.SetAt(i, type_arg);
@@ -937,17 +944,18 @@
     ReadAllocFixedSize(d, PatchClass::InstanceSize());
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
     ASSERT(!is_canonical());  // Never canonical.
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      PatchClassPtr cls = static_cast<PatchClassPtr>(d->Ref(id));
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      PatchClassPtr cls = static_cast<PatchClassPtr>(d.Ref(id));
       Deserializer::InitializeHeader(cls, kPatchClassCid,
                                      PatchClass::InstanceSize());
-      ReadFromTo(cls);
+      d.ReadFromTo(cls);
 #if !defined(DART_PRECOMPILED_RUNTIME)
-      if (d->kind() != Snapshot::kFullAOT) {
-        cls->untag()->library_kernel_offset_ = d->Read<int32_t>();
-      }
+      ASSERT(d_->kind() != Snapshot::kFullAOT);
+      cls->untag()->library_kernel_offset_ = d.Read<int32_t>();
 #endif
     }
   }
@@ -1135,68 +1143,68 @@
     ReadAllocFixedSize(d, Function::InstanceSize());
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
-    ASSERT(!is_canonical());  // Never canonical.
-    Snapshot::Kind kind = d->kind();
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
 
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      FunctionPtr func = static_cast<FunctionPtr>(d->Ref(id));
+    ASSERT(!is_canonical());  // Never canonical.
+    Snapshot::Kind kind = d_->kind();
+
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      FunctionPtr func = static_cast<FunctionPtr>(d.Ref(id));
       Deserializer::InitializeHeader(func, kFunctionCid,
                                      Function::InstanceSize());
-      ReadFromTo(func);
+      d.ReadFromTo(func);
 
 #if defined(DEBUG)
       func->untag()->entry_point_ = 0;
       func->untag()->unchecked_entry_point_ = 0;
 #endif
 
-      if (kind == Snapshot::kFullAOT) {
-        const intptr_t code_index = d->ReadUnsigned();
-        uword entry_point = 0;
-        CodePtr code = d->GetCodeByIndex(code_index, &entry_point);
-        func->untag()->code_ = code;
-        if (entry_point != 0) {
-          func->untag()->entry_point_ = entry_point;
-          func->untag()->unchecked_entry_point_ = entry_point;
-        }
-      } else if (kind == Snapshot::kFullJIT) {
-        NOT_IN_PRECOMPILED(func->untag()->unoptimized_code_ =
-                               static_cast<CodePtr>(d->ReadRef()));
-        func->untag()->code_ = static_cast<CodePtr>(d->ReadRef());
-        func->untag()->ic_data_array_ = static_cast<ArrayPtr>(d->ReadRef());
+#if defined(DART_PRECOMPILED_RUNTIME)
+      ASSERT(kind == Snapshot::kFullAOT);
+      const intptr_t code_index = d.ReadUnsigned();
+      uword entry_point = 0;
+      CodePtr code = d_->GetCodeByIndex(code_index, &entry_point);
+      func->untag()->code_ = code;
+      if (entry_point != 0) {
+        func->untag()->entry_point_ = entry_point;
+        func->untag()->unchecked_entry_point_ = entry_point;
       }
+#else
+      ASSERT(kind != Snapshot::kFullAOT);
+      if (kind == Snapshot::kFullJIT) {
+        func->untag()->unoptimized_code_ = static_cast<CodePtr>(d.ReadRef());
+        func->untag()->code_ = static_cast<CodePtr>(d.ReadRef());
+        func->untag()->ic_data_array_ = static_cast<ArrayPtr>(d.ReadRef());
+      }
+#endif
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-      if (kind != Snapshot::kFullAOT) {
-        func->untag()->positional_parameter_names_ =
-            static_cast<ArrayPtr>(d->ReadRef());
-        func->untag()->token_pos_ = d->ReadTokenPosition();
-        func->untag()->end_token_pos_ = d->ReadTokenPosition();
-        func->untag()->kernel_offset_ = d->Read<uint32_t>();
-      }
+      ASSERT(kind != Snapshot::kFullAOT);
+      func->untag()->positional_parameter_names_ =
+          static_cast<ArrayPtr>(d.ReadRef());
+      func->untag()->token_pos_ = d.ReadTokenPosition();
+      func->untag()->end_token_pos_ = d.ReadTokenPosition();
+      func->untag()->kernel_offset_ = d.Read<uint32_t>();
       func->untag()->unboxed_parameters_info_.Reset();
 #endif
-      func->untag()->packed_fields_ = d->Read<uint32_t>();
-      func->untag()->kind_tag_ = d->Read<uint32_t>();
-      if (kind == Snapshot::kFullAOT) {
-        // Omit fields used to support de/reoptimization.
-      } else {
+      func->untag()->packed_fields_ = d.Read<uint32_t>();
+      func->untag()->kind_tag_ = d.Read<uint32_t>();
 #if !defined(DART_PRECOMPILED_RUNTIME)
-        func->untag()->usage_counter_ = 0;
-        func->untag()->optimized_instruction_count_ = 0;
-        func->untag()->optimized_call_site_count_ = 0;
-        func->untag()->deoptimization_counter_ = 0;
-        func->untag()->state_bits_ = 0;
-        func->untag()->inlining_depth_ = 0;
+      func->untag()->usage_counter_ = 0;
+      func->untag()->optimized_instruction_count_ = 0;
+      func->untag()->optimized_call_site_count_ = 0;
+      func->untag()->deoptimization_counter_ = 0;
+      func->untag()->state_bits_ = 0;
+      func->untag()->inlining_depth_ = 0;
 #endif
-      }
     }
   }
 
   void PostLoad(Deserializer* d, const Array& refs, bool primary) {
     if (d->kind() == Snapshot::kFullAOT) {
       Function& func = Function::Handle(d->zone());
-      for (intptr_t i = start_index_; i < stop_index_; i++) {
+      for (intptr_t i = start_index_, n = stop_index_; i < n; i++) {
         func ^= refs.At(i);
         auto const code = func.ptr()->untag()->code();
         ASSERT(code->IsCode());
@@ -1212,7 +1220,7 @@
     } else if (d->kind() == Snapshot::kFullJIT) {
       Function& func = Function::Handle(d->zone());
       Code& code = Code::Handle(d->zone());
-      for (intptr_t i = start_index_; i < stop_index_; i++) {
+      for (intptr_t i = start_index_, n = stop_index_; i < n; i++) {
         func ^= refs.At(i);
         code = func.CurrentCode();
         if (func.HasCode() && !code.IsDisabled()) {
@@ -1224,7 +1232,7 @@
       }
     } else {
       Function& func = Function::Handle(d->zone());
-      for (intptr_t i = start_index_; i < stop_index_; i++) {
+      for (intptr_t i = start_index_, n = stop_index_; i < n; i++) {
         func ^= refs.At(i);
         func.ClearCodeSafe();  // Set code and entrypoint to lazy compile stub.
       }
@@ -1290,22 +1298,24 @@
     ReadAllocFixedSize(d, ClosureData::InstanceSize());
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
     ASSERT(!is_canonical());  // Never canonical.
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      ClosureDataPtr data = static_cast<ClosureDataPtr>(d->Ref(id));
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      ClosureDataPtr data = static_cast<ClosureDataPtr>(d.Ref(id));
       Deserializer::InitializeHeader(data, kClosureDataCid,
                                      ClosureData::InstanceSize());
-      if (d->kind() == Snapshot::kFullAOT) {
+      if (d_->kind() == Snapshot::kFullAOT) {
         data->untag()->context_scope_ = ContextScope::null();
       } else {
         data->untag()->context_scope_ =
-            static_cast<ContextScopePtr>(d->ReadRef());
+            static_cast<ContextScopePtr>(d.ReadRef());
       }
-      data->untag()->parent_function_ = static_cast<FunctionPtr>(d->ReadRef());
-      data->untag()->closure_ = static_cast<ClosurePtr>(d->ReadRef());
+      data->untag()->parent_function_ = static_cast<FunctionPtr>(d.ReadRef());
+      data->untag()->closure_ = static_cast<ClosurePtr>(d.ReadRef());
       data->untag()->default_type_arguments_kind_ =
-          static_cast<ClosureData::DefaultTypeArgumentsKind>(d->ReadUnsigned());
+          static_cast<ClosureData::DefaultTypeArgumentsKind>(d.ReadUnsigned());
     }
   }
 };
@@ -1365,15 +1375,17 @@
     ReadAllocFixedSize(d, FfiTrampolineData::InstanceSize());
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
     ASSERT(!is_canonical());  // Never canonical.
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      FfiTrampolineDataPtr data = static_cast<FfiTrampolineDataPtr>(d->Ref(id));
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      FfiTrampolineDataPtr data = static_cast<FfiTrampolineDataPtr>(d.Ref(id));
       Deserializer::InitializeHeader(data, kFfiTrampolineDataCid,
                                      FfiTrampolineData::InstanceSize());
-      ReadFromTo(data);
+      d.ReadFromTo(data);
       data->untag()->callback_id_ =
-          d->kind() == Snapshot::kFullAOT ? d->ReadUnsigned() : 0;
+          d_->kind() == Snapshot::kFullAOT ? d.ReadUnsigned() : 0;
     }
   }
 };
@@ -1479,50 +1491,49 @@
     ReadAllocFixedSize(d, Field::InstanceSize());
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
     ASSERT(!is_canonical());  // Never canonical.
-    Snapshot::Kind kind = d->kind();
-
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      FieldPtr field = static_cast<FieldPtr>(d->Ref(id));
-      Deserializer::InitializeHeader(field, kFieldCid, Field::InstanceSize());
-      ReadFromTo(field);
-      if (kind != Snapshot::kFullAOT) {
-        field->untag()->guarded_list_length_ =
-            static_cast<SmiPtr>(d->ReadRef());
-      }
-      if (kind == Snapshot::kFullJIT) {
-        field->untag()->dependent_code_ = static_cast<ArrayPtr>(d->ReadRef());
-      }
-      if (kind != Snapshot::kFullAOT) {
-        field->untag()->token_pos_ = d->ReadTokenPosition();
-        field->untag()->end_token_pos_ = d->ReadTokenPosition();
-        field->untag()->guarded_cid_ = d->ReadCid();
-        field->untag()->is_nullable_ = d->ReadCid();
-        const int8_t static_type_exactness_state = d->Read<int8_t>();
-#if defined(TARGET_ARCH_X64)
-        field->untag()->static_type_exactness_state_ =
-            static_type_exactness_state;
-#else
-        // We might produce core snapshots using X64 VM and then consume
-        // them in IA32 or ARM VM. In which case we need to simply ignore
-        // static type exactness state written into snapshot because non-X64
-        // builds don't have this feature enabled.
-        // TODO(dartbug.com/34170) Support other architectures.
-        USE(static_type_exactness_state);
-        field->untag()->static_type_exactness_state_ =
-            StaticTypeExactnessState::NotTracking().Encode();
-#endif  // defined(TARGET_ARCH_X64)
 #if !defined(DART_PRECOMPILED_RUNTIME)
-        field->untag()->kernel_offset_ = d->Read<uint32_t>();
+    Snapshot::Kind kind = d_->kind();
 #endif
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      FieldPtr field = static_cast<FieldPtr>(d.Ref(id));
+      Deserializer::InitializeHeader(field, kFieldCid, Field::InstanceSize());
+      d.ReadFromTo(field);
+#if !defined(DART_PRECOMPILED_RUNTIME)
+      ASSERT(d_->kind() != Snapshot::kFullAOT);
+      field->untag()->guarded_list_length_ = static_cast<SmiPtr>(d.ReadRef());
+      if (kind == Snapshot::kFullJIT) {
+        field->untag()->dependent_code_ = static_cast<ArrayPtr>(d.ReadRef());
       }
-      field->untag()->kind_bits_ = d->Read<uint16_t>();
+      field->untag()->token_pos_ = d.ReadTokenPosition();
+      field->untag()->end_token_pos_ = d.ReadTokenPosition();
+      field->untag()->guarded_cid_ = d.ReadCid();
+      field->untag()->is_nullable_ = d.ReadCid();
+      const int8_t static_type_exactness_state = d.Read<int8_t>();
+#if defined(TARGET_ARCH_X64)
+      field->untag()->static_type_exactness_state_ =
+          static_type_exactness_state;
+#else
+      // We might produce core snapshots using X64 VM and then consume
+      // them in IA32 or ARM VM. In which case we need to simply ignore
+      // static type exactness state written into snapshot because non-X64
+      // builds don't have this feature enabled.
+      // TODO(dartbug.com/34170) Support other architectures.
+      USE(static_type_exactness_state);
+      field->untag()->static_type_exactness_state_ =
+          StaticTypeExactnessState::NotTracking().Encode();
+#endif  // defined(TARGET_ARCH_X64)
+      field->untag()->kernel_offset_ = d.Read<uint32_t>();
+#endif
+      field->untag()->kind_bits_ = d.Read<uint16_t>();
 
-      ObjectPtr value_or_offset = d->ReadRef();
+      ObjectPtr value_or_offset = d.ReadRef();
       if (Field::StaticBit::decode(field->untag()->kind_bits_)) {
-        const intptr_t field_id = d->ReadUnsigned();
-        d->initial_field_table()->SetAt(
+        const intptr_t field_id = d.ReadUnsigned();
+        d_->initial_field_table()->SetAt(
             field_id, static_cast<InstancePtr>(value_or_offset));
         field->untag()->host_offset_or_field_id_ = Smi::New(field_id);
       } else {
@@ -1539,7 +1550,7 @@
   void PostLoad(Deserializer* d, const Array& refs, bool primary) {
     Field& field = Field::Handle(d->zone());
     if (!IsolateGroup::Current()->use_field_guards()) {
-      for (intptr_t i = start_index_; i < stop_index_; i++) {
+      for (intptr_t i = start_index_, n = stop_index_; i < n; i++) {
         field ^= refs.At(i);
         field.set_guarded_cid_unsafe(kDynamicCid);
         field.set_is_nullable_unsafe(true);
@@ -1550,7 +1561,7 @@
             StaticTypeExactnessState::NotTracking());
       }
     } else {
-      for (intptr_t i = start_index_; i < stop_index_; i++) {
+      for (intptr_t i = start_index_, n = stop_index_; i < n; i++) {
         field ^= refs.At(i);
         field.InitializeGuardedListLengthInObjectOffset(/*unsafe=*/true);
       }
@@ -1616,17 +1627,19 @@
     ReadAllocFixedSize(d, Script::InstanceSize());
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
     ASSERT(!is_canonical());  // Never canonical.
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      ScriptPtr script = static_cast<ScriptPtr>(d->Ref(id));
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      ScriptPtr script = static_cast<ScriptPtr>(d.Ref(id));
       Deserializer::InitializeHeader(script, kScriptCid,
                                      Script::InstanceSize());
-      ReadFromTo(script);
+      d.ReadFromTo(script);
 #if !defined(DART_PRECOMPILED_RUNTIME)
-      script->untag()->flags_and_max_position_ = d->Read<int32_t>();
+      script->untag()->flags_and_max_position_ = d.Read<int32_t>();
 #endif
-      script->untag()->kernel_script_index_ = d->Read<int32_t>();
+      script->untag()->kernel_script_index_ = d.Read<int32_t>();
       script->untag()->load_timestamp_ = 0;
     }
   }
@@ -1686,23 +1699,24 @@
     ReadAllocFixedSize(d, Library::InstanceSize());
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
     ASSERT(!is_canonical());  // Never canonical.
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      LibraryPtr lib = static_cast<LibraryPtr>(d->Ref(id));
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      LibraryPtr lib = static_cast<LibraryPtr>(d.Ref(id));
       Deserializer::InitializeHeader(lib, kLibraryCid, Library::InstanceSize());
-      ReadFromTo(lib);
+      d.ReadFromTo(lib);
       lib->untag()->native_entry_resolver_ = NULL;
       lib->untag()->native_entry_symbol_resolver_ = NULL;
-      lib->untag()->index_ = d->Read<int32_t>();
-      lib->untag()->num_imports_ = d->Read<uint16_t>();
-      lib->untag()->load_state_ = d->Read<int8_t>();
+      lib->untag()->index_ = d.Read<int32_t>();
+      lib->untag()->num_imports_ = d.Read<uint16_t>();
+      lib->untag()->load_state_ = d.Read<int8_t>();
       lib->untag()->flags_ =
-          UntaggedLibrary::InFullSnapshotBit::update(true, d->Read<uint8_t>());
+          UntaggedLibrary::InFullSnapshotBit::update(true, d.Read<uint8_t>());
 #if !defined(DART_PRECOMPILED_RUNTIME)
-      if (d->kind() != Snapshot::kFullAOT) {
-        lib->untag()->kernel_offset_ = d->Read<uint32_t>();
-      }
+      ASSERT(d_->kind() != Snapshot::kFullAOT);
+      lib->untag()->kernel_offset_ = d.Read<uint32_t>();
 #endif
     }
   }
@@ -1755,13 +1769,15 @@
     ReadAllocFixedSize(d, Namespace::InstanceSize());
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
     ASSERT(!is_canonical());  // Never canonical.
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      NamespacePtr ns = static_cast<NamespacePtr>(d->Ref(id));
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      NamespacePtr ns = static_cast<NamespacePtr>(d.Ref(id));
       Deserializer::InitializeHeader(ns, kNamespaceCid,
                                      Namespace::InstanceSize());
-      ReadFromTo(ns);
+      d.ReadFromTo(ns);
     }
   }
 };
@@ -1818,21 +1834,23 @@
     ReadAllocFixedSize(d, KernelProgramInfo::InstanceSize());
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
     ASSERT(!is_canonical());  // Never canonical.
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      KernelProgramInfoPtr info = static_cast<KernelProgramInfoPtr>(d->Ref(id));
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      KernelProgramInfoPtr info = static_cast<KernelProgramInfoPtr>(d.Ref(id));
       Deserializer::InitializeHeader(info, kKernelProgramInfoCid,
                                      KernelProgramInfo::InstanceSize());
-      ReadFromTo(info);
-      info->untag()->kernel_binary_version_ = d->Read<uint32_t>();
+      d.ReadFromTo(info);
+      info->untag()->kernel_binary_version_ = d.Read<uint32_t>();
     }
   }
 
   void PostLoad(Deserializer* d, const Array& refs, bool primary) {
     Array& array = Array::Handle(d->zone());
     KernelProgramInfo& info = KernelProgramInfo::Handle(d->zone());
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
       info ^= refs.At(id);
       array = HashTables::New<UnorderedHashMap<SmiTraits>>(16, Heap::kOld);
       info.set_libraries_cache(array);
@@ -2273,64 +2291,71 @@
 
   void ReadFill(Deserializer* d, bool primary) {
     ASSERT(!is_canonical());  // Never canonical.
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      ReadFill(d, id, false);
-    }
-    for (intptr_t id = deferred_start_index_; id < deferred_stop_index_; id++) {
-      ReadFill(d, id, true);
-    }
+    ReadFill(d, start_index_, stop_index_, false);
+#if defined(DART_PRECOMPILED_RUNTIME)
+    ReadFill(d, deferred_start_index_, deferred_stop_index_, true);
+#else
+    ASSERT(deferred_start_index_ == deferred_stop_index_);
+#endif
   }
 
-  void ReadFill(Deserializer* d, intptr_t id, bool deferred) {
-    auto const code = static_cast<CodePtr>(d->Ref(id));
+  void ReadFill(Deserializer* d,
+                intptr_t start_index,
+                intptr_t stop_index,
+                bool deferred) {
+    for (intptr_t id = start_index, n = stop_index; id < n; id++) {
+      auto const code = static_cast<CodePtr>(d->Ref(id));
 
-    ASSERT(!Code::IsUnknownDartCode(code));
+      ASSERT(!Code::IsUnknownDartCode(code));
 
-    Deserializer::InitializeHeader(code, kCodeCid, Code::InstanceSize(0));
-    ASSERT(!Code::IsDiscarded(code));
+      Deserializer::InitializeHeader(code, kCodeCid, Code::InstanceSize(0));
+      ASSERT(!Code::IsDiscarded(code));
 
-    d->ReadInstructions(code, deferred);
-
-    // There would be a single global pool if this is a full AOT snapshot
-    // with bare instructions.
-    if (d->kind() != Snapshot::kFullAOT) {
-      code->untag()->object_pool_ = static_cast<ObjectPoolPtr>(d->ReadRef());
-    } else {
-      code->untag()->object_pool_ = ObjectPool::null();
-    }
-    code->untag()->owner_ = d->ReadRef();
-    code->untag()->exception_handlers_ =
-        static_cast<ExceptionHandlersPtr>(d->ReadRef());
-    code->untag()->pc_descriptors_ =
-        static_cast<PcDescriptorsPtr>(d->ReadRef());
-    code->untag()->catch_entry_ = d->ReadRef();
-    if (d->kind() == Snapshot::kFullJIT) {
-      code->untag()->compressed_stackmaps_ =
-          static_cast<CompressedStackMapsPtr>(d->ReadRef());
-    } else if (d->kind() == Snapshot::kFullAOT) {
-      code->untag()->compressed_stackmaps_ = CompressedStackMaps::null();
-    }
-    code->untag()->inlined_id_to_function_ =
-        static_cast<ArrayPtr>(d->ReadRef());
-    code->untag()->code_source_map_ =
-        static_cast<CodeSourceMapPtr>(d->ReadRef());
+      d->ReadInstructions(code, deferred);
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-    if (d->kind() == Snapshot::kFullJIT) {
+      ASSERT(d->kind() == Snapshot::kFullJIT);
+      code->untag()->object_pool_ = static_cast<ObjectPoolPtr>(d->ReadRef());
+#else
+      ASSERT(d->kind() == Snapshot::kFullAOT);
+      // There is a single global pool.
+      code->untag()->object_pool_ = ObjectPool::null();
+#endif
+      code->untag()->owner_ = d->ReadRef();
+      code->untag()->exception_handlers_ =
+          static_cast<ExceptionHandlersPtr>(d->ReadRef());
+      code->untag()->pc_descriptors_ =
+          static_cast<PcDescriptorsPtr>(d->ReadRef());
+      code->untag()->catch_entry_ = d->ReadRef();
+#if !defined(DART_PRECOMPILED_RUNTIME)
+      ASSERT(d->kind() == Snapshot::kFullJIT);
+      code->untag()->compressed_stackmaps_ =
+          static_cast<CompressedStackMapsPtr>(d->ReadRef());
+#else
+      ASSERT(d->kind() == Snapshot::kFullAOT);
+      code->untag()->compressed_stackmaps_ = CompressedStackMaps::null();
+#endif
+      code->untag()->inlined_id_to_function_ =
+          static_cast<ArrayPtr>(d->ReadRef());
+      code->untag()->code_source_map_ =
+          static_cast<CodeSourceMapPtr>(d->ReadRef());
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+      ASSERT(d->kind() == Snapshot::kFullJIT);
       code->untag()->deopt_info_array_ = static_cast<ArrayPtr>(d->ReadRef());
       code->untag()->static_calls_target_table_ =
           static_cast<ArrayPtr>(d->ReadRef());
-    }
 #endif  // !DART_PRECOMPILED_RUNTIME
 
 #if !defined(PRODUCT)
-    code->untag()->return_address_metadata_ = d->ReadRef();
-    code->untag()->var_descriptors_ = LocalVarDescriptors::null();
-    code->untag()->comments_ = FLAG_code_comments
-                                   ? static_cast<ArrayPtr>(d->ReadRef())
-                                   : Array::null();
-    code->untag()->compile_timestamp_ = 0;
+      code->untag()->return_address_metadata_ = d->ReadRef();
+      code->untag()->var_descriptors_ = LocalVarDescriptors::null();
+      code->untag()->comments_ = FLAG_code_comments
+                                     ? static_cast<ArrayPtr>(d->ReadRef())
+                                     : Array::null();
+      code->untag()->compile_timestamp_ = 0;
 #endif
+    }
   }
 
   void PostLoad(Deserializer* d, const Array& refs, bool primary) {
@@ -2343,7 +2368,7 @@
 #if !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
     Object& owner = Object::Handle(d->zone());
 #endif
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
       code ^= refs.At(id);
 #if !defined(DART_PRECOMPILED_RUNTIME) && !defined(PRODUCT)
       if (CodeObservers::AreActive()) {
@@ -2506,9 +2531,11 @@
     stop_index_ = d->next_index();
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
     ASSERT(!is_canonical());  // Never canonical.
-    fill_position_ = d->position();
+    fill_position_ = d.Position();
 #if defined(DART_PRECOMPILED_RUNTIME)
     const uint8_t immediate_bits =
         ObjectPool::EncodeBits(ObjectPool::EntryType::kImmediate,
@@ -2521,22 +2548,22 @@
         StubCode::MegamorphicCall().MonomorphicEntryPoint();
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
 
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      const intptr_t length = d->ReadUnsigned();
-      ObjectPoolPtr pool = static_cast<ObjectPoolPtr>(d->Ref(id));
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      const intptr_t length = d.ReadUnsigned();
+      ObjectPoolPtr pool = static_cast<ObjectPoolPtr>(d.Ref(id));
       Deserializer::InitializeHeader(pool, kObjectPoolCid,
                                      ObjectPool::InstanceSize(length));
       pool->untag()->length_ = length;
       for (intptr_t j = 0; j < length; j++) {
-        const uint8_t entry_bits = d->Read<uint8_t>();
+        const uint8_t entry_bits = d.Read<uint8_t>();
         pool->untag()->entry_bits()[j] = entry_bits;
         UntaggedObjectPool::Entry& entry = pool->untag()->data()[j];
         switch (ObjectPool::TypeBits::decode(entry_bits)) {
           case ObjectPool::EntryType::kTaggedObject:
-            entry.raw_obj_ = d->ReadRef();
+            entry.raw_obj_ = d.ReadRef();
             break;
           case ObjectPool::EntryType::kImmediate:
-            entry.raw_value_ = d->Read<intptr_t>();
+            entry.raw_value_ = d.Read<intptr_t>();
             break;
           case ObjectPool::EntryType::kNativeFunction: {
             // Read nothing. Initialize with the lazy link entry.
@@ -2574,7 +2601,7 @@
       auto Z = d->zone();
       ObjectPool& pool = ObjectPool::Handle(Z);
       Object& entry = Object::Handle(Z);
-      for (intptr_t id = start_index_; id < stop_index_; id++) {
+      for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
         pool ^= refs.At(id);
         const intptr_t length = d->ReadUnsigned();
         for (intptr_t j = 0; j < length; j++) {
@@ -2712,16 +2739,18 @@
     stop_index_ = d->next_index();
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
     ASSERT(!is_canonical());  // Never canonical.
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      const intptr_t length = d->ReadUnsigned();
-      PcDescriptorsPtr desc = static_cast<PcDescriptorsPtr>(d->Ref(id));
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      const intptr_t length = d.ReadUnsigned();
+      PcDescriptorsPtr desc = static_cast<PcDescriptorsPtr>(d.Ref(id));
       Deserializer::InitializeHeader(desc, kPcDescriptorsCid,
                                      PcDescriptors::InstanceSize(length));
       desc->untag()->length_ = length;
       uint8_t* cdata = reinterpret_cast<uint8_t*>(desc->untag()->data());
-      d->ReadBytes(cdata, length);
+      d.ReadBytes(cdata, length);
     }
   }
 };
@@ -2787,15 +2816,17 @@
     stop_index_ = d->next_index();
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      const intptr_t length = d->ReadUnsigned();
-      CodeSourceMapPtr map = static_cast<CodeSourceMapPtr>(d->Ref(id));
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      const intptr_t length = d.ReadUnsigned();
+      CodeSourceMapPtr map = static_cast<CodeSourceMapPtr>(d.Ref(id));
       Deserializer::InitializeHeader(map, kPcDescriptorsCid,
                                      CodeSourceMap::InstanceSize(length));
       map->untag()->length_ = length;
       uint8_t* cdata = reinterpret_cast<uint8_t*>(map->untag()->data());
-      d->ReadBytes(cdata, length);
+      d.ReadBytes(cdata, length);
     }
   }
 };
@@ -2865,19 +2896,21 @@
     stop_index_ = d->next_index();
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      const intptr_t flags_and_size = d->ReadUnsigned();
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      const intptr_t flags_and_size = d.ReadUnsigned();
       const intptr_t length =
           UntaggedCompressedStackMaps::SizeField::decode(flags_and_size);
       CompressedStackMapsPtr map =
-          static_cast<CompressedStackMapsPtr>(d->Ref(id));
+          static_cast<CompressedStackMapsPtr>(d.Ref(id));
       Deserializer::InitializeHeader(map, kCompressedStackMapsCid,
                                      CompressedStackMaps::InstanceSize(length));
       map->untag()->payload()->set_flags_and_size(flags_and_size);
       uint8_t* cdata =
           reinterpret_cast<uint8_t*>(map->untag()->payload()->data());
-      d->ReadBytes(cdata, length);
+      d.ReadBytes(cdata, length);
     }
   }
 };
@@ -2983,7 +3016,9 @@
     }
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
     // No-op.
   }
 
@@ -3026,7 +3061,7 @@
       ExceptionHandlersPtr handlers = objects_[i];
       s->AssignRef(handlers);
       AutoTraceObject(handlers);
-      const intptr_t length = handlers->untag()->num_entries_;
+      const intptr_t length = handlers->untag()->num_entries();
       s->WriteUnsigned(length);
       target_memory_size_ +=
           compiler::target::ExceptionHandlers::InstanceSize(length);
@@ -3038,8 +3073,10 @@
     for (intptr_t i = 0; i < count; i++) {
       ExceptionHandlersPtr handlers = objects_[i];
       AutoTraceObject(handlers);
-      const intptr_t length = handlers->untag()->num_entries_;
-      s->WriteUnsigned(length);
+      const intptr_t packed_fields = handlers->untag()->packed_fields_;
+      const intptr_t length =
+          UntaggedExceptionHandlers::NumEntriesBits::decode(packed_fields);
+      s->WriteUnsigned(packed_fields);
       WriteCompressedField(handlers, handled_types_data);
       for (intptr_t j = 0; j < length; j++) {
         const ExceptionHandlerInfo& info = handlers->untag()->data()[j];
@@ -3075,24 +3112,28 @@
     stop_index_ = d->next_index();
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
     ASSERT(!is_canonical());  // Never canonical.
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
       ExceptionHandlersPtr handlers =
-          static_cast<ExceptionHandlersPtr>(d->Ref(id));
-      const intptr_t length = d->ReadUnsigned();
+          static_cast<ExceptionHandlersPtr>(d.Ref(id));
+      const intptr_t packed_fields = d.ReadUnsigned();
+      const intptr_t length =
+          UntaggedExceptionHandlers::NumEntriesBits::decode(packed_fields);
       Deserializer::InitializeHeader(handlers, kExceptionHandlersCid,
                                      ExceptionHandlers::InstanceSize(length));
-      handlers->untag()->num_entries_ = length;
+      handlers->untag()->packed_fields_ = packed_fields;
       handlers->untag()->handled_types_data_ =
-          static_cast<ArrayPtr>(d->ReadRef());
+          static_cast<ArrayPtr>(d.ReadRef());
       for (intptr_t j = 0; j < length; j++) {
         ExceptionHandlerInfo& info = handlers->untag()->data()[j];
-        info.handler_pc_offset = d->Read<uint32_t>();
-        info.outer_try_index = d->Read<int16_t>();
-        info.needs_stacktrace = d->Read<int8_t>();
-        info.has_catch_all = d->Read<int8_t>();
-        info.is_generated = d->Read<int8_t>();
+        info.handler_pc_offset = d.Read<uint32_t>();
+        info.outer_try_index = d.Read<int16_t>();
+        info.needs_stacktrace = d.Read<int8_t>();
+        info.has_catch_all = d.Read<int8_t>();
+        info.is_generated = d.Read<int8_t>();
       }
     }
   }
@@ -3164,17 +3205,19 @@
     stop_index_ = d->next_index();
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
     ASSERT(!is_canonical());  // Never canonical.
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      ContextPtr context = static_cast<ContextPtr>(d->Ref(id));
-      const intptr_t length = d->ReadUnsigned();
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      ContextPtr context = static_cast<ContextPtr>(d.Ref(id));
+      const intptr_t length = d.ReadUnsigned();
       Deserializer::InitializeHeader(context, kContextCid,
                                      Context::InstanceSize(length));
       context->untag()->num_variables_ = length;
-      context->untag()->parent_ = static_cast<ContextPtr>(d->ReadRef());
+      context->untag()->parent_ = static_cast<ContextPtr>(d.ReadRef());
       for (intptr_t j = 0; j < length; j++) {
-        context->untag()->data()[j] = d->ReadRef();
+        context->untag()->data()[j] = d.ReadRef();
       }
     }
   }
@@ -3244,16 +3287,18 @@
     stop_index_ = d->next_index();
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
     ASSERT(!is_canonical());  // Never canonical.
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      ContextScopePtr scope = static_cast<ContextScopePtr>(d->Ref(id));
-      const intptr_t length = d->ReadUnsigned();
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      ContextScopePtr scope = static_cast<ContextScopePtr>(d.Ref(id));
+      const intptr_t length = d.ReadUnsigned();
       Deserializer::InitializeHeader(scope, kContextScopeCid,
                                      ContextScope::InstanceSize(length));
       scope->untag()->num_variables_ = length;
-      scope->untag()->is_implicit_ = d->Read<bool>();
-      ReadFromTo(scope, length);
+      scope->untag()->is_implicit_ = d.Read<bool>();
+      d.ReadFromTo(scope, length);
     }
   }
 };
@@ -3307,14 +3352,16 @@
     ReadAllocFixedSize(d, UnlinkedCall::InstanceSize());
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
     ASSERT(!is_canonical());  // Never canonical.
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      UnlinkedCallPtr unlinked = static_cast<UnlinkedCallPtr>(d->Ref(id));
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      UnlinkedCallPtr unlinked = static_cast<UnlinkedCallPtr>(d.Ref(id));
       Deserializer::InitializeHeader(unlinked, kUnlinkedCallCid,
                                      UnlinkedCall::InstanceSize());
-      ReadFromTo(unlinked);
-      unlinked->untag()->can_patch_to_monomorphic_ = d->Read<bool>();
+      d.ReadFromTo(unlinked);
+      unlinked->untag()->can_patch_to_monomorphic_ = d.Read<bool>();
     }
   }
 };
@@ -3371,14 +3418,16 @@
     ReadAllocFixedSize(d, ICData::InstanceSize());
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
     ASSERT(!is_canonical());  // Never canonical.
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      ICDataPtr ic = static_cast<ICDataPtr>(d->Ref(id));
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      ICDataPtr ic = static_cast<ICDataPtr>(d.Ref(id));
       Deserializer::InitializeHeader(ic, kICDataCid, ICData::InstanceSize());
-      ReadFromTo(ic);
-      NOT_IN_PRECOMPILED(ic->untag()->deopt_id_ = d->Read<int32_t>());
-      ic->untag()->state_bits_ = d->Read<int32_t>();
+      d.ReadFromTo(ic);
+      NOT_IN_PRECOMPILED(ic->untag()->deopt_id_ = d.Read<int32_t>());
+      ic->untag()->state_bits_ = d.Read<int32_t>();
     }
   }
 };
@@ -3433,14 +3482,16 @@
     ReadAllocFixedSize(d, MegamorphicCache::InstanceSize());
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
     ASSERT(!is_canonical());  // Never canonical.
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      MegamorphicCachePtr cache = static_cast<MegamorphicCachePtr>(d->Ref(id));
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      MegamorphicCachePtr cache = static_cast<MegamorphicCachePtr>(d.Ref(id));
       Deserializer::InitializeHeader(cache, kMegamorphicCacheCid,
                                      MegamorphicCache::InstanceSize());
-      ReadFromTo(cache);
-      cache->untag()->filled_entry_count_ = d->Read<int32_t>();
+      d.ReadFromTo(cache);
+      cache->untag()->filled_entry_count_ = d.Read<int32_t>();
     }
   }
 };
@@ -3494,13 +3545,15 @@
     ReadAllocFixedSize(d, SubtypeTestCache::InstanceSize());
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
     ASSERT(!is_canonical());  // Never canonical.
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      SubtypeTestCachePtr cache = static_cast<SubtypeTestCachePtr>(d->Ref(id));
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      SubtypeTestCachePtr cache = static_cast<SubtypeTestCachePtr>(d.Ref(id));
       Deserializer::InitializeHeader(cache, kSubtypeTestCacheCid,
                                      SubtypeTestCache::InstanceSize());
-      cache->untag()->cache_ = static_cast<ArrayPtr>(d->ReadRef());
+      cache->untag()->cache_ = static_cast<ArrayPtr>(d.ReadRef());
     }
   }
 };
@@ -3553,15 +3606,17 @@
     ReadAllocFixedSize(d, LoadingUnit::InstanceSize());
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
     ASSERT(!is_canonical());  // Never canonical.
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      LoadingUnitPtr unit = static_cast<LoadingUnitPtr>(d->Ref(id));
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      LoadingUnitPtr unit = static_cast<LoadingUnitPtr>(d.Ref(id));
       Deserializer::InitializeHeader(unit, kLoadingUnitCid,
                                      LoadingUnit::InstanceSize());
-      unit->untag()->parent_ = static_cast<LoadingUnitPtr>(d->ReadRef());
+      unit->untag()->parent_ = static_cast<LoadingUnitPtr>(d.ReadRef());
       unit->untag()->base_objects_ = Array::null();
-      unit->untag()->id_ = d->Read<int32_t>();
+      unit->untag()->id_ = d.Read<int32_t>();
       unit->untag()->loaded_ = false;
       unit->untag()->load_outstanding_ = false;
     }
@@ -3619,16 +3674,18 @@
     ReadAllocFixedSize(d, LanguageError::InstanceSize());
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
     ASSERT(!is_canonical());  // Never canonical.
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      LanguageErrorPtr error = static_cast<LanguageErrorPtr>(d->Ref(id));
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      LanguageErrorPtr error = static_cast<LanguageErrorPtr>(d.Ref(id));
       Deserializer::InitializeHeader(error, kLanguageErrorCid,
                                      LanguageError::InstanceSize());
-      ReadFromTo(error);
-      error->untag()->token_pos_ = d->ReadTokenPosition();
-      error->untag()->report_after_token_ = d->Read<bool>();
-      error->untag()->kind_ = d->Read<int8_t>();
+      d.ReadFromTo(error);
+      error->untag()->token_pos_ = d.ReadTokenPosition();
+      error->untag()->report_after_token_ = d.Read<bool>();
+      error->untag()->kind_ = d.Read<int8_t>();
     }
   }
 };
@@ -3682,14 +3739,16 @@
     ReadAllocFixedSize(d, UnhandledException::InstanceSize());
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
     ASSERT(!is_canonical());  // Never canonical.
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
       UnhandledExceptionPtr exception =
-          static_cast<UnhandledExceptionPtr>(d->Ref(id));
+          static_cast<UnhandledExceptionPtr>(d.Ref(id));
       Deserializer::InitializeHeader(exception, kUnhandledExceptionCid,
                                      UnhandledException::InstanceSize());
-      ReadFromTo(exception);
+      d.ReadFromTo(exception);
     }
   }
 };
@@ -3807,7 +3866,7 @@
       SafepointMutexLocker ml(
           d->isolate_group()->constant_canonicalization_mutex());
       Instance& instance = Instance::Handle(d->zone());
-      for (intptr_t i = start_index_; i < stop_index_; i++) {
+      for (intptr_t i = start_index_, n = stop_index_; i < n; i++) {
         instance ^= refs.At(i);
         instance = instance.CanonicalizeLocked(d->thread());
         refs.SetAt(i, instance);
@@ -3839,28 +3898,32 @@
     stop_index_ = d->next_index();
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
+    const intptr_t cid = cid_;
+    const bool mark_canonical = primary && is_canonical();
     intptr_t next_field_offset = next_field_offset_in_words_
                                  << kCompressedWordSizeLog2;
     intptr_t instance_size = Object::RoundedAllocationSize(
         instance_size_in_words_ * kCompressedWordSize);
-    const UnboxedFieldBitmap unboxed_fields_bitmap(d->ReadUnsigned64());
+    const UnboxedFieldBitmap unboxed_fields_bitmap(d.ReadUnsigned64());
 
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      InstancePtr instance = static_cast<InstancePtr>(d->Ref(id));
-      Deserializer::InitializeHeader(instance, cid_, instance_size,
-                                     primary && is_canonical());
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      InstancePtr instance = static_cast<InstancePtr>(d.Ref(id));
+      Deserializer::InitializeHeader(instance, cid, instance_size,
+                                     mark_canonical);
       intptr_t offset = Instance::NextFieldOffset();
       while (offset < next_field_offset) {
         if (unboxed_fields_bitmap.Get(offset / kCompressedWordSize)) {
           compressed_uword* p = reinterpret_cast<compressed_uword*>(
               reinterpret_cast<uword>(instance->untag()) + offset);
           // Reads 32 bits of the unboxed value at a time
-          *p = d->ReadWordWith32BitReads();
+          *p = d.ReadWordWith32BitReads();
         } else {
           CompressedObjectPtr* p = reinterpret_cast<CompressedObjectPtr*>(
               reinterpret_cast<uword>(instance->untag()) + offset);
-          *p = d->ReadRef();
+          *p = d.ReadRef();
         }
         offset += kCompressedWordSize;
       }
@@ -3930,15 +3993,17 @@
     ReadAllocFixedSize(d, LibraryPrefix::InstanceSize());
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
     ASSERT(!is_canonical());  // Never canonical.
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      LibraryPrefixPtr prefix = static_cast<LibraryPrefixPtr>(d->Ref(id));
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      LibraryPrefixPtr prefix = static_cast<LibraryPrefixPtr>(d.Ref(id));
       Deserializer::InitializeHeader(prefix, kLibraryPrefixCid,
                                      LibraryPrefix::InstanceSize());
-      ReadFromTo(prefix);
-      prefix->untag()->num_imports_ = d->Read<uint16_t>();
-      prefix->untag()->is_deferred_load_ = d->Read<bool>();
+      d.ReadFromTo(prefix);
+      prefix->untag()->num_imports_ = d.Read<uint16_t>();
+      prefix->untag()->is_deferred_load_ = d.Read<bool>();
     }
   }
 };
@@ -4051,16 +4116,19 @@
     BuildCanonicalSetFromLayout(d);
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      TypePtr type = static_cast<TypePtr>(d->Ref(id));
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
+    const bool mark_canonical = primary && is_canonical();
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      TypePtr type = static_cast<TypePtr>(d.Ref(id));
       Deserializer::InitializeHeader(type, kTypeCid, Type::InstanceSize(),
-                                     primary && is_canonical());
-      ReadFromTo(type);
+                                     mark_canonical);
+      d.ReadFromTo(type);
       COMPILE_ASSERT(
           std::is_unsigned<decltype(UntaggedType::type_class_id_)>::value);
-      type->untag()->type_class_id_ = d->ReadUnsigned();
-      const uint8_t combined = d->Read<uint8_t>();
+      type->untag()->type_class_id_ = d.ReadUnsigned();
+      const uint8_t combined = d.Read<uint8_t>();
       type->untag()->type_state_ = combined >> kNullabilityBitSize;
       type->untag()->nullability_ = combined & kNullabilityBitMask;
     }
@@ -4074,7 +4142,7 @@
       object_store->set_canonical_types(table_);
     } else if (!primary && is_canonical()) {
       AbstractType& type = AbstractType::Handle(d->zone());
-      for (intptr_t i = start_index_; i < stop_index_; i++) {
+      for (intptr_t i = start_index_, n = stop_index_; i < n; i++) {
         type ^= refs.At(i);
         type = type.Canonicalize(d->thread(), nullptr);
         refs.SetAt(i, type);
@@ -4085,12 +4153,12 @@
     Code& stub = Code::Handle(d->zone());
 
     if (Snapshot::IncludesCode(d->kind())) {
-      for (intptr_t id = start_index_; id < stop_index_; id++) {
+      for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
         type ^= refs.At(id);
         type.UpdateTypeTestingStubEntryPoint();
       }
     } else {
-      for (intptr_t id = start_index_; id < stop_index_; id++) {
+      for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
         type ^= refs.At(id);
         stub = TypeTestingStubGenerator::DefaultCodeForType(type);
         type.InitializeTypeTestingStubNonAtomic(stub);
@@ -4178,18 +4246,20 @@
     BuildCanonicalSetFromLayout(d);
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      FunctionTypePtr type = static_cast<FunctionTypePtr>(d->Ref(id));
-      Deserializer::InitializeHeader(type, kFunctionTypeCid,
-                                     FunctionType::InstanceSize(),
-                                     primary && is_canonical());
-      ReadFromTo(type);
-      const uint8_t combined = d->Read<uint8_t>();
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
+    const bool mark_canonical = primary && is_canonical();
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      FunctionTypePtr type = static_cast<FunctionTypePtr>(d.Ref(id));
+      Deserializer::InitializeHeader(
+          type, kFunctionTypeCid, FunctionType::InstanceSize(), mark_canonical);
+      d.ReadFromTo(type);
+      const uint8_t combined = d.Read<uint8_t>();
       type->untag()->type_state_ = combined >> kNullabilityBitSize;
       type->untag()->nullability_ = combined & kNullabilityBitMask;
-      type->untag()->packed_parameter_counts_ = d->Read<uint32_t>();
-      type->untag()->packed_type_parameter_counts_ = d->Read<uint16_t>();
+      type->untag()->packed_parameter_counts_ = d.Read<uint32_t>();
+      type->untag()->packed_type_parameter_counts_ = d.Read<uint16_t>();
     }
   }
 
@@ -4201,7 +4271,7 @@
       object_store->set_canonical_function_types(table_);
     } else if (!primary && is_canonical()) {
       AbstractType& type = AbstractType::Handle(d->zone());
-      for (intptr_t i = start_index_; i < stop_index_; i++) {
+      for (intptr_t i = start_index_, n = stop_index_; i < n; i++) {
         type ^= refs.At(i);
         type = type.Canonicalize(d->thread(), nullptr);
         refs.SetAt(i, type);
@@ -4212,12 +4282,12 @@
     Code& stub = Code::Handle(d->zone());
 
     if (Snapshot::IncludesCode(d->kind())) {
-      for (intptr_t id = start_index_; id < stop_index_; id++) {
+      for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
         type ^= refs.At(id);
         type.UpdateTypeTestingStubEntryPoint();
       }
     } else {
-      for (intptr_t id = start_index_; id < stop_index_; id++) {
+      for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
         type ^= refs.At(id);
         stub = TypeTestingStubGenerator::DefaultCodeForType(type);
         type.InitializeTypeTestingStubNonAtomic(stub);
@@ -4273,19 +4343,22 @@
     ReadAllocFixedSize(d, TypeRef::InstanceSize());
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      TypeRefPtr type = static_cast<TypeRefPtr>(d->Ref(id));
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
+    const bool mark_canonical = primary && is_canonical();
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      TypeRefPtr type = static_cast<TypeRefPtr>(d.Ref(id));
       Deserializer::InitializeHeader(type, kTypeRefCid, TypeRef::InstanceSize(),
-                                     primary && is_canonical());
-      ReadFromTo(type);
+                                     mark_canonical);
+      d.ReadFromTo(type);
     }
   }
 
   void PostLoad(Deserializer* d, const Array& refs, bool primary) {
     if (!primary && is_canonical()) {
       AbstractType& type = AbstractType::Handle(d->zone());
-      for (intptr_t i = start_index_; i < stop_index_; i++) {
+      for (intptr_t i = start_index_, n = stop_index_; i < n; i++) {
         type ^= refs.At(i);
         type = type.Canonicalize(d->thread(), nullptr);
         refs.SetAt(i, type);
@@ -4296,12 +4369,12 @@
     Code& stub = Code::Handle(d->zone());
 
     if (Snapshot::IncludesCode(d->kind())) {
-      for (intptr_t id = start_index_; id < stop_index_; id++) {
+      for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
         type_ref ^= refs.At(id);
         type_ref.UpdateTypeTestingStubEntryPoint();
       }
     } else {
-      for (intptr_t id = start_index_; id < stop_index_; id++) {
+      for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
         type_ref ^= refs.At(id);
         stub = TypeTestingStubGenerator::DefaultCodeForType(type_ref);
         type_ref.InitializeTypeTestingStubNonAtomic(stub);
@@ -4387,17 +4460,20 @@
     BuildCanonicalSetFromLayout(d);
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      TypeParameterPtr type = static_cast<TypeParameterPtr>(d->Ref(id));
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
+    const bool mark_canonical = primary && is_canonical();
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      TypeParameterPtr type = static_cast<TypeParameterPtr>(d.Ref(id));
       Deserializer::InitializeHeader(type, kTypeParameterCid,
                                      TypeParameter::InstanceSize(),
-                                     primary && is_canonical());
-      ReadFromTo(type);
-      type->untag()->parameterized_class_id_ = d->Read<int32_t>();
-      type->untag()->base_ = d->Read<uint8_t>();
-      type->untag()->index_ = d->Read<uint8_t>();
-      const uint8_t combined = d->Read<uint8_t>();
+                                     mark_canonical);
+      d.ReadFromTo(type);
+      type->untag()->parameterized_class_id_ = d.Read<int32_t>();
+      type->untag()->base_ = d.Read<uint8_t>();
+      type->untag()->index_ = d.Read<uint8_t>();
+      const uint8_t combined = d.Read<uint8_t>();
       type->untag()->flags_ = combined >> kNullabilityBitSize;
       type->untag()->nullability_ = combined & kNullabilityBitMask;
     }
@@ -4411,7 +4487,7 @@
       object_store->set_canonical_type_parameters(table_);
     } else if (!primary && is_canonical()) {
       TypeParameter& type_param = TypeParameter::Handle(d->zone());
-      for (intptr_t i = start_index_; i < stop_index_; i++) {
+      for (intptr_t i = start_index_, n = stop_index_; i < n; i++) {
         type_param ^= refs.At(i);
         type_param ^= type_param.Canonicalize(d->thread(), nullptr);
         refs.SetAt(i, type_param);
@@ -4422,12 +4498,12 @@
     Code& stub = Code::Handle(d->zone());
 
     if (Snapshot::IncludesCode(d->kind())) {
-      for (intptr_t id = start_index_; id < stop_index_; id++) {
+      for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
         type_param ^= refs.At(id);
         type_param.UpdateTypeTestingStubEntryPoint();
       }
     } else {
-      for (intptr_t id = start_index_; id < stop_index_; id++) {
+      for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
         type_param ^= refs.At(id);
         stub = TypeTestingStubGenerator::DefaultCodeForType(type_param);
         type_param.InitializeTypeTestingStubNonAtomic(stub);
@@ -4486,13 +4562,15 @@
     ReadAllocFixedSize(d, Closure::InstanceSize());
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      ClosurePtr closure = static_cast<ClosurePtr>(d->Ref(id));
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
+    const bool mark_canonical = primary && is_canonical();
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      ClosurePtr closure = static_cast<ClosurePtr>(d.Ref(id));
       Deserializer::InitializeHeader(closure, kClosureCid,
-                                     Closure::InstanceSize(),
-                                     primary && is_canonical());
-      ReadFromTo(closure);
+                                     Closure::InstanceSize(), mark_canonical);
+      d.ReadFromTo(closure);
 #if defined(DART_PRECOMPILED_RUNTIME)
       closure->untag()->entry_point_ = 0;
 #endif
@@ -4503,16 +4581,15 @@
   void PostLoad(Deserializer* d, const Array& refs, bool primary) {
     // We only cache the entry point in bare instructions mode (as we need
     // to load the function anyway otherwise).
-    if (d->kind() == Snapshot::kFullAOT) {
-      auto& closure = Closure::Handle(d->zone());
-      auto& func = Function::Handle(d->zone());
-      for (intptr_t i = start_index_; i < stop_index_; i++) {
-        closure ^= refs.At(i);
-        func = closure.function();
-        uword entry_point = func.entry_point();
-        ASSERT(entry_point != 0);
-        closure.ptr()->untag()->entry_point_ = entry_point;
-      }
+    ASSERT(d->kind() == Snapshot::kFullAOT);
+    auto& closure = Closure::Handle(d->zone());
+    auto& func = Function::Handle(d->zone());
+    for (intptr_t i = start_index_, n = stop_index_; i < n; i++) {
+      closure ^= refs.At(i);
+      func = closure.function();
+      uword entry_point = func.entry_point();
+      ASSERT(entry_point != 0);
+      closure.ptr()->untag()->entry_point_ = entry_point;
     }
   }
 #endif
@@ -4579,6 +4656,7 @@
 
     start_index_ = d->next_index();
     const intptr_t count = d->ReadUnsigned();
+    const bool mark_canonical = is_canonical();
     for (intptr_t i = 0; i < count; i++) {
       int64_t value = d->Read<int64_t>();
       if (Smi::IsValid(value)) {
@@ -4587,7 +4665,7 @@
         MintPtr mint = static_cast<MintPtr>(
             old_space->AllocateSnapshot(Mint::InstanceSize()));
         Deserializer::InitializeHeader(mint, kMintCid, Mint::InstanceSize(),
-                                       is_canonical());
+                                       mark_canonical);
         mint->untag()->value_ = value;
         d->AssignRef(mint);
       }
@@ -4595,7 +4673,7 @@
     stop_index_ = d->next_index();
   }
 
-  void ReadFill(Deserializer* d, bool primary) {}
+  void ReadFill(Deserializer* d_, bool primary) { Deserializer::Local d(d_); }
 };
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
@@ -4647,12 +4725,14 @@
     ReadAllocFixedSize(d, Double::InstanceSize());
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      DoublePtr dbl = static_cast<DoublePtr>(d->Ref(id));
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+    const bool mark_canonical = primary && is_canonical();
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      DoublePtr dbl = static_cast<DoublePtr>(d.Ref(id));
       Deserializer::InitializeHeader(dbl, kDoubleCid, Double::InstanceSize(),
-                                     primary && is_canonical());
-      dbl->untag()->value_ = d->Read<double>();
+                                     mark_canonical);
+      dbl->untag()->value_ = d.Read<double>();
     }
   }
 };
@@ -4707,13 +4787,15 @@
     ReadAllocFixedSize(d, GrowableObjectArray::InstanceSize());
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
       GrowableObjectArrayPtr list =
-          static_cast<GrowableObjectArrayPtr>(d->Ref(id));
+          static_cast<GrowableObjectArrayPtr>(d.Ref(id));
       Deserializer::InitializeHeader(list, kGrowableObjectArrayCid,
                                      GrowableObjectArray::InstanceSize());
-      ReadFromTo(list);
+      d.ReadFromTo(list);
     }
   }
 };
@@ -4782,20 +4864,23 @@
     stop_index_ = d->next_index();
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
     ASSERT(!is_canonical());  // Never canonical.
     intptr_t element_size = TypedData::ElementSizeInBytes(cid_);
 
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      TypedDataPtr data = static_cast<TypedDataPtr>(d->Ref(id));
-      const intptr_t length = d->ReadUnsigned();
+    const intptr_t cid = cid_;
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      TypedDataPtr data = static_cast<TypedDataPtr>(d.Ref(id));
+      const intptr_t length = d.ReadUnsigned();
       const intptr_t length_in_bytes = length * element_size;
-      Deserializer::InitializeHeader(data, cid_,
+      Deserializer::InitializeHeader(data, cid,
                                      TypedData::InstanceSize(length_in_bytes));
       data->untag()->length_ = Smi::New(length);
       data->untag()->RecomputeDataField();
       uint8_t* cdata = reinterpret_cast<uint8_t*>(data->untag()->data());
-      d->ReadBytes(cdata, length_in_bytes);
+      d.ReadBytes(cdata, length_in_bytes);
     }
   }
 
@@ -4852,19 +4937,22 @@
     ReadAllocFixedSize(d, TypedDataView::InstanceSize());
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
+    const intptr_t cid = cid_;
     ASSERT(!is_canonical());  // Never canonical.
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      TypedDataViewPtr view = static_cast<TypedDataViewPtr>(d->Ref(id));
-      Deserializer::InitializeHeader(view, cid_, TypedDataView::InstanceSize());
-      ReadFromTo(view);
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      TypedDataViewPtr view = static_cast<TypedDataViewPtr>(d.Ref(id));
+      Deserializer::InitializeHeader(view, cid, TypedDataView::InstanceSize());
+      d.ReadFromTo(view);
     }
   }
 
   void PostLoad(Deserializer* d, const Array& refs, bool primary) {
     ASSERT(primary || !is_canonical());
     auto& view = TypedDataView::Handle(d->zone());
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
       view ^= refs.At(id);
       view.RecomputeDataField();
     }
@@ -4927,19 +5015,21 @@
     ReadAllocFixedSize(d, ExternalTypedData::InstanceSize());
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
-    ASSERT(!is_canonical());  // Never canonical.
-    intptr_t element_size = ExternalTypedData::ElementSizeInBytes(cid_);
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
 
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      ExternalTypedDataPtr data = static_cast<ExternalTypedDataPtr>(d->Ref(id));
-      const intptr_t length = d->ReadUnsigned();
-      Deserializer::InitializeHeader(data, cid_,
+    ASSERT(!is_canonical());  // Never canonical.
+    const intptr_t cid = cid_;
+    intptr_t element_size = ExternalTypedData::ElementSizeInBytes(cid);
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      ExternalTypedDataPtr data = static_cast<ExternalTypedDataPtr>(d.Ref(id));
+      const intptr_t length = d.ReadUnsigned();
+      Deserializer::InitializeHeader(data, cid,
                                      ExternalTypedData::InstanceSize());
       data->untag()->length_ = Smi::New(length);
-      d->Align(ExternalTypedData::kDataSerializationAlignment);
-      data->untag()->data_ = const_cast<uint8_t*>(d->CurrentBufferAddress());
-      d->Advance(length * element_size);
+      d.Align(ExternalTypedData::kDataSerializationAlignment);
+      data->untag()->data_ = const_cast<uint8_t*>(d.AddressOfCurrentPosition());
+      d.Advance(length * element_size);
       // No finalizer / external size 0.
     }
   }
@@ -4995,13 +5085,15 @@
     ReadAllocFixedSize(d, StackTrace::InstanceSize());
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
     ASSERT(!is_canonical());  // Never canonical.
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      StackTracePtr trace = static_cast<StackTracePtr>(d->Ref(id));
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      StackTracePtr trace = static_cast<StackTracePtr>(d.Ref(id));
       Deserializer::InitializeHeader(trace, kStackTraceCid,
                                      StackTrace::InstanceSize());
-      ReadFromTo(trace);
+      d.ReadFromTo(trace);
     }
   }
 };
@@ -5056,16 +5148,18 @@
     ReadAllocFixedSize(d, RegExp::InstanceSize());
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
     ASSERT(!is_canonical());  // Never canonical.
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RegExpPtr regexp = static_cast<RegExpPtr>(d->Ref(id));
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      RegExpPtr regexp = static_cast<RegExpPtr>(d.Ref(id));
       Deserializer::InitializeHeader(regexp, kRegExpCid,
                                      RegExp::InstanceSize());
-      ReadFromTo(regexp);
-      regexp->untag()->num_one_byte_registers_ = d->Read<int32_t>();
-      regexp->untag()->num_two_byte_registers_ = d->Read<int32_t>();
-      regexp->untag()->type_flags_ = d->Read<int8_t>();
+      d.ReadFromTo(regexp);
+      regexp->untag()->num_one_byte_registers_ = d.Read<int32_t>();
+      regexp->untag()->num_two_byte_registers_ = d.Read<int32_t>();
+      regexp->untag()->type_flags_ = d.Read<int8_t>();
     }
   }
 };
@@ -5133,13 +5227,15 @@
     ReadAllocFixedSize(d, WeakProperty::InstanceSize());
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
     ASSERT(!is_canonical());  // Never canonical.
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      WeakPropertyPtr property = static_cast<WeakPropertyPtr>(d->Ref(id));
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      WeakPropertyPtr property = static_cast<WeakPropertyPtr>(d.Ref(id));
       Deserializer::InitializeHeader(property, kWeakPropertyCid,
                                      WeakProperty::InstanceSize());
-      ReadFromTo(property);
+      d.ReadFromTo(property);
       property->untag()->next_seen_by_gc_ = WeakProperty::null();
     }
   }
@@ -5199,12 +5295,16 @@
     ReadAllocFixedSize(d, LinkedHashMap::InstanceSize());
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      LinkedHashMapPtr map = static_cast<LinkedHashMapPtr>(d->Ref(id));
-      Deserializer::InitializeHeader(map, cid_, LinkedHashMap::InstanceSize(),
-                                     primary && is_canonical());
-      ReadFromTo(map);
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
+    const intptr_t cid = cid_;
+    const bool mark_canonical = primary && is_canonical();
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      LinkedHashMapPtr map = static_cast<LinkedHashMapPtr>(d.Ref(id));
+      Deserializer::InitializeHeader(map, cid, LinkedHashMap::InstanceSize(),
+                                     mark_canonical);
+      d.ReadFromTo(map);
     }
   }
 
@@ -5266,12 +5366,16 @@
     ReadAllocFixedSize(d, LinkedHashSet::InstanceSize());
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      LinkedHashSetPtr set = static_cast<LinkedHashSetPtr>(d->Ref(id));
-      Deserializer::InitializeHeader(set, cid_, LinkedHashSet::InstanceSize(),
-                                     primary && is_canonical());
-      ReadFromTo(set);
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
+    const intptr_t cid = cid_;
+    const bool mark_canonical = primary && is_canonical();
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      LinkedHashSetPtr set = static_cast<LinkedHashSetPtr>(d.Ref(id));
+      Deserializer::InitializeHeader(set, cid, LinkedHashSet::InstanceSize(),
+                                     mark_canonical);
+      d.ReadFromTo(set);
     }
   }
 
@@ -5348,17 +5452,21 @@
     stop_index_ = d->next_index();
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      ArrayPtr array = static_cast<ArrayPtr>(d->Ref(id));
-      const intptr_t length = d->ReadUnsigned();
-      Deserializer::InitializeHeader(array, cid_, Array::InstanceSize(length),
-                                     primary && is_canonical());
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
+    const intptr_t cid = cid_;
+    const bool stamp_canonical = primary && is_canonical();
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      ArrayPtr array = static_cast<ArrayPtr>(d.Ref(id));
+      const intptr_t length = d.ReadUnsigned();
+      Deserializer::InitializeHeader(array, cid, Array::InstanceSize(length),
+                                     stamp_canonical);
       array->untag()->type_arguments_ =
-          static_cast<TypeArgumentsPtr>(d->ReadRef());
+          static_cast<TypeArgumentsPtr>(d.ReadRef());
       array->untag()->length_ = CompressedSmiPtr(Smi::New(length));
       for (intptr_t j = 0; j < length; j++) {
-        array->untag()->data()[j] = d->ReadRef();
+        array->untag()->data()[j] = d.ReadRef();
       }
     }
   }
@@ -5471,10 +5579,12 @@
     BuildCanonicalSetFromLayout(d);
   }
 
-  void ReadFill(Deserializer* d, bool primary) {
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      StringPtr str = static_cast<StringPtr>(d->Ref(id));
-      const intptr_t encoded = d->ReadUnsigned();
+  void ReadFill(Deserializer* d_, bool primary) {
+    Deserializer::Local d(d_);
+
+    for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
+      StringPtr str = static_cast<StringPtr>(d.Ref(id));
+      const intptr_t encoded = d.ReadUnsigned();
       intptr_t cid = 0;
       const intptr_t length = DecodeLengthAndCid(encoded, &cid);
       Deserializer::InitializeHeader(str, cid, InstanceSize(length, cid),
@@ -5483,14 +5593,14 @@
       StringHasher hasher;
       if (cid == kOneByteStringCid) {
         for (intptr_t j = 0; j < length; j++) {
-          uint8_t code_unit = d->Read<uint8_t>();
+          uint8_t code_unit = d.Read<uint8_t>();
           static_cast<OneByteStringPtr>(str)->untag()->data()[j] = code_unit;
           hasher.Add(code_unit);
         }
       } else {
         for (intptr_t j = 0; j < length; j++) {
-          uint16_t code_unit = d->Read<uint8_t>();
-          code_unit = code_unit | (d->Read<uint8_t>() << 8);
+          uint16_t code_unit = d.Read<uint8_t>();
+          code_unit = code_unit | (d.Read<uint8_t>() << 8);
           static_cast<TwoByteStringPtr>(str)->untag()->data()[j] = code_unit;
           hasher.Add(code_unit);
         }
@@ -5577,6 +5687,8 @@
                      "LocalVarDescriptors", "<empty>");
     s->AddBaseObject(Object::empty_exception_handlers().ptr(),
                      "ExceptionHandlers", "<empty>");
+    s->AddBaseObject(Object::empty_async_exception_handlers().ptr(),
+                     "ExceptionHandlers", "<empty async>");
 
     for (intptr_t i = 0; i < ArgumentsDescriptor::kCachedDescriptorCount; i++) {
       s->AddBaseObject(ArgumentsDescriptor::cached_args_descriptors_[i],
@@ -5688,6 +5800,7 @@
     d->AddBaseObject(Object::empty_descriptors().ptr());
     d->AddBaseObject(Object::empty_var_descriptors().ptr());
     d->AddBaseObject(Object::empty_exception_handlers().ptr());
+    d->AddBaseObject(Object::empty_async_exception_handlers().ptr());
 
     for (intptr_t i = 0; i < ArgumentsDescriptor::kCachedDescriptorCount; i++) {
       d->AddBaseObject(ArgumentsDescriptor::cached_args_descriptors_[i]);
@@ -8018,8 +8131,8 @@
 }
 
 void Deserializer::ReadInstructions(CodePtr code, bool deferred) {
-  if (deferred) {
 #if defined(DART_PRECOMPILED_RUNTIME)
+  if (deferred) {
     uword entry_point = StubCode::NotLoaded().EntryPoint();
     code->untag()->entry_point_ = entry_point;
     code->untag()->unchecked_entry_point_ = entry_point;
@@ -8027,12 +8140,8 @@
     code->untag()->monomorphic_unchecked_entry_point_ = entry_point;
     code->untag()->instructions_length_ = 0;
     return;
-#else
-    UNREACHABLE();
-#endif
   }
 
-#if defined(DART_PRECOMPILED_RUNTIME)
   const uword payload_start = instructions_table_.EntryPointAt(
       instructions_table_.rodata()->first_entry_with_code +
       instructions_index_);
@@ -8059,15 +8168,15 @@
   code->untag()->monomorphic_unchecked_entry_point_ =
       monomorphic_entry_point + unchecked_offset;
 #else
+  ASSERT(!deferred);
   InstructionsPtr instr = image_reader_->GetInstructionsAt(Read<uint32_t>());
   uint32_t unchecked_offset = ReadUnsigned();
   code->untag()->instructions_ = instr;
   code->untag()->unchecked_offset_ = unchecked_offset;
-  if (kind() == Snapshot::kFullJIT) {
-    const uint32_t active_offset = Read<uint32_t>();
-    instr = image_reader_->GetInstructionsAt(active_offset);
-    unchecked_offset = ReadUnsigned();
-  }
+  ASSERT(kind() == Snapshot::kFullJIT);
+  const uint32_t active_offset = Read<uint32_t>();
+  instr = image_reader_->GetInstructionsAt(active_offset);
+  unchecked_offset = ReadUnsigned();
   code->untag()->active_instructions_ = instr;
   Code::InitializeCachedEntryPointsFrom(code, instr, unchecked_offset);
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
@@ -8129,7 +8238,7 @@
 };
 
 void Deserializer::Deserialize(DeserializationRoots* roots) {
-  const void* clustered_start = CurrentBufferAddress();
+  const void* clustered_start = AddressOfCurrentPosition();
 
   Array& refs = Array::Handle(zone_);
   num_base_objects_ = ReadUnsigned();
@@ -8250,8 +8359,9 @@
   }
 
   if (isolate_group->snapshot_is_dontneed_safe()) {
-    size_t clustered_length = reinterpret_cast<uword>(CurrentBufferAddress()) -
-                              reinterpret_cast<uword>(clustered_start);
+    size_t clustered_length =
+        reinterpret_cast<uword>(AddressOfCurrentPosition()) -
+        reinterpret_cast<uword>(clustered_start);
     VirtualMemory::DontNeed(const_cast<void*>(clustered_start),
                             clustered_length);
   }
diff --git a/runtime/vm/app_snapshot.h b/runtime/vm/app_snapshot.h
index 118ca9c..0356e09 100644
--- a/runtime/vm/app_snapshot.h
+++ b/runtime/vm/app_snapshot.h
@@ -646,7 +646,7 @@
 
   intptr_t position() const { return stream_.Position(); }
   void set_position(intptr_t p) { stream_.SetPosition(p); }
-  const uint8_t* CurrentBufferAddress() const {
+  const uint8_t* AddressOfCurrentPosition() const {
     return stream_.AddressOfCurrentPosition();
   }
 
@@ -679,23 +679,6 @@
 
   ObjectPtr ReadRef() { return Ref(ReadRefId()); }
 
-  template <typename T, typename... P>
-  void ReadFromTo(T obj, P&&... params) {
-    auto* from = obj->untag()->from();
-    auto* to_snapshot = obj->untag()->to_snapshot(kind(), params...);
-    auto* to = obj->untag()->to(params...);
-    for (auto* p = from; p <= to_snapshot; p++) {
-      *p = ReadRef();
-    }
-    // This is necessary because, unlike Object::Allocate, the clustered
-    // deserializer allocates object without null-initializing them. Instead,
-    // each deserialization cluster is responsible for initializing every field,
-    // ensuring that every field is written to exactly once.
-    for (auto* p = to_snapshot + 1; p <= to; p++) {
-      *p = Object::null();
-    }
-  }
-
   TokenPosition ReadTokenPosition() {
     return TokenPosition::Deserialize(Read<int32_t>());
   }
@@ -726,7 +709,13 @@
   intptr_t next_index() const { return next_ref_index_; }
   Heap* heap() const { return heap_; }
   Zone* zone() const { return zone_; }
-  Snapshot::Kind kind() const { return kind_; }
+  Snapshot::Kind kind() const {
+#if defined(DART_PRECOMPILED_RUNTIME)
+    return Snapshot::kFullAOT;
+#else
+    return kind_;
+#endif
+  }
   FieldTable* initial_field_table() const { return initial_field_table_; }
   bool is_non_root_unit() const { return is_non_root_unit_; }
   void set_code_start_index(intptr_t value) { code_start_index_ = value; }
@@ -738,6 +727,74 @@
   }
   intptr_t num_base_objects() const { return num_base_objects_; }
 
+  // This serves to make the snapshot cursor, ref table and null be locals
+  // during ReadFill, which allows the C compiler to see they are not aliased
+  // and can be kept in registers.
+  class Local : public ReadStream {
+   public:
+    explicit Local(Deserializer* d)
+        : ReadStream(d->stream_.buffer_, d->stream_.current_, d->stream_.end_),
+          d_(d),
+          refs_(d->refs_),
+          null_(Object::null()) {
+#if defined(DEBUG)
+      // Can't mix use of Deserializer::Read*.
+      d->stream_.current_ = nullptr;
+#endif
+    }
+    ~Local() {
+      d_->stream_.current_ = current_;
+    }
+
+    ObjectPtr Ref(intptr_t index) const {
+      ASSERT(index > 0);
+      ASSERT(index <= d_->num_objects_);
+      return refs_->untag()->element(index);
+    }
+
+    template <typename T>
+    T Read() {
+      return ReadStream::Raw<sizeof(T), T>::Read(this);
+    }
+    uint64_t ReadUnsigned64() {
+      return ReadUnsigned<uint64_t>();
+    }
+
+    ObjectPtr ReadRef() {
+      return Ref(ReadRefId());
+    }
+    TokenPosition ReadTokenPosition() {
+      return TokenPosition::Deserialize(Read<int32_t>());
+    }
+
+    intptr_t ReadCid() {
+      COMPILE_ASSERT(UntaggedObject::kClassIdTagSize <= 32);
+      return Read<int32_t>();
+    }
+
+    template <typename T, typename... P>
+    void ReadFromTo(T obj, P&&... params) {
+      auto* from = obj->untag()->from();
+      auto* to_snapshot = obj->untag()->to_snapshot(d_->kind(), params...);
+      auto* to = obj->untag()->to(params...);
+      for (auto* p = from; p <= to_snapshot; p++) {
+        *p = ReadRef();
+      }
+      // This is necessary because, unlike Object::Allocate, the clustered
+      // deserializer allocates object without null-initializing them. Instead,
+      // each deserialization cluster is responsible for initializing every
+      // field, ensuring that every field is written to exactly once.
+      for (auto* p = to_snapshot + 1; p <= to; p++) {
+        *p = null_;
+      }
+    }
+
+   private:
+    Deserializer* const d_;
+    const ArrayPtr refs_;
+    const ObjectPtr null_;
+  };
+
  private:
   Heap* heap_;
   Zone* zone_;
@@ -758,8 +815,6 @@
   InstructionsTable& instructions_table_;
 };
 
-#define ReadFromTo(obj, ...) d->ReadFromTo(obj, ##__VA_ARGS__);
-
 class FullSnapshotWriter {
  public:
   static const intptr_t kInitialSize = 64 * KB;
diff --git a/runtime/vm/class_id.h b/runtime/vm/class_id.h
index 7d764c7..311fd12 100644
--- a/runtime/vm/class_id.h
+++ b/runtime/vm/class_id.h
@@ -95,6 +95,7 @@
   V(ReceivePort)                                                               \
   V(SendPort)                                                                  \
   V(StackTrace)                                                                \
+  V(SuspendState)                                                              \
   V(RegExp)                                                                    \
   V(WeakProperty)                                                              \
   V(WeakReference)                                                             \
diff --git a/runtime/vm/code_descriptors.cc b/runtime/vm/code_descriptors.cc
index 87625f3..9d13919 100644
--- a/runtime/vm/code_descriptors.cc
+++ b/runtime/vm/code_descriptors.cc
@@ -125,10 +125,12 @@
     uword entry_point) const {
   intptr_t num_handlers = Length();
   if (num_handlers == 0) {
-    return Object::empty_exception_handlers().ptr();
+    return has_async_handler_ ? Object::empty_async_exception_handlers().ptr()
+                              : Object::empty_exception_handlers().ptr();
   }
   const ExceptionHandlers& handlers =
       ExceptionHandlers::Handle(ExceptionHandlers::New(num_handlers));
+  handlers.set_has_async_handler(has_async_handler_);
   for (intptr_t i = 0; i < num_handlers; i++) {
     // Assert that every element in the array has been initialized.
     if (list_[i].handler_types == NULL) {
diff --git a/runtime/vm/code_descriptors.h b/runtime/vm/code_descriptors.h
index bd0d358..9251781 100644
--- a/runtime/vm/code_descriptors.h
+++ b/runtime/vm/code_descriptors.h
@@ -76,7 +76,8 @@
     bool needs_stacktrace;
   };
 
-  ExceptionHandlerList() : list_() {}
+  explicit ExceptionHandlerList(const Function& function)
+      : list_(), has_async_handler_(function.IsCompactAsyncFunction()) {}
 
   intptr_t Length() const { return list_.length(); }
 
@@ -137,6 +138,7 @@
 
  private:
   GrowableArray<struct HandlerDesc> list_;
+  const bool has_async_handler_;
   DISALLOW_COPY_AND_ASSIGN(ExceptionHandlerList);
 };
 
diff --git a/runtime/vm/compiler/aot/dispatch_table_generator.cc b/runtime/vm/compiler/aot/dispatch_table_generator.cc
index 42a8d8a..bb5faac 100644
--- a/runtime/vm/compiler/aot/dispatch_table_generator.cc
+++ b/runtime/vm/compiler/aot/dispatch_table_generator.cc
@@ -453,7 +453,7 @@
           if (function.IsDynamicFunction(/*allow_abstract=*/false)) {
             const bool on_null_interface = klass.IsObjectClass();
             const bool requires_args_descriptor =
-                function.IsGeneric() || function.HasOptionalParameters();
+                function.PrologueNeedsArgumentsDescriptor();
             // Get assigned selector ID for this function.
             const int32_t sid = selector_map_.SelectorId(function);
             if (sid == SelectorMap::kInvalidSelectorId) {
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index 36fd740..b58ff26 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -2266,10 +2266,6 @@
         }
       }
       if (retained_functions.Length() > 0) {
-        // Last entry must be null.
-        retained_functions.Add(Object::null_object());
-        retained_functions.Add(Object::null_object());
-        retained_functions.Add(Object::null_object());
         functions = Array::MakeFixedLength(retained_functions);
       } else {
         functions = Object::empty_array().ptr();
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm.cc b/runtime/vm/compiler/asm_intrinsifier_arm.cc
index 3b6b707..c45f72f 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm.cc
@@ -1592,8 +1592,7 @@
   __ cmp(length_reg, Operand(0));
   __ b(failure, LT);
 
-  NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R0, cid));
-  NOT_IN_PRODUCT(__ MaybeTraceAllocation(R0, failure));
+  NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, failure, R0));
   __ mov(R8, Operand(length_reg));  // Save the length register.
   if (cid == kOneByteStringCid) {
     __ SmiUntag(length_reg);
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm64.cc b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
index eb0477e..7d0fb15 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
@@ -1819,7 +1819,7 @@
   // negative length: call to runtime to produce error.
   __ tbnz(failure, length_reg, compiler::target::kBitsPerWord - 1);
 
-  NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, R0, failure));
+  NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, failure, R0));
   __ mov(R6, length_reg);  // Save the length register.
   if (cid == kOneByteStringCid) {
     // Untag length.
diff --git a/runtime/vm/compiler/asm_intrinsifier_ia32.cc b/runtime/vm/compiler/asm_intrinsifier_ia32.cc
index 815a2e0..fce0555 100644
--- a/runtime/vm/compiler/asm_intrinsifier_ia32.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_ia32.cc
@@ -1626,8 +1626,7 @@
   __ cmpl(length_reg, Immediate(0));
   __ j(LESS, failure);
 
-  NOT_IN_PRODUCT(
-      __ MaybeTraceAllocation(cid, EAX, failure, Assembler::kFarJump));
+  NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, failure, EAX));
   if (length_reg != EDI) {
     __ movl(EDI, length_reg);
   }
diff --git a/runtime/vm/compiler/asm_intrinsifier_riscv.cc b/runtime/vm/compiler/asm_intrinsifier_riscv.cc
index 39cfdf9..eefc6ef 100644
--- a/runtime/vm/compiler/asm_intrinsifier_riscv.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_riscv.cc
@@ -1510,7 +1510,7 @@
   // negative length: call to runtime to produce error.
   __ bltz(length_reg, failure);
 
-  NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, TMP, failure));
+  NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, failure, TMP));
   __ mv(T0, length_reg);  // Save the length register.
   if (cid == kOneByteStringCid) {
     // Untag length.
diff --git a/runtime/vm/compiler/asm_intrinsifier_x64.cc b/runtime/vm/compiler/asm_intrinsifier_x64.cc
index 4abdfe1..bbdc515 100644
--- a/runtime/vm/compiler/asm_intrinsifier_x64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_x64.cc
@@ -1702,7 +1702,7 @@
   __ cmpq(length_reg, Immediate(0));
   __ j(LESS, failure);
 
-  NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, failure, Assembler::kFarJump));
+  NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, failure));
   if (length_reg != RDI) {
     __ movq(RDI, length_reg);
   }
diff --git a/runtime/vm/compiler/assembler/assembler_arm.cc b/runtime/vm/compiler/assembler/assembler_arm.cc
index bca236c..c56be1c 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm.cc
@@ -3161,6 +3161,19 @@
   }
 }
 
+void Assembler::OrImmediate(Register rd,
+                            Register rs,
+                            int32_t imm,
+                            Condition cond) {
+  Operand o;
+  if (Operand::CanHold(imm, &o)) {
+    orr(rd, rs, Operand(o), cond);
+  } else {
+    LoadImmediate(TMP, imm, cond);
+    orr(rd, rs, Operand(TMP), cond);
+  }
+}
+
 void Assembler::CompareImmediate(Register rn, int32_t value, Condition cond) {
   Operand o;
   if (Operand::CanHold(value, &o)) {
@@ -3516,6 +3529,14 @@
   b(trace, NE);
 }
 
+void Assembler::MaybeTraceAllocation(intptr_t cid,
+                                     Label* trace,
+                                     Register temp_reg,
+                                     JumpDistance distance) {
+  LoadAllocationStatsAddress(temp_reg, cid);
+  MaybeTraceAllocation(temp_reg, trace);
+}
+
 void Assembler::LoadAllocationStatsAddress(Register dest, intptr_t cid) {
   ASSERT(dest != kNoRegister);
   ASSERT(dest != TMP);
@@ -3623,6 +3644,21 @@
   }
 }
 
+void Assembler::CopyMemoryWords(Register src,
+                                Register dst,
+                                Register size,
+                                Register temp) {
+  Label loop, done;
+  __ cmp(size, Operand(0));
+  __ b(&done, EQUAL);
+  __ Bind(&loop);
+  __ ldr(temp, Address(src, target::kWordSize, Address::PostIndex));
+  __ str(temp, Address(dst, target::kWordSize, Address::PostIndex));
+  __ subs(size, size, Operand(target::kWordSize));
+  __ b(&loop, NOT_ZERO);
+  __ Bind(&done);
+}
+
 void Assembler::GenerateUnRelocatedPcRelativeCall(Condition cond,
                                                   intptr_t offset_into_target) {
   // Emit "blr.cond <offset>".
diff --git a/runtime/vm/compiler/assembler/assembler_arm.h b/runtime/vm/compiler/assembler/assembler_arm.h
index 2f2f1fb..f7f856e 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.h
+++ b/runtime/vm/compiler/assembler/assembler_arm.h
@@ -385,6 +385,8 @@
   void Bind(Label* label);
   // Unconditional jump to a given label. [distance] is ignored on ARM.
   void Jump(Label* label, JumpDistance distance = kFarJump) { b(label); }
+  // Unconditional jump to a given address in register.
+  void Jump(Register target) { bx(target); }
   // Unconditional jump to a given address in memory.
   void Jump(const Address& address) { Branch(address); }
 
@@ -415,9 +417,6 @@
     // We don't run TSAN bots on 32 bit.
   }
 
-  void CompareWithFieldValue(Register value, FieldAddress address) {
-    CompareWithMemoryValue(value, address);
-  }
   void CompareWithCompressedFieldFromOffset(Register value,
                                             Register base,
                                             int32_t offset) {
@@ -818,6 +817,9 @@
                             Register rn,
                             int32_t value,
                             Condition cond = AL);
+  void AddRegisters(Register dest, Register src) {
+    add(dest, dest, Operand(src));
+  }
   void SubImmediate(Register rd,
                     Register rn,
                     int32_t value,
@@ -826,7 +828,24 @@
                             Register rn,
                             int32_t value,
                             Condition cond = AL);
+  void SubRegisters(Register dest, Register src) {
+    sub(dest, dest, Operand(src));
+  }
   void AndImmediate(Register rd, Register rs, int32_t imm, Condition cond = AL);
+  void AndImmediate(Register rd, int32_t imm, Condition cond = AL) {
+    AndImmediate(rd, rd, imm, cond);
+  }
+  void OrImmediate(Register rd, Register rs, int32_t imm, Condition cond = AL);
+  void OrImmediate(Register rd, int32_t imm, Condition cond = AL) {
+    OrImmediate(rd, rd, imm, cond);
+  }
+  void LslImmediate(Register rd, Register rn, int32_t shift) {
+    ASSERT((shift >= 0) && (shift < kBitsPerInt32));
+    Lsl(rd, rn, Operand(shift));
+  }
+  void LslImmediate(Register rd, int32_t shift) {
+    LslImmediate(rd, rd, shift);
+  }
 
   // Test rn and immediate. May clobber IP.
   void TestImmediate(Register rn, int32_t imm, Condition cond = AL);
@@ -1051,6 +1070,10 @@
                           Condition cond = AL) {
     StoreToOffset(reg, base, offset - kHeapObjectTag, type, cond);
   }
+  void StoreZero(const Address& address, Register temp) {
+    mov(temp, Operand(0));
+    str(temp, address);
+  }
   void LoadSFromOffset(SRegister reg,
                        Register base,
                        int32_t offset,
@@ -1137,6 +1160,14 @@
     cmp(rn, Operand(0));
     b(label, ZERO);
   }
+  void BranchIfBit(Register rn,
+                   intptr_t bit_number,
+                   Condition condition,
+                   Label* label,
+                   JumpDistance distance = kFarJump) {
+    tst(rn, Operand(1 << bit_number));
+    b(label, condition);
+  }
 
   void MoveRegister(Register rd, Register rm, Condition cond) {
     ExtendValue(rd, rm, kFourBytes, cond);
@@ -1368,6 +1399,13 @@
   // which will allocate in the runtime where tracing occurs.
   void MaybeTraceAllocation(Register stats_addr_reg, Label* trace);
 
+  // If allocation tracing for |cid| is enabled, will jump to |trace| label,
+  // which will allocate in the runtime where tracing occurs.
+  void MaybeTraceAllocation(intptr_t cid,
+                            Label* trace,
+                            Register temp_reg,
+                            JumpDistance distance = JumpDistance::kFarJump);
+
   void TryAllocateObject(intptr_t cid,
                          intptr_t instance_size,
                          Label* failure,
@@ -1383,6 +1421,14 @@
                         Register temp1,
                         Register temp2);
 
+  // Copy [size] bytes from [src] address to [dst] address.
+  // [size] should be a multiple of word size.
+  // Clobbers [src], [dst], [size] and [temp] registers.
+  void CopyMemoryWords(Register src,
+                       Register dst,
+                       Register size,
+                       Register temp);
+
   // This emits an PC-relative call of the form "blr.<cond> <offset>".  The
   // offset is not yet known and needs therefore relocation to the right place
   // before the code can be used.
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.cc b/runtime/vm/compiler/assembler/assembler_arm64.cc
index 8f0e2ee..efdeb2d 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64.cc
@@ -1998,8 +1998,9 @@
 
 #ifndef PRODUCT
 void Assembler::MaybeTraceAllocation(intptr_t cid,
+                                     Label* trace,
                                      Register temp_reg,
-                                     Label* trace) {
+                                     JumpDistance distance) {
   ASSERT(cid > 0);
 
   const intptr_t shared_table_offset =
@@ -2034,7 +2035,7 @@
     // If this allocation is traced, program will jump to failure path
     // (i.e. the allocation stub) which will allocate the object and trace the
     // allocation call site.
-    NOT_IN_PRODUCT(MaybeTraceAllocation(cid, temp_reg, failure));
+    NOT_IN_PRODUCT(MaybeTraceAllocation(cid, failure, temp_reg));
     RELEASE_ASSERT((target::Thread::top_offset() + target::kWordSize) ==
                    target::Thread::end_offset());
     ldp(instance_reg, temp_reg,
@@ -2076,7 +2077,7 @@
     // If this allocation is traced, program will jump to failure path
     // (i.e. the allocation stub) which will allocate the object and trace the
     // allocation call site.
-    NOT_IN_PRODUCT(MaybeTraceAllocation(cid, temp1, failure));
+    NOT_IN_PRODUCT(MaybeTraceAllocation(cid, failure, temp1));
     // Potential new object start.
     ldr(instance, Address(THR, target::Thread::top_offset()));
     AddImmediateSetFlags(end_address, instance, instance_size);
@@ -2105,6 +2106,20 @@
   }
 }
 
+void Assembler::CopyMemoryWords(Register src,
+                                Register dst,
+                                Register size,
+                                Register temp) {
+  Label loop, done;
+  __ cbz(&done, size);
+  __ Bind(&loop);
+  __ ldr(temp, Address(src, target::kWordSize, Address::PostIndex));
+  __ str(temp, Address(dst, target::kWordSize, Address::PostIndex));
+  __ subs(size, size, Operand(target::kWordSize));
+  __ b(&loop, NOT_ZERO);
+  __ Bind(&done);
+}
+
 void Assembler::GenerateUnRelocatedPcRelativeCall(intptr_t offset_into_target) {
   // Emit "bl <offset>".
   EmitUnconditionalBranchOp(BL, 0);
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index 4cd2832..980c22c 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -545,6 +545,8 @@
   void Bind(Label* label);
   // Unconditional jump to a given label. [distance] is ignored on ARM.
   void Jump(Label* label, JumpDistance distance = kFarJump) { b(label); }
+  // Unconditional jump to a given address in register.
+  void Jump(Register target) { br(target); }
   // Unconditional jump to a given address in memory. Clobbers TMP.
   void Jump(const Address& address) {
     ldr(TMP, address);
@@ -629,9 +631,6 @@
 #endif
   }
 
-  void CompareWithFieldValue(Register value, FieldAddress address) {
-    CompareWithMemoryValue(value, address);
-  }
   void CompareWithCompressedFieldFromOffset(Register value,
                                             Register base,
                                             int32_t offset) {
@@ -1260,6 +1259,19 @@
                     JumpDistance distance = kFarJump) {
     cbz(label, rn);
   }
+  void BranchIfBit(Register rn,
+                   intptr_t bit_number,
+                   Condition condition,
+                   Label* label,
+                   JumpDistance distance = kFarJump) {
+    if (condition == ZERO) {
+      tbz(label, rn, bit_number);
+    } else if (condition == NOT_ZERO) {
+      tbnz(label, rn, bit_number);
+    } else {
+      UNREACHABLE();
+    }
+  }
 
   void cbz(Label* label, Register rt, OperandSize sz = kEightBytes) {
     EmitCompareAndBranch(CBZ, rt, label, sz);
@@ -1676,13 +1688,16 @@
 
   void LslImmediate(Register rd,
                     Register rn,
-                    int shift,
+                    int32_t shift,
                     OperandSize sz = kEightBytes) {
-    const int reg_size =
+    const int32_t reg_size =
         (sz == kEightBytes) ? kXRegSizeInBits : kWRegSizeInBits;
     ASSERT((shift >= 0) && (shift < reg_size));
     ubfm(rd, rn, (reg_size - shift) % reg_size, reg_size - shift - 1, sz);
   }
+  void LslImmediate(Register rd, int32_t shift, OperandSize sz = kEightBytes) {
+    LslImmediate(rd, rd, shift, sz);
+  }
   void LsrImmediate(Register rd,
                     Register rn,
                     int shift,
@@ -1792,18 +1807,30 @@
                             Register rn,
                             int64_t imm,
                             OperandSize sz = kEightBytes);
+  void AddRegisters(Register dest, Register src) {
+    add(dest, dest, Operand(src));
+  }
   void SubImmediateSetFlags(Register dest,
                             Register rn,
                             int64_t imm,
                             OperandSize sz = kEightBytes);
+  void SubRegisters(Register dest, Register src) {
+    sub(dest, dest, Operand(src));
+  }
   void AndImmediate(Register rd,
                     Register rn,
                     int64_t imm,
                     OperandSize sz = kEightBytes);
+  void AndImmediate(Register rd, int64_t imm) {
+    AndImmediate(rd, rd, imm);
+  }
   void OrImmediate(Register rd,
                    Register rn,
                    int64_t imm,
                    OperandSize sz = kEightBytes);
+  void OrImmediate(Register rd, int64_t imm) {
+    OrImmediate(rd, rd, imm);
+  }
   void XorImmediate(Register rd,
                     Register rn,
                     int64_t imm,
@@ -1884,6 +1911,9 @@
                           OperandSize sz = kEightBytes) {
     StoreToOffset(src, base, offset - kHeapObjectTag, sz);
   }
+  void StoreZero(const Address& address, Register temp = kNoRegister) {
+    str(ZR, address);
+  }
 
   void StoreSToOffset(VRegister src, Register base, int32_t offset);
   void StoreDToOffset(VRegister src, Register base, int32_t offset);
@@ -2123,7 +2153,10 @@
 
   // If allocation tracing for |cid| is enabled, will jump to |trace| label,
   // which will allocate in the runtime where tracing occurs.
-  void MaybeTraceAllocation(intptr_t cid, Register temp_reg, Label* trace);
+  void MaybeTraceAllocation(intptr_t cid,
+                            Label* trace,
+                            Register temp_reg,
+                            JumpDistance distance = JumpDistance::kFarJump);
 
   void TryAllocateObject(intptr_t cid,
                          intptr_t instance_size,
@@ -2140,6 +2173,14 @@
                         Register temp1,
                         Register temp2);
 
+  // Copy [size] bytes from [src] address to [dst] address.
+  // [size] should be a multiple of word size.
+  // Clobbers [src], [dst], [size] and [temp] registers.
+  void CopyMemoryWords(Register src,
+                       Register dst,
+                       Register size,
+                       Register temp);
+
   // This emits an PC-relative call of the form "bl <offset>".  The offset
   // is not yet known and needs therefore relocation to the right place before
   // the code can be used.
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.cc b/runtime/vm/compiler/assembler/assembler_ia32.cc
index 05d3863..e004bb5 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.cc
+++ b/runtime/vm/compiler/assembler/assembler_ia32.cc
@@ -320,7 +320,7 @@
   EmitUint8(0xA5);
 }
 
-void Assembler::rep_movsl() {
+void Assembler::rep_movsd() {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   EmitUint8(0xF3);
   EmitUint8(0xA5);
@@ -1889,6 +1889,18 @@
   }
 }
 
+void Assembler::AddImmediate(Register dest, Register src, int32_t value) {
+  if (dest == src) {
+    AddImmediate(dest, value);
+    return;
+  }
+  if (value == 0) {
+    MoveRegister(dest, src);
+    return;
+  }
+  leal(dest, Address(src, value));
+}
+
 void Assembler::SubImmediate(Register reg, const Immediate& imm) {
   const intptr_t value = imm.value();
   if (value == 0) {
@@ -2598,8 +2610,8 @@
 
 #ifndef PRODUCT
 void Assembler::MaybeTraceAllocation(intptr_t cid,
-                                     Register temp_reg,
                                      Label* trace,
+                                     Register temp_reg,
                                      JumpDistance distance) {
   ASSERT(cid > 0);
   Address state_address(kNoRegister, 0);
@@ -2636,7 +2648,7 @@
     // If this allocation is traced, program will jump to failure path
     // (i.e. the allocation stub) which will allocate the object and trace the
     // allocation call site.
-    NOT_IN_PRODUCT(MaybeTraceAllocation(cid, temp_reg, failure, distance));
+    NOT_IN_PRODUCT(MaybeTraceAllocation(cid, failure, temp_reg, distance));
     movl(instance_reg, Address(THR, target::Thread::top_offset()));
     addl(instance_reg, Immediate(instance_size));
     // instance_reg: potential next object start.
@@ -2669,7 +2681,7 @@
     // If this allocation is traced, program will jump to failure path
     // (i.e. the allocation stub) which will allocate the object and trace the
     // allocation call site.
-    NOT_IN_PRODUCT(MaybeTraceAllocation(cid, temp_reg, failure, distance));
+    NOT_IN_PRODUCT(MaybeTraceAllocation(cid, failure, temp_reg, distance));
     movl(instance, Address(THR, target::Thread::top_offset()));
     movl(end_address, instance);
 
@@ -2696,6 +2708,17 @@
   }
 }
 
+void Assembler::CopyMemoryWords(Register src,
+                                Register dst,
+                                Register size,
+                                Register temp) {
+  RELEASE_ASSERT(src == ESI);
+  RELEASE_ASSERT(dst == EDI);
+  RELEASE_ASSERT(size == ECX);
+  shrl(size, Immediate(target::kWordSizeLog2));
+  rep_movsd();
+}
+
 void Assembler::PushCodeObject() {
   ASSERT(IsNotTemporaryScopedHandle(code_));
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
@@ -2713,6 +2736,10 @@
   }
 }
 
+void Assembler::LeaveDartFrame() {
+  LeaveFrame();
+}
+
 // On entry to a function compiled for OSR, the caller's frame pointer, the
 // stack locals, and any copied parameters are already in place.  The frame
 // pointer is already set up. There may be extra space for spill slots to
@@ -2734,7 +2761,7 @@
 }
 
 void Assembler::LeaveStubFrame() {
-  LeaveFrame();
+  LeaveDartFrame();
 }
 
 void Assembler::EnterCFrame(intptr_t frame_space) {
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.h b/runtime/vm/compiler/assembler/assembler_ia32.h
index 8cee67d..bc35841 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.h
+++ b/runtime/vm/compiler/assembler/assembler_ia32.h
@@ -297,7 +297,7 @@
 
   void rep_movsb();
   void rep_movsw();
-  void rep_movsl();
+  void rep_movsd();
 
   void movss(XmmRegister dst, const Address& src);
   void movss(const Address& dst, XmmRegister src);
@@ -587,6 +587,14 @@
     cmpl(src, Immediate(0));
     j(ZERO, label, distance);
   }
+  void BranchIfBit(Register rn,
+                   intptr_t bit_number,
+                   Condition condition,
+                   Label* label,
+                   JumpDistance distance = kFarJump) {
+    testl(rn, Immediate(1 << bit_number));
+    j(condition, label, distance);
+  }
 
   // Arch-specific LoadFromOffset to choose the right operation for [sz].
   void LoadFromOffset(Register dst,
@@ -645,6 +653,9 @@
                           OperandSize sz = kFourBytes) {
     StoreToOffset(src, FieldAddress(base, offset), sz);
   }
+  void StoreZero(const Address& address, Register temp = kNoRegister) {
+    movl(address, Immediate(0));
+  }
   void LoadFromStack(Register dst, intptr_t depth);
   void StoreToStack(Register src, intptr_t depth);
   void CompareToStack(Register src, intptr_t depth);
@@ -682,6 +693,10 @@
     // We don't run TSAN on 32 bit systems.
   }
 
+  void CompareWithMemoryValue(Register value, Address address) {
+    cmpl(value, address);
+  }
+
   void ExtendValue(Register to, Register from, OperandSize sz) override;
   void PushRegister(Register r);
   void PopRegister(Register r);
@@ -699,7 +714,24 @@
   void AddImmediate(Register reg, int32_t value) {
     AddImmediate(reg, Immediate(value));
   }
+  void AddImmediate(Register dest, Register src, int32_t value);
+  void AddRegisters(Register dest, Register src) {
+    addl(dest, src);
+  }
+
   void SubImmediate(Register reg, const Immediate& imm);
+  void SubRegisters(Register dest, Register src) {
+    subl(dest, src);
+  }
+  void AndImmediate(Register dst, int32_t value) {
+    andl(dst, Immediate(value));
+  }
+  void OrImmediate(Register dst, int32_t value) {
+    orl(dst, Immediate(value));
+  }
+  void LslImmediate(Register dst, int32_t shift) {
+    shll(dst, Immediate(shift));
+  }
 
   void CompareImmediate(Register reg, int32_t immediate) {
     cmpl(reg, Immediate(immediate));
@@ -934,6 +966,10 @@
   void Jump(Label* label, JumpDistance distance = kFarJump) {
     jmp(label, distance);
   }
+  // Unconditional jump to a given address in register.
+  void Jump(Register target) {
+    jmp(target);
+  }
 
   // Moves one word from the memory at [from] to the memory at [to].
   // Needs a temporary register.
@@ -956,6 +992,7 @@
   //   L: <code to adjust saved pc if there is any intrinsification code>
   //   .....
   void EnterDartFrame(intptr_t frame_size);
+  void LeaveDartFrame();
 
   // Set up a Dart frame for a function compiled for on-stack replacement.
   // The frame layout is a normal Dart frame, but the frame is partially set
@@ -1002,9 +1039,9 @@
   // If allocation tracing for |cid| is enabled, will jump to |trace| label,
   // which will allocate in the runtime where tracing occurs.
   void MaybeTraceAllocation(intptr_t cid,
-                            Register temp_reg,
                             Label* trace,
-                            JumpDistance distance);
+                            Register temp_reg,
+                            JumpDistance distance = JumpDistance::kFarJump);
 
   void TryAllocateObject(intptr_t cid,
                          intptr_t instance_size,
@@ -1021,6 +1058,16 @@
                         Register end_address,
                         Register temp);
 
+  // Copy [size] bytes from [src] address to [dst] address.
+  // [size] should be a multiple of word size.
+  // Clobbers [src], [dst], [size] and [temp] registers.
+  // IA32 requires fixed registers for memory copying:
+  // [src] = ESI, [dst] = EDI, [size] = ECX.
+  void CopyMemoryWords(Register src,
+                       Register dst,
+                       Register size,
+                       Register temp = kNoRegister);
+
   // Debugging and bringup support.
   void Breakpoint() override { int3(); }
 
diff --git a/runtime/vm/compiler/assembler/assembler_ia32_test.cc b/runtime/vm/compiler/assembler/assembler_ia32_test.cc
index e89073d..715d5bb 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_ia32_test.cc
@@ -4821,7 +4821,7 @@
   __ movl(ESI, Address(ESP, 4 * target::kWordSize));  // from.
   __ movl(EDI, Address(ESP, 5 * target::kWordSize));  // to.
   __ movl(ECX, Address(ESP, 6 * target::kWordSize));  // count.
-  __ rep_movsl();
+  __ rep_movsd();
   __ popl(ECX);
   __ popl(EDI);
   __ popl(ESI);
diff --git a/runtime/vm/compiler/assembler/assembler_riscv.cc b/runtime/vm/compiler/assembler/assembler_riscv.cc
index cc1c65b..b9bf437 100644
--- a/runtime/vm/compiler/assembler/assembler_riscv.cc
+++ b/runtime/vm/compiler/assembler/assembler_riscv.cc
@@ -2373,10 +2373,9 @@
   UNIMPLEMENTED();
 }
 
-void Assembler::CompareWithMemoryValue(Register value,
-                                       Address address,
-                                       OperandSize sz) {
-  UNIMPLEMENTED();
+void Assembler::CompareWithMemoryValue(Register value, Address address) {
+  lx(TMP2, address);
+  CompareRegisters(value, TMP2);
 }
 
 void Assembler::CompareFunctionTypeNullabilityWith(Register type,
@@ -2648,6 +2647,22 @@
   beqz(rn, label, distance);
 }
 
+void Assembler::BranchIfBit(Register rn,
+                            intptr_t bit_number,
+                            Condition condition,
+                            Label* label,
+                            JumpDistance distance) {
+  ASSERT(rn != TMP2);
+  andi(TMP2, rn, 1 << bit_number);
+  if (condition == ZERO) {
+    beqz(TMP2, label, distance);
+  } else if (condition == NOT_ZERO) {
+    bnez(TMP2, label, distance);
+  } else {
+    UNREACHABLE();
+  }
+}
+
 void Assembler::BranchIfNotSmi(Register reg,
                                Label* label,
                                JumpDistance distance) {
@@ -3923,8 +3938,9 @@
 
 #ifndef PRODUCT
 void Assembler::MaybeTraceAllocation(intptr_t cid,
+                                     Label* trace,
                                      Register temp_reg,
-                                     Label* trace) {
+                                     JumpDistance distance) {
   ASSERT(cid > 0);
 
   const intptr_t shared_table_offset =
@@ -3963,7 +3979,7 @@
     // If this allocation is traced, program will jump to failure path
     // (i.e. the allocation stub) which will allocate the object and trace the
     // allocation call site.
-    NOT_IN_PRODUCT(MaybeTraceAllocation(cid, temp_reg, failure));
+    NOT_IN_PRODUCT(MaybeTraceAllocation(cid, failure, temp_reg));
 
     lx(instance_reg, Address(THR, target::Thread::top_offset()));
     lx(temp_reg, Address(THR, target::Thread::end_offset()));
@@ -4003,7 +4019,7 @@
     // If this allocation is traced, program will jump to failure path
     // (i.e. the allocation stub) which will allocate the object and trace the
     // allocation call site.
-    NOT_IN_PRODUCT(MaybeTraceAllocation(cid, temp1, failure));
+    NOT_IN_PRODUCT(MaybeTraceAllocation(cid, failure, temp1));
     // Potential new object start.
     lx(instance, Address(THR, target::Thread::top_offset()));
     AddImmediate(end_address, instance, instance_size);
@@ -4031,6 +4047,22 @@
   }
 }
 
+void Assembler::CopyMemoryWords(Register src,
+                                Register dst,
+                                Register size,
+                                Register temp) {
+  Label loop, done;
+  beqz(size, &done, kNearJump);
+  Bind(&loop);
+  lx(temp, Address(src));
+  addi(src, src, target::kWordSize);
+  sx(temp, Address(dst));
+  addi(dst, dst, target::kWordSize);
+  subi(size, size, target::kWordSize);
+  bnez(size, &loop, kNearJump);
+  Bind(&done);
+}
+
 void Assembler::GenerateUnRelocatedPcRelativeCall(intptr_t offset_into_target) {
   // JAL only has a +/- 1MB range. AUIPC+JALR has a +/- 2GB range.
   intx_t imm = offset_into_target;
diff --git a/runtime/vm/compiler/assembler/assembler_riscv.h b/runtime/vm/compiler/assembler/assembler_riscv.h
index 985ce81..68ec777 100644
--- a/runtime/vm/compiler/assembler/assembler_riscv.h
+++ b/runtime/vm/compiler/assembler/assembler_riscv.h
@@ -801,6 +801,8 @@
   void Jump(Label* label, JumpDistance distance = kFarJump) {
     j(label, distance);
   }
+  // Unconditional jump to a given address in register.
+  void Jump(Register target) { jr(target); }
   // Unconditional jump to a given address in memory. Clobbers TMP.
   void Jump(const Address& address);
 
@@ -834,16 +836,11 @@
                               Register address,
                               int32_t offset = 0);
 
-  void CompareWithFieldValue(Register value, FieldAddress address) {
-    CompareWithMemoryValue(value, address);
-  }
   void CompareWithCompressedFieldFromOffset(Register value,
                                             Register base,
                                             int32_t offset);
 
-  void CompareWithMemoryValue(Register value,
-                              Address address,
-                              OperandSize sz = kWordBytes);
+  void CompareWithMemoryValue(Register value, Address address);
 
   void CompareFunctionTypeNullabilityWith(Register type, int8_t value) override;
   void CompareTypeNullabilityWith(Register type, int8_t value) override;
@@ -888,6 +885,11 @@
   void BranchIfZero(Register rn,
                     Label* label,
                     JumpDistance distance = kFarJump);
+  void BranchIfBit(Register rn,
+                   intptr_t bit_number,
+                   Condition condition,
+                   Label* label,
+                   JumpDistance distance = kFarJump);
   void SetIf(Condition condition, Register rd);
 
   void SmiUntag(Register reg) { SmiUntag(reg, reg); }
@@ -932,6 +934,12 @@
   void AddImmediate(Register dest, intx_t imm) {
     AddImmediate(dest, dest, imm);
   }
+  void AddRegisters(Register dest, Register src) {
+    add(dest, dest, src);
+  }
+  void SubRegisters(Register dest, Register src) {
+    sub(dest, dest, src);
+  }
 
   // Macros accepting a pp Register argument may attempt to load values from
   // the object pool when possible. Unless you are sure that the untagged object
@@ -946,14 +954,23 @@
                     Register rn,
                     intx_t imm,
                     OperandSize sz = kWordBytes);
+  void AndImmediate(Register rd, intx_t imm) {
+    AndImmediate(rd, rd, imm);
+  }
   void OrImmediate(Register rd,
                    Register rn,
                    intx_t imm,
                    OperandSize sz = kWordBytes);
+  void OrImmediate(Register rd, intx_t imm) {
+    OrImmediate(rd, rd, imm);
+  }
   void XorImmediate(Register rd,
                     Register rn,
                     intx_t imm,
                     OperandSize sz = kWordBytes);
+  void LslImmediate(Register rd, int32_t shift) {
+    slli(rd, rd, shift);
+  }
   void TestImmediate(Register rn, intx_t imm, OperandSize sz = kWordBytes);
   void CompareImmediate(Register rn, intx_t imm, OperandSize sz = kWordBytes);
 
@@ -1016,6 +1033,9 @@
                           OperandSize sz = kWordBytes) {
     StoreToOffset(src, base, offset - kHeapObjectTag, sz);
   }
+  void StoreZero(const Address& address, Register temp = kNoRegister) {
+    sx(ZR, address);
+  }
   void StoreSToOffset(FRegister src, Register base, int32_t offset);
   void StoreDToOffset(FRegister src, Register base, int32_t offset);
   void StoreDFieldToOffset(FRegister src, Register base, int32_t offset) {
@@ -1256,7 +1276,10 @@
 
   // If allocation tracing for |cid| is enabled, will jump to |trace| label,
   // which will allocate in the runtime where tracing occurs.
-  void MaybeTraceAllocation(intptr_t cid, Register temp_reg, Label* trace);
+  void MaybeTraceAllocation(intptr_t cid,
+                            Label* trace,
+                            Register temp_reg,
+                            JumpDistance distance = JumpDistance::kFarJump);
 
   void TryAllocateObject(intptr_t cid,
                          intptr_t instance_size,
@@ -1273,6 +1296,14 @@
                         Register temp1,
                         Register temp2);
 
+  // Copy [size] bytes from [src] address to [dst] address.
+  // [size] should be a multiple of word size.
+  // Clobbers [src], [dst], [size] and [temp] registers.
+  void CopyMemoryWords(Register src,
+                       Register dst,
+                       Register size,
+                       Register temp);
+
   // This emits an PC-relative call of the form "bl <offset>".  The offset
   // is not yet known and needs therefore relocation to the right place before
   // the code can be used.
diff --git a/runtime/vm/compiler/assembler/assembler_x64.cc b/runtime/vm/compiler/assembler/assembler_x64.cc
index 9a65cda..ade5233 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64.cc
@@ -1161,6 +1161,18 @@
   }
 }
 
+void Assembler::AddImmediate(Register dest, Register src, int32_t value) {
+  if (dest == src) {
+    AddImmediate(dest, value);
+    return;
+  }
+  if (value == 0) {
+    MoveRegister(dest, src);
+    return;
+  }
+  leaq(dest, Address(src, value));
+}
+
 void Assembler::AddImmediate(const Address& address, const Immediate& imm) {
   const int64_t value = imm.value();
   if (value == 0) {
@@ -2185,6 +2197,7 @@
 #ifndef PRODUCT
 void Assembler::MaybeTraceAllocation(intptr_t cid,
                                      Label* trace,
+                                     Register temp_reg,
                                      JumpDistance distance) {
   ASSERT(cid > 0);
   const intptr_t shared_table_offset =
@@ -2193,7 +2206,9 @@
       target::SharedClassTable::class_heap_stats_table_offset();
   const intptr_t class_offset = target::ClassTable::ClassOffsetFor(cid);
 
-  Register temp_reg = TMP;
+  if (temp_reg == kNoRegister) {
+    temp_reg = TMP;
+  }
   LoadIsolateGroup(temp_reg);
   movq(temp_reg, Address(temp_reg, shared_table_offset));
   movq(temp_reg, Address(temp_reg, table_offset));
@@ -2219,7 +2234,7 @@
     // If this allocation is traced, program will jump to failure path
     // (i.e. the allocation stub) which will allocate the object and trace the
     // allocation call site.
-    NOT_IN_PRODUCT(MaybeTraceAllocation(cid, failure, distance));
+    NOT_IN_PRODUCT(MaybeTraceAllocation(cid, failure, temp_reg, distance));
     movq(instance_reg, Address(THR, target::Thread::top_offset()));
     addq(instance_reg, Immediate(instance_size));
     // instance_reg: potential next object start.
@@ -2251,7 +2266,7 @@
     // If this allocation is traced, program will jump to failure path
     // (i.e. the allocation stub) which will allocate the object and trace the
     // allocation call site.
-    NOT_IN_PRODUCT(MaybeTraceAllocation(cid, failure, distance));
+    NOT_IN_PRODUCT(MaybeTraceAllocation(cid, failure, temp, distance));
     movq(instance, Address(THR, target::Thread::top_offset()));
     movq(end_address, instance);
 
@@ -2279,6 +2294,17 @@
   }
 }
 
+void Assembler::CopyMemoryWords(Register src,
+                                Register dst,
+                                Register size,
+                                Register temp) {
+  RELEASE_ASSERT(src == RSI);
+  RELEASE_ASSERT(dst == RDI);
+  RELEASE_ASSERT(size == RCX);
+  shrq(size, Immediate(target::kWordSizeLog2));
+  rep_movsq();
+}
+
 void Assembler::GenerateUnRelocatedPcRelativeCall(intptr_t offset_into_target) {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   buffer_.Emit<uint8_t>(0xe8);
diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h
index 395a372..c85db24 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.h
+++ b/runtime/vm/compiler/assembler/assembler_x64.h
@@ -407,7 +407,7 @@
   SIMPLE(lock, 0xF0)
   SIMPLE(rep_movsb, 0xF3, 0xA4)
   SIMPLE(rep_movsw, 0xF3, 0x66, 0xA5)
-  SIMPLE(rep_movsl, 0xF3, 0xA5)
+  SIMPLE(rep_movsd, 0xF3, 0xA5)
   SIMPLE(rep_movsq, 0xF3, 0x48, 0xA5)
 #undef SIMPLE
 // XmmRegister operations with another register or an address.
@@ -583,8 +583,17 @@
                      OperandSize width = kEightBytes);
 
   void AndImmediate(Register dst, const Immediate& imm);
+  void AndImmediate(Register dst, int32_t value) {
+    AndImmediate(dst, Immediate(value));
+  }
   void OrImmediate(Register dst, const Immediate& imm);
+  void OrImmediate(Register dst, int32_t value) {
+    OrImmediate(dst, Immediate(value));
+  }
   void XorImmediate(Register dst, const Immediate& imm);
+  void LslImmediate(Register dst, int32_t shift) {
+    shlq(dst, Immediate(shift));
+  }
 
   void shldq(Register dst, Register src, Register shifter) {
     ASSERT(shifter == RCX);
@@ -715,6 +724,14 @@
     cmpq(src, Immediate(0));
     j(ZERO, label, distance);
   }
+  void BranchIfBit(Register rn,
+                   intptr_t bit_number,
+                   Condition condition,
+                   Label* label,
+                   JumpDistance distance = kFarJump) {
+    testq(rn, Immediate(1 << bit_number));
+    j(condition, label, distance);
+  }
 
   void ExtendValue(Register dst, Register src, OperandSize sz) override;
   void PushRegister(Register r);
@@ -740,11 +757,18 @@
                     OperandSize width = kEightBytes) {
     AddImmediate(reg, Immediate(value), width);
   }
+  void AddRegisters(Register dest, Register src) {
+    addq(dest, src);
+  }
+  void AddImmediate(Register dest, Register src, int32_t value);
   void AddImmediate(const Address& address, const Immediate& imm);
   void SubImmediate(Register reg,
                     const Immediate& imm,
                     OperandSize width = kEightBytes);
   void SubImmediate(const Address& address, const Immediate& imm);
+  void SubRegisters(Register dest, Register src) {
+    subq(dest, src);
+  }
 
   void Drop(intptr_t stack_elements, Register tmp = TMP);
 
@@ -965,6 +989,10 @@
   void Jump(Label* label, JumpDistance distance = kFarJump) {
     jmp(label, distance);
   }
+  // Unconditional jump to a given address in register.
+  void Jump(Register target) {
+    jmp(target);
+  }
   // Unconditional jump to a given address in memory.
   void Jump(const Address& address) { jmp(address); }
 
@@ -1028,6 +1056,9 @@
                           OperandSize sz = kEightBytes) {
     StoreToOffset(src, FieldAddress(base, offset), sz);
   }
+  void StoreZero(const Address& address, Register temp = kNoRegister) {
+    movq(address, Immediate(0));
+  }
   void LoadFromStack(Register dst, intptr_t depth);
   void StoreToStack(Register src, intptr_t depth);
   void CompareToStack(Register src, intptr_t depth);
@@ -1097,7 +1128,7 @@
 #endif
   }
 
-  void CompareWithFieldValue(Register value, FieldAddress address) {
+  void CompareWithMemoryValue(Register value, Address address) {
     cmpq(value, address);
   }
   void CompareWithCompressedFieldFromOffset(Register value,
@@ -1178,7 +1209,10 @@
 
   // If allocation tracing for |cid| is enabled, will jump to |trace| label,
   // which will allocate in the runtime where tracing occurs.
-  void MaybeTraceAllocation(intptr_t cid, Label* trace, JumpDistance distance);
+  void MaybeTraceAllocation(intptr_t cid,
+                            Label* trace,
+                            Register temp_reg = kNoRegister,
+                            JumpDistance distance = JumpDistance::kFarJump);
 
   void TryAllocateObject(intptr_t cid,
                          intptr_t instance_size,
@@ -1195,6 +1229,16 @@
                         Register end_address,
                         Register temp);
 
+  // Copy [size] bytes from [src] address to [dst] address.
+  // [size] should be a multiple of word size.
+  // Clobbers [src], [dst], [size] and [temp] registers.
+  // X64 requires fixed registers for memory copying:
+  // [src] = RSI, [dst] = RDI, [size] = RCX.
+  void CopyMemoryWords(Register src,
+                       Register dst,
+                       Register size,
+                       Register temp = kNoRegister);
+
   // This emits an PC-relative call of the form "callq *[rip+<offset>]".  The
   // offset is not yet known and needs therefore relocation to the right place
   // before the code can be used.
diff --git a/runtime/vm/compiler/assembler/assembler_x64_test.cc b/runtime/vm/compiler/assembler/assembler_x64_test.cc
index 83239a8..57daebc 100644
--- a/runtime/vm/compiler/assembler/assembler_x64_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64_test.cc
@@ -5693,7 +5693,7 @@
   __ movq(RSI, Address(RSP, 2 * target::kWordSize));  // from.
   __ movq(RDI, Address(RSP, 1 * target::kWordSize));  // to.
   __ movq(RCX, Address(RSP, 0 * target::kWordSize));  // count.
-  __ rep_movsl();
+  __ rep_movsd();
   // Remove saved arguments.
   __ popq(RAX);
   __ popq(RAX);
diff --git a/runtime/vm/compiler/backend/compile_type.h b/runtime/vm/compiler/backend/compile_type.h
index 4b6bffd..9e0e619 100644
--- a/runtime/vm/compiler/backend/compile_type.h
+++ b/runtime/vm/compiler/backend/compile_type.h
@@ -259,6 +259,10 @@
   // can be uninstantiated.
   bool CanBeSmi();
 
+  // Returns true if a value of this CompileType can contain a Future
+  // instance.
+  bool CanBeFuture();
+
   bool Specialize(GrowableArray<intptr_t>* class_ids);
 
   void PrintTo(BaseTextBuffer* f) const;
diff --git a/runtime/vm/compiler/backend/constant_propagator.cc b/runtime/vm/compiler/backend/constant_propagator.cc
index d3c855b..63528f15 100644
--- a/runtime/vm/compiler/backend/constant_propagator.cc
+++ b/runtime/vm/compiler/backend/constant_propagator.cc
@@ -1460,6 +1460,10 @@
   SetValue(instr, non_constant_);
 }
 
+void ConstantPropagator::VisitCall1ArgStub(Call1ArgStubInstr* instr) {
+  SetValue(instr, non_constant_);
+}
+
 void ConstantPropagator::VisitLoadThread(LoadThreadInstr* instr) {
   SetValue(instr, non_constant_);
 }
diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc
index 360d454..fd20143 100644
--- a/runtime/vm/compiler/backend/flow_graph.cc
+++ b/runtime/vm/compiler/backend/flow_graph.cc
@@ -39,7 +39,7 @@
       current_ssa_temp_index_(0),
       max_block_id_(max_block_id),
       parsed_function_(parsed_function),
-      num_direct_parameters_(parsed_function.function().HasOptionalParameters()
+      num_direct_parameters_(parsed_function.function().MakesCopyOfParameters()
                                  ? 0
                                  : parsed_function.function().NumParameters()),
       direct_parameters_size_(0),
@@ -54,7 +54,7 @@
       prologue_info_(prologue_info),
       loop_hierarchy_(nullptr),
       loop_invariant_loads_(nullptr),
-      captured_parameters_(new (zone()) BitVector(zone(), variable_count())),
+      captured_parameters_(new(zone()) BitVector(zone(), variable_count())),
       inlining_id_(-1),
       should_print_(false) {
   should_print_ = FlowGraphPrinter::ShouldPrint(parsed_function.function(),
@@ -1076,7 +1076,7 @@
   GrowableArray<BlockEntryInstr*> worklist;
   for (intptr_t var_index = 0; var_index < variable_count(); ++var_index) {
     const bool always_live =
-        !FLAG_prune_dead_locals || (var_index == CurrentContextEnvIndex());
+        !FLAG_prune_dead_locals || IsImmortalVariable(var_index);
     // Add to the worklist each block containing an assignment.
     for (intptr_t block_index = 0; block_index < block_count; ++block_index) {
       if (assigned_vars[block_index]->Contains(var_index)) {
@@ -1378,7 +1378,7 @@
       // TODO(fschneider): Make sure that live_in always contains the
       // CurrentContext variable to avoid the special case here.
       if (FLAG_prune_dead_locals && !live_in->Contains(i) &&
-          (i != CurrentContextEnvIndex())) {
+          !IsImmortalVariable(i)) {
         (*env)[i] = constant_dead();
       }
     }
@@ -1619,10 +1619,6 @@
     return;
   }
 
-  // Current_context_var is never pruned, it is artificially kept alive, so
-  // it should not be checked here.
-  const intptr_t current_context_var_index = CurrentContextEnvIndex();
-
   for (intptr_t i = 0, n = preorder().length(); i < n; ++i) {
     BlockEntryInstr* block_entry = preorder()[i];
     Instruction* last_instruction = block_entry->last_instruction();
@@ -1634,7 +1630,7 @@
       if (successor->phis() != NULL) {
         for (intptr_t j = 0; j < successor->phis()->length(); ++j) {
           PhiInstr* phi = (*successor->phis())[j];
-          if (phi == nullptr && j != current_context_var_index) {
+          if (phi == nullptr && !IsImmortalVariable(j)) {
             // We have no phi node for the this variable.
             // Double check we do not have a different value in our env.
             // If we do, we would have needed a phi-node in the successsor.
diff --git a/runtime/vm/compiler/backend/flow_graph.h b/runtime/vm/compiler/backend/flow_graph.h
index 614d19b..98341177 100644
--- a/runtime/vm/compiler/backend/flow_graph.h
+++ b/runtime/vm/compiler/backend/flow_graph.h
@@ -165,6 +165,12 @@
 
   bool IsIrregexpFunction() const { return function().IsIrregexpFunction(); }
 
+  LocalVariable* SuspendStateVar() const {
+    return parsed_function().suspend_state_var();
+  }
+
+  intptr_t SuspendStateEnvIndex() const { return EnvIndex(SuspendStateVar()); }
+
   LocalVariable* CurrentContextVar() const {
     return parsed_function().current_context_var();
   }
@@ -186,6 +192,14 @@
     return num_direct_parameters_ - variable->index().value();
   }
 
+  // Context and :suspend_state variables are never pruned and
+  // artificially kept alive.
+  bool IsImmortalVariable(intptr_t env_index) const {
+    return (env_index == CurrentContextEnvIndex()) ||
+           (SuspendStateVar() != nullptr &&
+            env_index == SuspendStateEnvIndex());
+  }
+
   static bool NeedsPairLocation(Representation representation) {
     return representation == kUnboxedInt64 &&
            compiler::target::kIntSpillFactor == 2;
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index 6f556e5..04712ef 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -208,7 +208,8 @@
       new (zone()) CompressedStackMapsBuilder(zone());
   pc_descriptors_list_ = new (zone()) DescriptorList(
       zone(), &code_source_map_builder_->inline_id_to_function());
-  exception_handlers_list_ = new (zone()) ExceptionHandlerList();
+  exception_handlers_list_ =
+      new (zone()) ExceptionHandlerList(parsed_function().function());
 #if defined(DART_PRECOMPILER)
   catch_entry_moves_maps_builder_ = new (zone()) CatchEntryMovesMapBuilder();
 #endif
@@ -1220,7 +1221,7 @@
   // to spill slots. The deoptimization environment does not track them.
   const Function& function = parsed_function().function();
   const intptr_t incoming_arg_count =
-      function.HasOptionalParameters() ? 0 : function.num_fixed_parameters();
+      function.MakesCopyOfParameters() ? 0 : function.num_fixed_parameters();
   DeoptInfoBuilder builder(zone(), incoming_arg_count, assembler);
 
   intptr_t deopt_info_table_size = DeoptTable::SizeFor(deopt_infos_.length());
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.h b/runtime/vm/compiler/backend/flow_graph_compiler.h
index f533e32..8860c23 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.h
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.h
@@ -814,6 +814,7 @@
   void RecordCatchEntryMoves(Environment* env);
 
   void EmitCallToStub(const Code& stub);
+  void EmitJumpToStub(const Code& stub);
   void EmitTailCallToStub(const Code& stub);
 
   // Emits the following metadata for the current PC:
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
index 1d5dd66..7b14f31 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
@@ -373,6 +373,15 @@
       Register value_reg = slot_index == args_desc_slot ? ARGS_DESC_REG : R0;
       __ StoreToOffset(value_reg, FP, slot_index * compiler::target::kWordSize);
     }
+  } else if (parsed_function().suspend_state_var() != nullptr) {
+    // Initialize synthetic :suspend_state variable early
+    // as it may be accessed by GC and exception handling before
+    // InitAsync stub is called.
+    const intptr_t slot_index =
+        compiler::target::frame_layout.FrameSlotForVariable(
+            parsed_function().suspend_state_var());
+    __ LoadObject(R0, Object::null_object());
+    __ StoreToOffset(R0, FP, slot_index * compiler::target::kWordSize);
   }
 
   EndCodeSourceRange(PrologueSource());
@@ -389,10 +398,25 @@
   }
 }
 
+void FlowGraphCompiler::EmitJumpToStub(const Code& stub) {
+  ASSERT(!stub.IsNull());
+  if (CanPcRelativeCall(stub)) {
+    __ GenerateUnRelocatedPcRelativeTailCall();
+    AddPcRelativeTailCallStubTarget(stub);
+  } else {
+    __ LoadObject(CODE_REG, stub);
+    __ ldr(PC, compiler::FieldAddress(
+                   CODE_REG, compiler::target::Code::entry_point_offset()));
+    AddStubCallTarget(stub);
+  }
+}
+
 void FlowGraphCompiler::EmitTailCallToStub(const Code& stub) {
   ASSERT(!stub.IsNull());
   if (CanPcRelativeCall(stub)) {
-    __ LeaveDartFrame();
+    if (flow_graph().graph_entry()->NeedsFrame()) {
+      __ LeaveDartFrame();
+    }
     __ GenerateUnRelocatedPcRelativeTailCall();
     AddPcRelativeTailCallStubTarget(stub);
 #if defined(DEBUG)
@@ -400,7 +424,9 @@
 #endif
   } else {
     __ LoadObject(CODE_REG, stub);
-    __ LeaveDartFrame();
+    if (flow_graph().graph_entry()->NeedsFrame()) {
+      __ LeaveDartFrame();
+    }
     __ ldr(PC, compiler::FieldAddress(
                    CODE_REG, compiler::target::Code::entry_point_offset()));
     AddStubCallTarget(stub);
@@ -645,7 +671,7 @@
     Code::EntryKind entry_kind) {
   ASSERT(CanCallDart());
   ASSERT(!function.IsClosureFunction());
-  if (function.HasOptionalParameters() || function.IsGeneric()) {
+  if (function.PrologueNeedsArgumentsDescriptor()) {
     __ LoadObject(R4, arguments_descriptor);
   } else {
     if (!FLAG_precompiled_mode) {
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
index 1ccb222..67fed8a 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
@@ -363,6 +363,14 @@
           slot_index == args_desc_slot ? ARGS_DESC_REG : NULL_REG;
       __ StoreToOffset(value_reg, FP, slot_index * kWordSize);
     }
+  } else if (parsed_function().suspend_state_var() != nullptr) {
+    // Initialize synthetic :suspend_state variable early
+    // as it may be accessed by GC and exception handling before
+    // InitAsync stub is called.
+    const intptr_t slot_index =
+        compiler::target::frame_layout.FrameSlotForVariable(
+            parsed_function().suspend_state_var());
+    __ StoreToOffset(NULL_REG, FP, slot_index * kWordSize);
   }
 
   EndCodeSourceRange(PrologueSource());
@@ -379,10 +387,26 @@
   }
 }
 
+void FlowGraphCompiler::EmitJumpToStub(const Code& stub) {
+  ASSERT(!stub.IsNull());
+  if (CanPcRelativeCall(stub)) {
+    __ GenerateUnRelocatedPcRelativeTailCall();
+    AddPcRelativeTailCallStubTarget(stub);
+  } else {
+    __ LoadObject(CODE_REG, stub);
+    __ ldr(TMP, compiler::FieldAddress(
+                    CODE_REG, compiler::target::Code::entry_point_offset()));
+    __ br(TMP);
+    AddStubCallTarget(stub);
+  }
+}
+
 void FlowGraphCompiler::EmitTailCallToStub(const Code& stub) {
   ASSERT(!stub.IsNull());
   if (CanPcRelativeCall(stub)) {
-    __ LeaveDartFrame();
+    if (flow_graph().graph_entry()->NeedsFrame()) {
+      __ LeaveDartFrame();
+    }
     __ GenerateUnRelocatedPcRelativeTailCall();
     AddPcRelativeTailCallStubTarget(stub);
 #if defined(DEBUG)
@@ -390,7 +414,9 @@
 #endif
   } else {
     __ LoadObject(CODE_REG, stub);
-    __ LeaveDartFrame();
+    if (flow_graph().graph_entry()->NeedsFrame()) {
+      __ LeaveDartFrame();
+    }
     __ ldr(TMP, compiler::FieldAddress(
                     CODE_REG, compiler::target::Code::entry_point_offset()));
     __ br(TMP);
@@ -646,7 +672,7 @@
     Code::EntryKind entry_kind) {
   ASSERT(CanCallDart());
   ASSERT(!function.IsClosureFunction());
-  if (function.HasOptionalParameters() || function.IsGeneric()) {
+  if (function.PrologueNeedsArgumentsDescriptor()) {
     __ LoadObject(R4, arguments_descriptor);
   } else {
     if (!FLAG_precompiled_mode) {
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
index 9ed25de..c23ff8a 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
@@ -450,6 +450,15 @@
       Register value_reg = slot_index == args_desc_slot ? ARGS_DESC_REG : EAX;
       __ movl(compiler::Address(EBP, slot_index * kWordSize), value_reg);
     }
+  } else if (parsed_function().suspend_state_var() != nullptr) {
+    // Initialize synthetic :suspend_state variable early
+    // as it may be accessed by GC and exception handling before
+    // InitAsync stub is called.
+    const intptr_t slot_index =
+        compiler::target::frame_layout.FrameSlotForVariable(
+            parsed_function().suspend_state_var());
+    __ LoadObject(EAX, Object::null_object());
+    __ movl(compiler::Address(EBP, slot_index * kWordSize), EAX);
   }
 
   EndCodeSourceRange(PrologueSource());
@@ -464,6 +473,14 @@
   AddStubCallTarget(stub);
 }
 
+void FlowGraphCompiler::EmitJumpToStub(const Code& stub) {
+  ASSERT(!stub.IsNull());
+  __ LoadObject(CODE_REG, stub);
+  __ jmp(compiler::FieldAddress(CODE_REG,
+                                compiler::target::Code::entry_point_offset()));
+  AddStubCallTarget(stub);
+}
+
 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
                                          const InstructionSource& source,
                                          const Code& stub,
@@ -625,7 +642,7 @@
     LocationSummary* locs,
     Code::EntryKind entry_kind) {
   ASSERT(CanCallDart());
-  if (function.HasOptionalParameters() || function.IsGeneric()) {
+  if (function.PrologueNeedsArgumentsDescriptor()) {
     __ LoadObject(EDX, arguments_descriptor);
   } else {
     __ xorl(EDX, EDX);  // GC safe smi zero because of stub.
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_riscv.cc b/runtime/vm/compiler/backend/flow_graph_compiler_riscv.cc
index 46a6ba5..2c40fdc 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_riscv.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_riscv.cc
@@ -357,6 +357,14 @@
       __ StoreToOffset(value_reg, SP,
                        (slot_index + fp_to_sp_delta) * kWordSize);
     }
+  } else if (parsed_function().suspend_state_var() != nullptr) {
+    // Initialize synthetic :suspend_state variable early
+    // as it may be accessed by GC and exception handling before
+    // InitAsync stub is called.
+    const intptr_t slot_index =
+        compiler::target::frame_layout.FrameSlotForVariable(
+            parsed_function().suspend_state_var());
+    __ StoreToOffset(NULL_REG, FP, slot_index * kWordSize);
   }
 
   EndCodeSourceRange(PrologueSource());
@@ -373,10 +381,26 @@
   }
 }
 
+void FlowGraphCompiler::EmitJumpToStub(const Code& stub) {
+  ASSERT(!stub.IsNull());
+  if (CanPcRelativeCall(stub)) {
+    __ GenerateUnRelocatedPcRelativeTailCall();
+    AddPcRelativeTailCallStubTarget(stub);
+  } else {
+    __ LoadObject(CODE_REG, stub);
+    __ lx(TMP, compiler::FieldAddress(
+                   CODE_REG, compiler::target::Code::entry_point_offset()));
+    __ jr(TMP);
+    AddStubCallTarget(stub);
+  }
+}
+
 void FlowGraphCompiler::EmitTailCallToStub(const Code& stub) {
   ASSERT(!stub.IsNull());
   if (CanPcRelativeCall(stub)) {
-    __ LeaveDartFrame();
+    if (flow_graph().graph_entry()->NeedsFrame()) {
+      __ LeaveDartFrame();
+    }
     __ GenerateUnRelocatedPcRelativeTailCall();
     AddPcRelativeTailCallStubTarget(stub);
 #if defined(DEBUG)
@@ -384,7 +408,9 @@
 #endif
   } else {
     __ LoadObject(CODE_REG, stub);
-    __ LeaveDartFrame();
+    if (flow_graph().graph_entry()->NeedsFrame()) {
+      __ LeaveDartFrame();
+    }
     __ lx(TMP, compiler::FieldAddress(
                    CODE_REG, compiler::target::Code::entry_point_offset()));
     __ jr(TMP);
@@ -616,7 +642,7 @@
     Code::EntryKind entry_kind) {
   ASSERT(CanCallDart());
   ASSERT(!function.IsClosureFunction());
-  if (function.HasOptionalParameters() || function.IsGeneric()) {
+  if (function.PrologueNeedsArgumentsDescriptor()) {
     __ LoadObject(ARGS_DESC_REG, arguments_descriptor);
   } else {
     if (!FLAG_precompiled_mode) {
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
index 5ef22a0..e6c3b1e 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
@@ -369,6 +369,15 @@
       Register value_reg = slot_index == args_desc_slot ? ARGS_DESC_REG : RAX;
       __ movq(compiler::Address(RBP, slot_index * kWordSize), value_reg);
     }
+  } else if (parsed_function().suspend_state_var() != nullptr) {
+    // Initialize synthetic :suspend_state variable early
+    // as it may be accessed by GC and exception handling before
+    // InitAsync stub is called.
+    const intptr_t slot_index =
+        compiler::target::frame_layout.FrameSlotForVariable(
+            parsed_function().suspend_state_var());
+    __ LoadObject(RAX, Object::null_object());
+    __ movq(compiler::Address(RBP, slot_index * kWordSize), RAX);
   }
 
   EndCodeSourceRange(PrologueSource());
@@ -385,10 +394,25 @@
   }
 }
 
+void FlowGraphCompiler::EmitJumpToStub(const Code& stub) {
+  ASSERT(!stub.IsNull());
+  if (CanPcRelativeCall(stub)) {
+    __ GenerateUnRelocatedPcRelativeTailCall();
+    AddPcRelativeTailCallStubTarget(stub);
+  } else {
+    __ LoadObject(CODE_REG, stub);
+    __ jmp(compiler::FieldAddress(
+        CODE_REG, compiler::target::Code::entry_point_offset()));
+    AddStubCallTarget(stub);
+  }
+}
+
 void FlowGraphCompiler::EmitTailCallToStub(const Code& stub) {
   ASSERT(!stub.IsNull());
   if (CanPcRelativeCall(stub)) {
-    __ LeaveDartFrame();
+    if (flow_graph().graph_entry()->NeedsFrame()) {
+      __ LeaveDartFrame();
+    }
     __ GenerateUnRelocatedPcRelativeTailCall();
     AddPcRelativeTailCallStubTarget(stub);
 #if defined(DEBUG)
@@ -396,7 +420,9 @@
 #endif
   } else {
     __ LoadObject(CODE_REG, stub);
-    __ LeaveDartFrame();
+    if (flow_graph().graph_entry()->NeedsFrame()) {
+      __ LeaveDartFrame();
+    }
     __ jmp(compiler::FieldAddress(
         CODE_REG, compiler::target::Code::entry_point_offset()));
     AddStubCallTarget(stub);
@@ -629,7 +655,7 @@
     Code::EntryKind entry_kind) {
   ASSERT(CanCallDart());
   ASSERT(!function.IsClosureFunction());
-  if (function.HasOptionalParameters() || function.IsGeneric()) {
+  if (function.PrologueNeedsArgumentsDescriptor()) {
     __ LoadObject(R10, arguments_descriptor);
   } else {
     if (!FLAG_precompiled_mode) {
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 7e2133d..768d5c4 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -6900,6 +6900,19 @@
   compiler->assembler()->StoreMemoryValue(value_reg, base_reg, offset_);
 }
 
+const Code& ReturnInstr::GetReturnStub(FlowGraphCompiler* compiler) const {
+  ASSERT(compiler->parsed_function().function().IsCompactAsyncFunction());
+  if (!value()->Type()->CanBeFuture()) {
+    return Code::ZoneHandle(compiler->zone(),
+                            compiler->isolate_group()
+                                ->object_store()
+                                ->return_async_not_future_stub());
+  }
+  return Code::ZoneHandle(
+      compiler->zone(),
+      compiler->isolate_group()->object_store()->return_async_stub());
+}
+
 void NativeReturnInstr::EmitReturnMoves(FlowGraphCompiler* compiler) {
   const auto& dst1 = marshaller_.Location(compiler::ffi::kResultIndex);
   if (dst1.payload_type().IsVoid()) {
@@ -7209,6 +7222,55 @@
   return simd_op_information[kind()].has_mask;
 }
 
+LocationSummary* Call1ArgStubInstr::MakeLocationSummary(Zone* zone,
+                                                        bool opt) const {
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* locs = new (zone)
+      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
+  switch (stub_id_) {
+    case StubId::kInitAsync:
+      locs->set_in(0, Location::RegisterLocation(
+                          InitSuspendableFunctionStubABI::kTypeArgsReg));
+      break;
+    case StubId::kAwaitAsync:
+      locs->set_in(0, Location::RegisterLocation(SuspendStubABI::kArgumentReg));
+      break;
+  }
+  locs->set_out(0, Location::RegisterLocation(CallingConventions::kReturnReg));
+  return locs;
+}
+
+void Call1ArgStubInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  ObjectStore* object_store = compiler->isolate_group()->object_store();
+  Code& stub = Code::ZoneHandle(compiler->zone());
+  switch (stub_id_) {
+    case StubId::kInitAsync:
+      stub = object_store->init_async_stub();
+      break;
+    case StubId::kAwaitAsync:
+      stub = object_store->await_async_stub();
+      break;
+  }
+  compiler->GenerateStubCall(source(), stub, UntaggedPcDescriptors::kOther,
+                             locs(), deopt_id(), env());
+
+#if defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_IA32)
+  if (stub_id_ == StubId::kAwaitAsync) {
+    // On x86 (X64 and IA32) mismatch between calls and returns
+    // significantly regresses performance. So suspend stub
+    // does not return directly to the caller. Instead, a small
+    // epilogue is generated right after the call to suspend stub,
+    // and resume stub adjusts resume PC to skip this epilogue.
+    const intptr_t start = compiler->assembler()->CodeSize();
+    __ LeaveFrame();
+    __ ret();
+    RELEASE_ASSERT(compiler->assembler()->CodeSize() - start ==
+                   SuspendStubABI::kResumePcDistance);
+  }
+#endif
+}
+
 #undef __
 
 }  // namespace dart
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 08d8f81..d0bbaed 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -528,6 +528,7 @@
   M(BoxSmallInt, kNoGC)                                                        \
   M(IntConverter, kNoGC)                                                       \
   M(BitCast, kNoGC)                                                            \
+  M(Call1ArgStub, _)                                                           \
   M(LoadThread, kNoGC)                                                         \
   M(Deoptimize, kNoGC)                                                         \
   M(SimdOp, kNoGC)
@@ -3099,6 +3100,8 @@
   const intptr_t yield_index_;
   const Representation representation_;
 
+  const Code& GetReturnStub(FlowGraphCompiler* compiler) const;
+
   DISALLOW_COPY_AND_ASSIGN(ReturnInstr);
 };
 
@@ -9560,6 +9563,42 @@
   DISALLOW_COPY_AND_ASSIGN(SimdOpInstr);
 };
 
+// Generic instruction to call 1-argument stubs specified using [StubId].
+class Call1ArgStubInstr : public TemplateDefinition<1, Throws> {
+ public:
+  enum class StubId {
+    kInitAsync,
+    kAwaitAsync,
+  };
+
+  Call1ArgStubInstr(const InstructionSource& source,
+                    StubId stub_id,
+                    Value* operand,
+                    intptr_t deopt_id)
+      : TemplateDefinition(source, deopt_id),
+        stub_id_(stub_id),
+        token_pos_(source.token_pos) {
+    SetInputAt(0, operand);
+  }
+
+  Value* operand() const { return inputs_[0]; }
+  StubId stub_id() const { return stub_id_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
+
+  virtual bool CanCallDart() const { return true; }
+  virtual bool ComputeCanDeoptimize() const { return true; }
+  virtual bool HasUnknownSideEffects() const { return true; }
+
+  DECLARE_INSTRUCTION(Call1ArgStub);
+  PRINT_OPERANDS_TO_SUPPORT
+
+ private:
+  const StubId stub_id_;
+  const TokenPosition token_pos_;
+
+  DISALLOW_COPY_AND_ASSIGN(Call1ArgStubInstr);
+};
+
 #undef DECLARE_INSTRUCTION
 
 class Environment : public ZoneAllocated {
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index 3bdaac0..cf3345c 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -484,6 +484,13 @@
     ASSERT(result == CallingConventions::kReturnFpuReg);
   }
 
+  if (compiler->parsed_function().function().IsCompactAsyncFunction()) {
+    ASSERT(compiler->flow_graph().graph_entry()->NeedsFrame());
+    const Code& stub = GetReturnStub(compiler);
+    compiler->EmitJumpToStub(stub);
+    return;
+  }
+
   if (!compiler->flow_graph().graph_entry()->NeedsFrame()) {
     __ Ret();
     return;
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index d1a9fe0..a6a35de 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -411,6 +411,13 @@
     ASSERT(result == CallingConventions::kReturnFpuReg);
   }
 
+  if (compiler->parsed_function().function().IsCompactAsyncFunction()) {
+    ASSERT(compiler->flow_graph().graph_entry()->NeedsFrame());
+    const Code& stub = GetReturnStub(compiler);
+    compiler->EmitJumpToStub(stub);
+    return;
+  }
+
   if (!compiler->flow_graph().graph_entry()->NeedsFrame()) {
     __ ret();
     return;
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index 06243b2..3a4a935 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -116,7 +116,7 @@
     case 4:
     case 8:
     case 16:
-      __ rep_movsl();
+      __ rep_movsd();
       break;
   }
 
@@ -233,6 +233,13 @@
   Register result = locs()->in(0).reg();
   ASSERT(result == EAX);
 
+  if (compiler->parsed_function().function().IsCompactAsyncFunction()) {
+    ASSERT(compiler->flow_graph().graph_entry()->NeedsFrame());
+    const Code& stub = GetReturnStub(compiler);
+    compiler->EmitJumpToStub(stub);
+    return;
+  }
+
   if (!compiler->flow_graph().graph_entry()->NeedsFrame()) {
     __ ret();
     return;
@@ -256,7 +263,7 @@
   if (yield_index() != UntaggedPcDescriptors::kInvalidYieldIndex) {
     compiler->EmitYieldPositionMetadata(source(), yield_index());
   }
-  __ LeaveFrame();
+  __ LeaveDartFrame();
   __ ret();
 }
 
@@ -272,8 +279,7 @@
     return_in_st0 = true;
   }
 
-  // Leave Dart frame.
-  __ LeaveFrame();
+  __ LeaveDartFrame();
 
   // EDI is the only sane choice for a temporary register here because:
   //
@@ -1139,7 +1145,7 @@
             compiler::Address(SPREG, marshaller_.RequiredStackSpaceInBytes()));
   } else {
     // Leave dummy exit frame.
-    __ LeaveFrame();
+    __ LeaveDartFrame();
 
     // Instead of returning to the "fake" return address, we just pop it.
     __ popl(temp);
diff --git a/runtime/vm/compiler/backend/il_printer.cc b/runtime/vm/compiler/backend/il_printer.cc
index cc6770b..a4ed678 100644
--- a/runtime/vm/compiler/backend/il_printer.cc
+++ b/runtime/vm/compiler/backend/il_printer.cc
@@ -1356,6 +1356,21 @@
   f->AddString(")");
 }
 
+void Call1ArgStubInstr::PrintOperandsTo(BaseTextBuffer* f) const {
+  const char* name = "";
+  switch (stub_id_) {
+    case StubId::kInitAsync:
+      name = "InitAsync";
+      break;
+    case StubId::kAwaitAsync:
+      name = "AwaitAsync";
+      break;
+  }
+  f->Printf("%s(", name);
+  operand()->PrintTo(f);
+  f->AddString(")");
+}
+
 void PushArgumentInstr::PrintOperandsTo(BaseTextBuffer* f) const {
   value()->PrintTo(f);
 }
diff --git a/runtime/vm/compiler/backend/il_riscv.cc b/runtime/vm/compiler/backend/il_riscv.cc
index a2d70f7..d646861 100644
--- a/runtime/vm/compiler/backend/il_riscv.cc
+++ b/runtime/vm/compiler/backend/il_riscv.cc
@@ -464,6 +464,13 @@
     ASSERT(result == CallingConventions::kReturnFpuReg);
   }
 
+  if (compiler->parsed_function().function().IsCompactAsyncFunction()) {
+    ASSERT(compiler->flow_graph().graph_entry()->NeedsFrame());
+    const Code& stub = GetReturnStub(compiler);
+    compiler->EmitJumpToStub(stub);
+    return;
+  }
+
   if (!compiler->flow_graph().graph_entry()->NeedsFrame()) {
     __ ret();
     return;
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index b30b025..75475b1 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -180,7 +180,7 @@
       __ rep_movsw();
       break;
     case 4:
-      __ rep_movsl();
+      __ rep_movsd();
       break;
     case 8:
     case 16:
@@ -338,6 +338,13 @@
     ASSERT(result == CallingConventions::kReturnFpuReg);
   }
 
+  if (compiler->parsed_function().function().IsCompactAsyncFunction()) {
+    ASSERT(compiler->flow_graph().graph_entry()->NeedsFrame());
+    const Code& stub = GetReturnStub(compiler);
+    compiler->EmitJumpToStub(stub);
+    return;
+  }
+
   if (!compiler->flow_graph().graph_entry()->NeedsFrame()) {
     __ ret();
     return;
diff --git a/runtime/vm/compiler/backend/linearscan.cc b/runtime/vm/compiler/backend/linearscan.cc
index de3c5b1..8438490 100644
--- a/runtime/vm/compiler/backend/linearscan.cc
+++ b/runtime/vm/compiler/backend/linearscan.cc
@@ -2082,6 +2082,41 @@
   ConvertAllUses(range);
 }
 
+void FlowGraphAllocator::AllocateSpillSlotForSuspendState() {
+  if (flow_graph_.parsed_function().suspend_state_var() == nullptr) {
+    return;
+  }
+
+  spill_slots_.Add(kMaxPosition);
+  quad_spill_slots_.Add(false);
+  untagged_spill_slots_.Add(false);
+
+#if defined(DEBUG)
+  const intptr_t stack_index =
+      -compiler::target::frame_layout.VariableIndexForFrameSlot(
+          compiler::target::frame_layout.FrameSlotForVariable(
+              flow_graph_.parsed_function().suspend_state_var()));
+  ASSERT(stack_index == spill_slots_.length() - 1);
+#endif
+}
+
+void FlowGraphAllocator::UpdateStackmapsForSuspendState() {
+  if (flow_graph_.parsed_function().suspend_state_var() == nullptr) {
+    return;
+  }
+
+  const intptr_t stack_index =
+      -compiler::target::frame_layout.VariableIndexForFrameSlot(
+          compiler::target::frame_layout.FrameSlotForVariable(
+              flow_graph_.parsed_function().suspend_state_var()));
+  ASSERT(stack_index >= 0);
+
+  for (intptr_t i = 0, n = safepoints_.length(); i < n; ++i) {
+    Instruction* safepoint_instr = safepoints_[i];
+    safepoint_instr->locs()->SetStackBit(stack_index);
+  }
+}
+
 intptr_t FlowGraphAllocator::FirstIntersectionWithAllocated(
     intptr_t reg,
     LiveRange* unallocated) {
@@ -3102,11 +3137,11 @@
     return;
   }
 
-  // Optional parameter handling needs special changes to become frameless.
+  // Copying of parameters needs special changes to become frameless.
   // Specifically we need to rebase IL instructions which directly access frame
   // ({Load,Store}IndexedUnsafeInstr) to use SP rather than FP.
   // For now just always give such functions a frame.
-  if (flow_graph_.parsed_function().function().HasOptionalParameters()) {
+  if (flow_graph_.parsed_function().function().MakesCopyOfParameters()) {
     return;
   }
 
@@ -3211,8 +3246,15 @@
 
   NumberInstructions();
 
+  // Reserve spill slot for :suspend_state synthetic variable before
+  // reserving spill slots for parameter variables.
+  AllocateSpillSlotForSuspendState();
+
   BuildLiveRanges();
 
+  // Update stackmaps after all safepoints are collected.
+  UpdateStackmapsForSuspendState();
+
   if (FLAG_print_ssa_liveranges && CompilerState::ShouldTrace()) {
     const Function& function = flow_graph_.function();
     THR_Print("-- [before ssa allocator] ranges [%s] ---------\n",
diff --git a/runtime/vm/compiler/backend/linearscan.h b/runtime/vm/compiler/backend/linearscan.h
index bc26c63..7c16c5f 100644
--- a/runtime/vm/compiler/backend/linearscan.h
+++ b/runtime/vm/compiler/backend/linearscan.h
@@ -242,6 +242,13 @@
   // Find a spill slot that can be used by the given live range.
   void AllocateSpillSlotFor(LiveRange* range);
 
+  // Allocate spill slot for synthetic :suspend_state variable.
+  void AllocateSpillSlotForSuspendState();
+
+  // Mark synthetic :suspend_state variable as object in stackmaps
+  // at all safepoints.
+  void UpdateStackmapsForSuspendState();
+
   // Allocate the given live range to a spill slot.
   void Spill(LiveRange* range);
 
diff --git a/runtime/vm/compiler/backend/range_analysis.cc b/runtime/vm/compiler/backend/range_analysis.cc
index 2c4af9c..708308f 100644
--- a/runtime/vm/compiler/backend/range_analysis.cc
+++ b/runtime/vm/compiler/backend/range_analysis.cc
@@ -2814,6 +2814,9 @@
     case Slot::Kind::kFunctionType_parameter_types:
     case Slot::Kind::kFunctionType_type_parameters:
     case Slot::Kind::kInstance_native_fields_array:
+    case Slot::Kind::kSuspendState_future:
+    case Slot::Kind::kSuspendState_then_callback:
+    case Slot::Kind::kSuspendState_error_callback:
     case Slot::Kind::kTypedDataView_typed_data:
     case Slot::Kind::kType_arguments:
     case Slot::Kind::kTypeArgumentsIndex:
diff --git a/runtime/vm/compiler/backend/slot.cc b/runtime/vm/compiler/backend/slot.cc
index 9356180..77d0153 100644
--- a/runtime/vm/compiler/backend/slot.cc
+++ b/runtime/vm/compiler/backend/slot.cc
@@ -243,6 +243,9 @@
     case Slot::Kind::kFunctionType_named_parameter_names:
     case Slot::Kind::kFunctionType_parameter_types:
     case Slot::Kind::kFunctionType_type_parameters:
+    case Slot::Kind::kSuspendState_future:
+    case Slot::Kind::kSuspendState_then_callback:
+    case Slot::Kind::kSuspendState_error_callback:
     case Slot::Kind::kType_arguments:
     case Slot::Kind::kTypeArgumentsIndex:
     case Slot::Kind::kTypeParameters_names:
diff --git a/runtime/vm/compiler/backend/slot.h b/runtime/vm/compiler/backend/slot.h
index aa0c8ad..12609d6 100644
--- a/runtime/vm/compiler/backend/slot.h
+++ b/runtime/vm/compiler/backend/slot.h
@@ -73,6 +73,9 @@
   V(ImmutableLinkedHashBase, UntaggedLinkedHashBase, index,                    \
     TypedDataUint32Array, VAR)                                                 \
   V(Instance, UntaggedInstance, native_fields_array, Dynamic, VAR)             \
+  V(SuspendState, UntaggedSuspendState, future, Dynamic, VAR)                  \
+  V(SuspendState, UntaggedSuspendState, then_callback, Closure, VAR)           \
+  V(SuspendState, UntaggedSuspendState, error_callback, Closure, VAR)          \
   V(Type, UntaggedType, arguments, TypeArguments, FINAL)                       \
   V(TypeParameters, UntaggedTypeParameters, flags, Array, FINAL)               \
   V(TypeParameters, UntaggedTypeParameters, bounds, TypeArguments, FINAL)      \
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index 859fa3f..b163fbe 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -938,6 +938,43 @@
   return CanPotentiallyBeSmi(*ToAbstractType(), /*recurse=*/true);
 }
 
+bool CompileType::CanBeFuture() {
+  IsolateGroup* isolate_group = IsolateGroup::Current();
+  ObjectStore* object_store = isolate_group->object_store();
+
+  if (cid_ != kIllegalCid && cid_ != kDynamicCid) {
+    if ((cid_ == kNullCid) || (cid_ == kNeverCid)) {
+      return false;
+    }
+    const Class& cls = Class::Handle(isolate_group->class_table()->At(cid_));
+    return Class::IsSubtypeOf(
+        cls, TypeArguments::null_type_arguments(), Nullability::kNonNullable,
+        Type::Handle(object_store->non_nullable_future_rare_type()),
+        Heap::kNew);
+  }
+
+  AbstractType& type = AbstractType::Handle(ToAbstractType()->ptr());
+  if (type.IsTypeParameter()) {
+    type = TypeParameter::Cast(type).bound();
+  }
+  if (type.IsTypeParameter()) {
+    // Type parameter bounds can be cyclic, do not bother handling them here.
+    return true;
+  }
+  const intptr_t type_class_id = type.type_class_id();
+  if (type_class_id == kDynamicCid || type_class_id == kVoidCid ||
+      type_class_id == kInstanceCid || type_class_id == kFutureOrCid) {
+    return true;
+  }
+  if ((type_class_id == kNullCid) || (type_class_id == kNeverCid)) {
+    return false;
+  }
+  Type& future_type =
+      Type::Handle(object_store->non_nullable_future_rare_type());
+  future_type = future_type.ToNullability(Nullability::kNullable, Heap::kNew);
+  return type.IsSubtypeOf(future_type, Heap::kNew);
+}
+
 void CompileType::PrintTo(BaseTextBuffer* f) const {
   const char* type_name = "?";
   if (IsNone()) {
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
index e8fe9a6..31cf456 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
@@ -284,7 +284,7 @@
 
 Fragment BaseFlowGraphBuilder::TailCall(const Code& code) {
   Value* arg_desc = Pop();
-  return Fragment(new (Z) TailCallInstr(code, arg_desc));
+  return Fragment(new (Z) TailCallInstr(code, arg_desc)).closed();
 }
 
 void BaseFlowGraphBuilder::InlineBailout(const char* reason) {
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 0af255f..ab59d68 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -647,9 +647,9 @@
       LocalVariable* variable = pf.ParameterVariable(i);
       if (variable->is_captured()) {
         LocalVariable& raw_parameter = *pf.RawParameterVariable(i);
-        ASSERT((function.HasOptionalParameters() &&
+        ASSERT((function.MakesCopyOfParameters() &&
                 raw_parameter.owner() == scope) ||
-               (!function.HasOptionalParameters() &&
+               (!function.MakesCopyOfParameters() &&
                 raw_parameter.owner() == nullptr));
         ASSERT(!raw_parameter.is_captured());
 
@@ -666,6 +666,28 @@
   return body;
 }
 
+Fragment StreamingFlowGraphBuilder::InitSuspendableFunction(
+    const Function& dart_function) {
+  Fragment body;
+  if (dart_function.IsCompactAsyncFunction()) {
+    const auto& result_type =
+        AbstractType::Handle(Z, dart_function.result_type());
+    auto& type_args = TypeArguments::ZoneHandle(Z);
+    if (result_type.IsType() &&
+        (Class::Handle(Z, result_type.type_class()).IsFutureClass() ||
+         result_type.IsFutureOrType())) {
+      ASSERT(result_type.IsFinalized());
+      type_args = result_type.arguments();
+    }
+
+    body += TranslateInstantiatedTypeArguments(type_args);
+    body += B->Call1ArgStub(TokenPosition::kNoSource,
+                            Call1ArgStubInstr::StubId::kInitAsync);
+    body += Drop();
+  }
+  return body;
+}
+
 Fragment StreamingFlowGraphBuilder::ShortcutForUserDefinedEquals(
     const Function& dart_function,
     LocalVariable* first_parameter) {
@@ -885,6 +907,7 @@
   // objects than necessary during GC.
   const Fragment body =
       ClearRawParameters(dart_function) + B->BuildNullAssertions() +
+      InitSuspendableFunction(dart_function) +
       BuildFunctionBody(dart_function, first_parameter, is_constructor);
 
   auto extra_entry_point_style = ChooseEntryPointStyle(
@@ -1220,6 +1243,8 @@
       return BuildLibraryPrefixAction(position, Symbols::LoadLibrary());
     case kCheckLibraryIsLoaded:
       return BuildLibraryPrefixAction(position, Symbols::CheckLoaded());
+    case kAwaitExpression:
+      return BuildAwaitExpression(position);
     case kConstStaticInvocation:
     case kConstConstructorInvocation:
     case kConstListLiteral:
@@ -1442,6 +1467,10 @@
   return flow_graph_builder_->stack_;
 }
 
+void StreamingFlowGraphBuilder::set_stack(Value* top) {
+  flow_graph_builder_->stack_ = top;
+}
+
 void StreamingFlowGraphBuilder::Push(Definition* definition) {
   flow_graph_builder_->Push(definition);
 }
@@ -4291,6 +4320,20 @@
   return instructions;
 }
 
+Fragment StreamingFlowGraphBuilder::BuildAwaitExpression(
+    TokenPosition* position) {
+  ASSERT(parsed_function()->function().IsCompactAsyncFunction());
+  Fragment instructions;
+
+  const TokenPosition pos = ReadPosition();  // read file offset.
+  if (position != nullptr) *position = pos;
+
+  instructions += BuildExpression();  // read operand.
+
+  instructions += B->Call1ArgStub(pos, Call1ArgStubInstr::StubId::kAwaitAsync);
+  return instructions;
+}
+
 Fragment StreamingFlowGraphBuilder::BuildExpressionStatement(
     TokenPosition* position) {
   Fragment instructions = BuildExpression(position);  // read expression.
@@ -4468,7 +4511,6 @@
 
 Fragment StreamingFlowGraphBuilder::BuildWhileStatement(
     TokenPosition* position) {
-  ASSERT(block_expression_depth() == 0);  // no while in block-expr
   loop_depth_inc();
   const TokenPosition pos = ReadPosition();  // read position.
   if (position != nullptr) *position = pos;
@@ -4485,8 +4527,7 @@
     body_entry += Goto(join);
 
     Fragment loop(join);
-    ASSERT(B->GetStackDepth() == 0);
-    loop += CheckStackOverflow(pos);
+    loop += CheckStackOverflow(pos);  // may have non-empty stack
     loop.current->LinkTo(condition.entry);
 
     entry = Goto(join).entry;
@@ -4499,7 +4540,6 @@
 }
 
 Fragment StreamingFlowGraphBuilder::BuildDoStatement(TokenPosition* position) {
-  ASSERT(block_expression_depth() == 0);  // no do-while in block-expr
   loop_depth_inc();
   const TokenPosition pos = ReadPosition();  // read position.
   if (position != nullptr) *position = pos;
@@ -4516,8 +4556,7 @@
 
   JoinEntryInstr* join = BuildJoinEntry();
   Fragment loop(join);
-  ASSERT(B->GetStackDepth() == 0);
-  loop += CheckStackOverflow(pos);
+  loop += CheckStackOverflow(pos);  // may have non-empty stack
   loop += body;
   loop <<= condition.entry;
 
@@ -5089,7 +5128,6 @@
 }
 
 Fragment StreamingFlowGraphBuilder::BuildTryFinally(TokenPosition* position) {
-  ASSERT(block_expression_depth() == 0);  // no try-finally in block-expr
   // Note on streaming:
   // We only stream this TryFinally if we can stream everything inside it,
   // so creating a "TryFinallyBlock" with a kernel binary offset instead of an
@@ -5152,6 +5190,7 @@
 
   // Fill in the body of the catch.
   catch_depth_inc();
+
   const Array& handler_types = Array::ZoneHandle(Z, Array::New(1, Heap::kOld));
   handler_types.SetAt(0, Object::dynamic_type());
   // Note: rethrow will actually force mark the handler as needing a stacktrace.
@@ -5159,6 +5198,15 @@
                                           /* needs_stacktrace = */ false,
                                           /* is_synthesized = */ true);
   SetOffset(finalizer_offset);
+
+  // Try/finally might occur in control flow collections with non-empty
+  // expression stack (via desugaring of 'await for'). Note that catch-block
+  // generated for finally always throws so there is no merge.
+  // Save and reset expression stack around catch body in order to maintain
+  // correct stack depth, as catch entry drops expression stack.
+  Value* const saved_stack_top = stack();
+  set_stack(nullptr);
+
   finally_body += BuildStatementWithBranchCoverage();  // read finalizer
   if (finally_body.is_open()) {
     finally_body += LoadLocal(CurrentException());
@@ -5167,6 +5215,9 @@
         RethrowException(TokenPosition::kNoSource, try_handler_index);
     Drop();
   }
+
+  ASSERT(stack() == nullptr);
+  set_stack(saved_stack_top);
   catch_depth_dec();
 
   return Fragment(try_body.entry, after_try);
@@ -5416,36 +5467,53 @@
           lib.AddMetadata(function, func_decl_offset);
         }
 
-        function.set_is_debuggable(function_node_helper.dart_async_marker_ ==
-                                   FunctionNodeHelper::kSync);
-        switch (function_node_helper.dart_async_marker_) {
-          case FunctionNodeHelper::kSyncStar:
-            function.set_modifier(UntaggedFunction::kSyncGen);
-            break;
-          case FunctionNodeHelper::kAsync:
-            function.set_modifier(UntaggedFunction::kAsync);
-            break;
-          case FunctionNodeHelper::kAsyncStar:
-            function.set_modifier(UntaggedFunction::kAsyncGen);
-            break;
-          default:
-            // no special modifier
-            break;
-        }
-        function.set_is_generated_body(function_node_helper.async_marker_ ==
-                                       FunctionNodeHelper::kSyncYielding);
-        // sync* functions contain two nested synthetic functions, the first of
-        // which (sync_op_gen) is a regular sync function so we need to manually
-        // label it generated:
-        if (function.parent_function() != Function::null()) {
-          const auto& parent = Function::Handle(function.parent_function());
-          if (parent.IsSyncGenerator()) {
-            function.set_is_generated_body(true);
+        if (function_node_helper.async_marker_ == FunctionNodeHelper::kAsync) {
+          if (!FLAG_precompiled_mode) {
+            FATAL("Compact async functions are only supported in AOT mode.");
           }
-        }
-        // Note: Is..() methods use the modifiers set above, so order matters.
-        if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) {
-          function.set_is_inlinable(!FLAG_lazy_async_stacks);
+          function.set_modifier(UntaggedFunction::kAsync);
+          function.set_is_debuggable(true);
+          function.set_is_inlinable(false);
+          function.set_is_visible(true);
+          ASSERT(function.IsCompactAsyncFunction());
+        } else {
+          ASSERT((function_node_helper.async_marker_ ==
+                  FunctionNodeHelper::kSync) ||
+                 (function_node_helper.async_marker_ ==
+                  FunctionNodeHelper::kSyncYielding));
+          function.set_is_debuggable(function_node_helper.dart_async_marker_ ==
+                                     FunctionNodeHelper::kSync);
+          switch (function_node_helper.dart_async_marker_) {
+            case FunctionNodeHelper::kSyncStar:
+              function.set_modifier(UntaggedFunction::kSyncGen);
+              break;
+            case FunctionNodeHelper::kAsync:
+              function.set_modifier(UntaggedFunction::kAsync);
+              break;
+            case FunctionNodeHelper::kAsyncStar:
+              function.set_modifier(UntaggedFunction::kAsyncGen);
+              break;
+            default:
+              // no special modifier
+              break;
+          }
+          function.set_is_generated_body(function_node_helper.async_marker_ ==
+                                         FunctionNodeHelper::kSyncYielding);
+          // sync* functions contain two nested synthetic functions,
+          // the first of which (sync_op_gen) is a regular sync function so we
+          // need to manually label it generated:
+          if (function.parent_function() != Function::null()) {
+            const auto& parent = Function::Handle(function.parent_function());
+            if (parent.IsSyncGenerator()) {
+              function.set_is_generated_body(true);
+            }
+          }
+          // Note: Is..() methods use the modifiers set above, so order
+          // matters.
+          if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) {
+            function.set_is_inlinable(!FLAG_lazy_async_stacks);
+          }
+          ASSERT(!function.IsCompactAsyncFunction());
         }
 
         // If the start token position is synthetic, the end token position
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index cc8a1f9..cd5ccb6 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -93,6 +93,7 @@
   Fragment SetAsyncStackTrace(const Function& dart_function);
   Fragment CheckStackOverflowInPrologue(const Function& dart_function);
   Fragment SetupCapturedParameters(const Function& dart_function);
+  Fragment InitSuspendableFunction(const Function& dart_function);
   Fragment ShortcutForUserDefinedEquals(const Function& dart_function,
                                         LocalVariable* first_parameter);
   Fragment TypeArgumentsHandling(const Function& dart_function);
@@ -131,6 +132,7 @@
   BreakableBlock* breakable_block();
   GrowableArray<YieldContinuation>& yield_continuations();
   Value* stack();
+  void set_stack(Value* top);
   void Push(Definition* definition);
   Value* Pop();
   Class& GetSuperOrDie();
@@ -335,6 +337,7 @@
   Fragment BuildPartialTearoffInstantiation(TokenPosition* position);
   Fragment BuildLibraryPrefixAction(TokenPosition* position,
                                     const String& selector);
+  Fragment BuildAwaitExpression(TokenPosition* position);
 
   Fragment BuildExpressionStatement(TokenPosition* position);
   Fragment BuildBlock(TokenPosition* position);
diff --git a/runtime/vm/compiler/frontend/kernel_fingerprints.cc b/runtime/vm/compiler/frontend/kernel_fingerprints.cc
index d55f1c2..21884e4 100644
--- a/runtime/vm/compiler/frontend/kernel_fingerprints.cc
+++ b/runtime/vm/compiler/frontend/kernel_fingerprints.cc
@@ -617,6 +617,10 @@
     case kCheckLibraryIsLoaded:
       ReadUInt();  // skip library index
       return;
+    case kAwaitExpression:
+      ReadPosition();                    // read position.
+      CalculateExpressionFingerprint();  // read operand.
+      return;
     case kConstStaticInvocation:
     case kConstConstructorInvocation:
     case kConstListLiteral:
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index a769901..6f0e43c 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -309,8 +309,7 @@
   // => We therefore create a block for the body (fresh try index) and another
   //    join block (with current try index).
   Fragment body;
-  JoinEntryInstr* entry = new (Z)
-      JoinEntryInstr(AllocateBlockId(), try_handler_index, GetNextDeoptId());
+  JoinEntryInstr* entry = BuildJoinEntry(try_handler_index);
   body += LoadLocal(parsed_function_->current_context_var());
   body += StoreLocal(TokenPosition::kNoSource, CurrentCatchContext());
   body += Drop();
@@ -835,6 +834,9 @@
   V(LinkedHashBase_getIndex, LinkedHashBase_index)                             \
   V(LinkedHashBase_getUsedData, LinkedHashBase_used_data)                      \
   V(ObjectArrayLength, Array_length)                                           \
+  V(SuspendState_getFuture, SuspendState_future)                               \
+  V(SuspendState_getThenCallback, SuspendState_then_callback)                  \
+  V(SuspendState_getErrorCallback, SuspendState_error_callback)                \
   V(TypedDataViewOffsetInBytes, TypedDataView_offset_in_bytes)                 \
   V(TypedDataViewTypedData, TypedDataView_typed_data)                          \
   V(TypedListBaseLength, TypedDataBase_length)                                 \
@@ -850,6 +852,9 @@
   V(NativeFinalizer_setCallback, NativeFinalizer_callback)                     \
   V(LinkedHashBase_setData, LinkedHashBase_data)                               \
   V(LinkedHashBase_setIndex, LinkedHashBase_index)                             \
+  V(SuspendState_setFuture, SuspendState_future)                               \
+  V(SuspendState_setThenCallback, SuspendState_then_callback)                  \
+  V(SuspendState_setErrorCallback, SuspendState_error_callback)                \
   V(WeakProperty_setKey, WeakProperty_key)                                     \
   V(WeakProperty_setValue, WeakProperty_value)                                 \
   V(WeakReference_setTarget, WeakReference_target)
@@ -864,6 +869,7 @@
   const MethodRecognizer::Kind kind = function.recognized_kind();
 
   switch (kind) {
+    case MethodRecognizer::kSuspendState_resume:
     case MethodRecognizer::kTypedData_ByteDataView_factory:
     case MethodRecognizer::kTypedData_Int8ArrayView_factory:
     case MethodRecognizer::kTypedData_Uint8ArrayView_factory:
@@ -1012,6 +1018,13 @@
 
   const MethodRecognizer::Kind kind = function.recognized_kind();
   switch (kind) {
+    case MethodRecognizer::kSuspendState_resume: {
+      const Code& resume_stub =
+          Code::ZoneHandle(Z, IG->object_store()->resume_stub());
+      body += NullConstant();
+      body += TailCall(resume_stub);
+      break;
+    }
     case MethodRecognizer::kTypedData_ByteDataView_factory:
       body += BuildTypedDataViewFactoryConstructor(function, kByteDataViewCid);
       break;
@@ -1704,7 +1717,10 @@
     }
   }
 
-  body += Return(TokenPosition::kNoSource, /* omit_result_type_check = */ true);
+  if (body.is_open()) {
+    body +=
+        Return(TokenPosition::kNoSource, /* omit_result_type_check = */ true);
+  }
 
   return new (Z) FlowGraph(*parsed_function_, graph_entry_, last_used_block_id_,
                            prologue_info);
@@ -4184,6 +4200,14 @@
   return Fragment(instr);
 }
 
+Fragment FlowGraphBuilder::Call1ArgStub(TokenPosition position,
+                                        Call1ArgStubInstr::StubId stub_id) {
+  Call1ArgStubInstr* instr = new (Z) Call1ArgStubInstr(
+      InstructionSource(position), stub_id, Pop(), GetNextDeoptId());
+  Push(instr);
+  return Fragment(instr);
+}
+
 Fragment FlowGraphBuilder::WrapTypedDataBaseInCompound(
     const AbstractType& compound_type) {
   const auto& compound_sub_class =
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.h b/runtime/vm/compiler/frontend/kernel_to_il.h
index eeab45d..c7f7478 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.h
+++ b/runtime/vm/compiler/frontend/kernel_to_il.h
@@ -416,6 +416,10 @@
   // Currently only works with equal sizes and floating point <-> integer.
   Fragment BitCast(Representation from, Representation to);
 
+  // Generates Call1ArgStub instruction.
+  Fragment Call1ArgStub(TokenPosition position,
+                        Call1ArgStubInstr::StubId stub_id);
+
   LocalVariable* LookupVariable(intptr_t kernel_offset);
 
   // Build type argument type checks for the current function.
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 6026870..66a054c 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -2620,6 +2620,10 @@
     case kCheckLibraryIsLoaded:
       ReadUInt();  // skip library index
       return;
+    case kAwaitExpression:
+      ReadPosition();    // read position.
+      SkipExpression();  // read operand.
+      return;
     case kConstStaticInvocation:
     case kConstConstructorInvocation:
     case kConstListLiteral:
diff --git a/runtime/vm/compiler/frontend/prologue_builder.cc b/runtime/vm/compiler/frontend/prologue_builder.cc
index 635b3d9..86e6638 100644
--- a/runtime/vm/compiler/frontend/prologue_builder.cc
+++ b/runtime/vm/compiler/frontend/prologue_builder.cc
@@ -35,12 +35,12 @@
 
 bool PrologueBuilder::PrologueSkippableOnUncheckedEntry(
     const Function& function) {
-  return !function.HasOptionalParameters() &&
+  return !function.MakesCopyOfParameters() &&
          !function.IsNonImplicitClosureFunction() && !function.IsGeneric();
 }
 
 bool PrologueBuilder::HasEmptyPrologue(const Function& function) {
-  return !function.HasOptionalParameters() && !function.IsGeneric() &&
+  return !function.MakesCopyOfParameters() && !function.IsGeneric() &&
          !function.IsClosureFunction();
 }
 
@@ -51,14 +51,13 @@
 
   const intptr_t previous_block_id = last_used_block_id_;
 
-  const bool load_optional_arguments = function_.HasOptionalParameters();
+  const bool copy_parameters = function_.MakesCopyOfParameters();
   const bool expect_type_args = function_.IsGeneric();
 
   Fragment prologue = Fragment(entry);
 
-  if (load_optional_arguments) {
-    Fragment f =
-        BuildOptionalParameterHandling(parsed_function_->expression_temp_var());
+  if (copy_parameters) {
+    Fragment f = BuildParameterHandling();
     if (link) prologue += f;
   }
   if (function_.IsClosureFunction()) {
@@ -94,8 +93,7 @@
   }
 }
 
-Fragment PrologueBuilder::BuildOptionalParameterHandling(
-    LocalVariable* temp_var) {
+Fragment PrologueBuilder::BuildParameterHandling() {
   Fragment copy_args_prologue;
   const int num_fixed_params = function_.num_fixed_parameters();
   const int num_opt_pos_params = function_.NumOptionalPositionalParameters();
@@ -111,18 +109,22 @@
   // where num_pos_args is the number of positional arguments passed in.
   const int min_num_pos_args = num_fixed_params;
 
-  copy_args_prologue += LoadArgDescriptor();
-  copy_args_prologue +=
-      LoadNativeField(Slot::ArgumentsDescriptor_positional_count());
+  LocalVariable* count_var = nullptr;
+  LocalVariable* optional_count_var = nullptr;
+  if ((num_opt_pos_params > 0) || (num_opt_named_params > 0)) {
+    copy_args_prologue += LoadArgDescriptor();
+    copy_args_prologue +=
+        LoadNativeField(Slot::ArgumentsDescriptor_positional_count());
 
-  copy_args_prologue += LoadArgDescriptor();
-  copy_args_prologue += LoadNativeField(Slot::ArgumentsDescriptor_count());
-  LocalVariable* count_var = MakeTemporary();
+    copy_args_prologue += LoadArgDescriptor();
+    copy_args_prologue += LoadNativeField(Slot::ArgumentsDescriptor_count());
+    count_var = MakeTemporary();
 
-  copy_args_prologue += LoadLocal(count_var);
-  copy_args_prologue += IntConstant(min_num_pos_args);
-  copy_args_prologue += SmiBinaryOp(Token::kSUB, /* truncate= */ true);
-  LocalVariable* optional_count_var = MakeTemporary();
+    copy_args_prologue += LoadLocal(count_var);
+    copy_args_prologue += IntConstant(min_num_pos_args);
+    copy_args_prologue += SmiBinaryOp(Token::kSUB, /* truncate= */ true);
+    optional_count_var = MakeTemporary();
+  }
 
   // Copy mandatory parameters down.
   intptr_t param = 0;
@@ -157,7 +159,11 @@
              ? FlowGraph::ParameterRepresentationAt(function_, param_index)
              : kTagged);
 
-    copy_args_prologue += LoadLocal(optional_count_var);
+    if ((num_opt_pos_params > 0) || (num_opt_named_params > 0)) {
+      copy_args_prologue += LoadLocal(optional_count_var);
+    } else {
+      copy_args_prologue += IntConstant(0);
+    }
     copy_args_prologue += LoadFpRelativeSlot(
         compiler::target::kWordSize *
             (compiler::target::frame_layout.param_end_from_fp +
@@ -208,9 +214,8 @@
     }
     copy_args_prologue += Goto(next_missing /* join good/not_good flows */);
     copy_args_prologue.current = next_missing;
-  } else {
-    ASSERT(num_opt_named_params > 0);
 
+  } else if (num_opt_named_params > 0) {
     const bool check_required_params =
         IsolateGroup::Current()->use_strict_null_safety_checks();
     const intptr_t first_name_offset =
@@ -222,8 +227,9 @@
     SortOptionalNamedParametersInto(opt_param_position, num_fixed_params,
                                     num_params);
 
-    ASSERT(temp_var != nullptr);
-    LocalVariable* optional_count_vars_processed = temp_var;
+    LocalVariable* optional_count_vars_processed =
+        parsed_function_->expression_temp_var();
+    ASSERT(optional_count_vars_processed != nullptr);
     copy_args_prologue += IntConstant(0);
     copy_args_prologue +=
         StoreLocalRaw(TokenPosition::kNoSource, optional_count_vars_processed);
@@ -332,9 +338,11 @@
     }
   }
 
-  copy_args_prologue += Drop();  // optional_count_var
-  copy_args_prologue += Drop();  // count_var
-  copy_args_prologue += Drop();  // positional_count_var
+  if ((num_opt_pos_params > 0) || (num_opt_named_params > 0)) {
+    copy_args_prologue += Drop();  // optional_count_var
+    copy_args_prologue += Drop();  // count_var
+    copy_args_prologue += Drop();  // positional_count_var
+  }
 
   return copy_args_prologue;
 }
diff --git a/runtime/vm/compiler/frontend/prologue_builder.h b/runtime/vm/compiler/frontend/prologue_builder.h
index d474d72..30605ad 100644
--- a/runtime/vm/compiler/frontend/prologue_builder.h
+++ b/runtime/vm/compiler/frontend/prologue_builder.h
@@ -49,7 +49,7 @@
   BlockEntryInstr* BuildPrologue(BlockEntryInstr* entry,
                                  PrologueInfo* prologue_info);
 
-  Fragment BuildOptionalParameterHandling(LocalVariable* temp_var);
+  Fragment BuildParameterHandling();
 
   static bool HasEmptyPrologue(const Function& function);
   static bool PrologueSkippableOnUncheckedEntry(const Function& function);
diff --git a/runtime/vm/compiler/frontend/scope_builder.cc b/runtime/vm/compiler/frontend/scope_builder.cc
index f103f14..c20ee54 100644
--- a/runtime/vm/compiler/frontend/scope_builder.cc
+++ b/runtime/vm/compiler/frontend/scope_builder.cc
@@ -89,6 +89,16 @@
   scope_->set_begin_token_pos(function.token_pos());
   scope_->set_end_token_pos(function.end_token_pos());
 
+  if (function.IsCompactAsyncFunction()) {
+    LocalVariable* suspend_state_var =
+        MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
+                     Symbols::SuspendStateVar(), AbstractType::dynamic_type());
+    suspend_state_var->set_is_forced_stack();
+    suspend_state_var->set_invisible(true);
+    scope_->AddVariable(suspend_state_var);
+    parsed_function_->set_suspend_state_var(suspend_state_var);
+  }
+
   // Add function type arguments variable before current context variable.
   if (function.IsGeneric() || function.HasGenericParent()) {
     LocalVariable* type_args_var = MakeVariable(
@@ -438,6 +448,12 @@
 
   parsed_function_->AllocateVariables();
 
+  // :suspend_state variable should be allocated to a fixed location in
+  // the stack frame.
+  RELEASE_ASSERT((parsed_function_->suspend_state_var() == nullptr) ||
+                 (parsed_function_->suspend_state_var()->index().value() ==
+                  SuspendState::kSuspendStateVarIndex));
+
   return result_;
 }
 
@@ -977,6 +993,10 @@
     case kCheckLibraryIsLoaded:
       helper_.ReadUInt();  // library index
       break;
+    case kAwaitExpression:
+      helper_.ReadPosition();  // read position.
+      VisitExpression();       // read operand.
+      return;
     case kConstStaticInvocation:
     case kConstConstructorInvocation:
     case kConstListLiteral:
diff --git a/runtime/vm/compiler/recognized_methods_list.h b/runtime/vm/compiler/recognized_methods_list.h
index 0331e00..f1ce6f5 100644
--- a/runtime/vm/compiler/recognized_methods_list.h
+++ b/runtime/vm/compiler/recognized_methods_list.h
@@ -83,6 +83,19 @@
   V(::, copyRangeFromUint8ListToOneByteString,                                 \
     CopyRangeFromUint8ListToOneByteString, 0x19a1bf41)                         \
   V(_StringBase, _interpolate, StringBaseInterpolate, 0x7da2a580)              \
+  V(_SuspendState, get:_future, SuspendState_getFuture, 0x0e2a7e73)            \
+  V(_SuspendState, set:_future, SuspendState_setFuture, 0x179923b0)            \
+  V(_SuspendState, get:_thenCallback, SuspendState_getThenCallback,            \
+    0xff1dccec)                                                                \
+  V(_SuspendState, set:_thenCallback, SuspendState_setThenCallback,            \
+    0x6446bde9)                                                                \
+  V(_SuspendState, get:_errorCallback, SuspendState_getErrorCallback,          \
+    0x8a6eb3cf)                                                                \
+  V(_SuspendState, set:_errorCallback, SuspendState_setErrorCallback,          \
+    0x4935f88c)                                                                \
+  V(_SuspendState, _createAsyncCallbacks, SuspendState_createAsyncCallbacks,   \
+    0x4add6c13)                                                                \
+  V(_SuspendState, _resume, SuspendState_resume, 0x93d8c5e8)                   \
   V(_IntegerImplementation, toDouble, IntegerToDouble, 0x97728b46)             \
   V(_Double, _add, DoubleAdd, 0xea666327)                                      \
   V(_Double, _sub, DoubleSub, 0x28474c2e)                                      \
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc
index 5ae1b56..6ccecf7 100644
--- a/runtime/vm/compiler/runtime_api.cc
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -213,9 +213,10 @@
   return Class::Handle(object_store->closure_class());
 }
 
-const Array& OneArgArgumentsDescriptor() {
+const Array& ArgumentsDescriptorBoxed(intptr_t type_args_len,
+                                      intptr_t num_arguments) {
   return Array::ZoneHandle(
-      ArgumentsDescriptor::NewBoxed(/*type_args_len=*/0, /*num_arguments=*/1));
+      ArgumentsDescriptor::NewBoxed(type_args_len, num_arguments));
 }
 
 bool IsOriginalObject(const Object& object) {
diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h
index f2c212d..267337f 100644
--- a/runtime/vm/compiler/runtime_api.h
+++ b/runtime/vm/compiler/runtime_api.h
@@ -120,7 +120,8 @@
 const Class& Float64x2Class();
 const Class& Int32x4Class();
 const Class& ClosureClass();
-const Array& OneArgArgumentsDescriptor();
+const Array& ArgumentsDescriptorBoxed(intptr_t type_args_len,
+                                      intptr_t num_arguments);
 
 template <typename To, typename From>
 const To& CastHandle(const From& from) {
@@ -987,6 +988,21 @@
   FINAL_CLASS();
 };
 
+class SuspendState : public AllStatic {
+ public:
+  static word frame_size_offset();
+  static word pc_offset();
+  static word future_offset();
+  static word then_callback_offset();
+  static word error_callback_offset();
+  static word payload_offset();
+
+  static word HeaderSize();
+  static word InstanceSize();
+  static word InstanceSize(word payload_size);
+  FINAL_CLASS();
+};
+
 class Integer : public AllStatic {
  public:
   static word InstanceSize();
@@ -1222,6 +1238,12 @@
 
   static word random_offset();
 
+  static word suspend_state_init_async_entry_point_offset();
+  static word suspend_state_await_async_entry_point_offset();
+  static word suspend_state_return_async_entry_point_offset();
+  static word suspend_state_return_async_not_future_entry_point_offset();
+  static word suspend_state_handle_exception_entry_point_offset();
+
   static word OffsetFromThread(const dart::Object& object);
   static intptr_t OffsetFromThread(const dart::RuntimeEntry* runtime_entry);
 };
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index 2e89961..738ed65 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -245,11 +245,20 @@
 static constexpr dart::compiler::target::word String_length_offset = 4;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 4;
 static constexpr dart::compiler::target::word
+    SuspendState_error_callback_offset = 20;
+static constexpr dart::compiler::target::word SuspendState_frame_size_offset =
+    4;
+static constexpr dart::compiler::target::word SuspendState_future_offset = 12;
+static constexpr dart::compiler::target::word SuspendState_payload_offset = 24;
+static constexpr dart::compiler::target::word SuspendState_pc_offset = 8;
+static constexpr dart::compiler::target::word
+    SuspendState_then_callback_offset = 16;
+static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 380;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    756;
+    780;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    760;
+    784;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 272;
 static constexpr dart::compiler::target::word
@@ -272,7 +281,7 @@
     Thread_allocate_object_slow_entry_point_offset = 296;
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 200;
-static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 796;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 820;
 static constexpr dart::compiler::target::word
     Thread_auto_scope_native_wrapper_entry_point_offset = 344;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 120;
@@ -283,13 +292,13 @@
     Thread_call_to_runtime_entry_point_offset = 276;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 140;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 824;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 848;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 44;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 800;
+    Thread_double_truncate_round_supported_offset = 824;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 828;
+    Thread_service_extension_stream_offset = 852;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     316;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 228;
@@ -305,7 +314,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 252;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    776;
+    800;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 256;
 static constexpr dart::compiler::target::word
@@ -327,13 +336,13 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 376;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    764;
+    788;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 136;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    792;
+    816;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 40;
-static constexpr dart::compiler::target::word Thread_isolate_group_offset = 832;
+static constexpr dart::compiler::target::word Thread_isolate_group_offset = 856;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     64;
 static constexpr dart::compiler::target::word
@@ -375,11 +384,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 112;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 348;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 768;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 792;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 772;
+    Thread_saved_shadow_call_stack_offset = 796;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    780;
+    804;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 244;
 static constexpr dart::compiler::target::word
@@ -400,6 +409,16 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     76;
 static constexpr dart::compiler::target::word
+    Thread_suspend_state_await_async_entry_point_offset = 764;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_init_async_entry_point_offset = 760;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_entry_point_offset = 768;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 772;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_handle_exception_entry_point_offset = 776;
+static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 72;
 static constexpr dart::compiler::target::word Thread_top_offset = 48;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 16;
@@ -413,13 +432,13 @@
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     32;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 36;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 784;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 808;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 788;
-static constexpr dart::compiler::target::word Thread_random_offset = 808;
+    Thread_callback_stack_return_offset = 812;
+static constexpr dart::compiler::target::word Thread_random_offset = 832;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 328;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 816;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 840;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -512,7 +531,7 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        724, 728, 732, 736, 740, -1, 744, -1, 748, 752, -1, -1, -1, -1, -1, -1};
+        728, 732, 736, 740, 744, -1, 748, -1, 752, 756, -1, -1, -1, -1, -1, -1};
 static constexpr dart::compiler::target::word AbstractType_InstanceSize = 12;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 8;
 static constexpr dart::compiler::target::word Array_header_size = 12;
@@ -585,6 +604,7 @@
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
     16;
 static constexpr dart::compiler::target::word StackTrace_InstanceSize = 20;
+static constexpr dart::compiler::target::word SuspendState_HeaderSize = 24;
 static constexpr dart::compiler::target::word String_InstanceSize = 12;
 static constexpr dart::compiler::target::word SubtypeTestCache_InstanceSize = 8;
 static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 20;
@@ -840,11 +860,20 @@
 static constexpr dart::compiler::target::word String_length_offset = 8;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
+    SuspendState_error_callback_offset = 40;
+static constexpr dart::compiler::target::word SuspendState_frame_size_offset =
+    8;
+static constexpr dart::compiler::target::word SuspendState_future_offset = 24;
+static constexpr dart::compiler::target::word SuspendState_payload_offset = 48;
+static constexpr dart::compiler::target::word SuspendState_pc_offset = 16;
+static constexpr dart::compiler::target::word
+    SuspendState_then_callback_offset = 32;
+static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 736;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1512;
+    1560;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1520;
+    1568;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
@@ -868,7 +897,7 @@
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 376;
 static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1592;
+    1640;
 static constexpr dart::compiler::target::word
     Thread_auto_scope_native_wrapper_entry_point_offset = 664;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 216;
@@ -879,13 +908,13 @@
     Thread_call_to_runtime_entry_point_offset = 528;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 256;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1632;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1680;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 1600;
+    Thread_double_truncate_round_supported_offset = 1648;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 1640;
+    Thread_service_extension_stream_offset = 1688;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     608;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 432;
@@ -901,7 +930,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1552;
+    1600;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
@@ -923,14 +952,14 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 728;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1528;
+    1576;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1584;
+    1632;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word Thread_isolate_group_offset =
-    1648;
+    1696;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     128;
 static constexpr dart::compiler::target::word
@@ -972,11 +1001,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 200;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 672;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1536;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1584;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1544;
+    Thread_saved_shadow_call_stack_offset = 1592;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1560;
+    1608;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
@@ -997,6 +1026,16 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     152;
 static constexpr dart::compiler::target::word
+    Thread_suspend_state_await_async_entry_point_offset = 1528;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_init_async_entry_point_offset = 1520;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_entry_point_offset = 1536;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 1544;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_handle_exception_entry_point_offset = 1552;
+static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word Thread_top_offset = 96;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 32;
@@ -1011,13 +1050,13 @@
     64;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1568;
+    1616;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 1576;
-static constexpr dart::compiler::target::word Thread_random_offset = 1608;
+    Thread_callback_stack_return_offset = 1624;
+static constexpr dart::compiler::target::word Thread_random_offset = 1656;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 632;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1616;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1664;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -1112,8 +1151,8 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        1424, 1432, 1440, 1448, -1,   -1,   1456, 1464,
-        1472, 1480, 1488, -1,   1496, 1504, -1,   -1};
+        1432, 1440, 1448, 1456, -1,   -1,   1464, 1472,
+        1480, 1488, 1496, -1,   1504, 1512, -1,   -1};
 static constexpr dart::compiler::target::word AbstractType_InstanceSize = 24;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_header_size = 24;
@@ -1186,6 +1225,7 @@
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
     32;
 static constexpr dart::compiler::target::word StackTrace_InstanceSize = 40;
+static constexpr dart::compiler::target::word SuspendState_HeaderSize = 48;
 static constexpr dart::compiler::target::word String_InstanceSize = 16;
 static constexpr dart::compiler::target::word SubtypeTestCache_InstanceSize =
     16;
@@ -1438,11 +1478,20 @@
 static constexpr dart::compiler::target::word String_length_offset = 4;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 4;
 static constexpr dart::compiler::target::word
+    SuspendState_error_callback_offset = 20;
+static constexpr dart::compiler::target::word SuspendState_frame_size_offset =
+    4;
+static constexpr dart::compiler::target::word SuspendState_future_offset = 12;
+static constexpr dart::compiler::target::word SuspendState_payload_offset = 24;
+static constexpr dart::compiler::target::word SuspendState_pc_offset = 8;
+static constexpr dart::compiler::target::word
+    SuspendState_then_callback_offset = 16;
+static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 380;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    724;
+    748;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    728;
+    752;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 272;
 static constexpr dart::compiler::target::word
@@ -1465,7 +1514,7 @@
     Thread_allocate_object_slow_entry_point_offset = 296;
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 200;
-static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 764;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 788;
 static constexpr dart::compiler::target::word
     Thread_auto_scope_native_wrapper_entry_point_offset = 344;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 120;
@@ -1476,13 +1525,13 @@
     Thread_call_to_runtime_entry_point_offset = 276;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 140;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 792;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 816;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 44;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 768;
+    Thread_double_truncate_round_supported_offset = 792;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 796;
+    Thread_service_extension_stream_offset = 820;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     316;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 228;
@@ -1498,7 +1547,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 252;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    744;
+    768;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 256;
 static constexpr dart::compiler::target::word
@@ -1520,13 +1569,13 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 376;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    732;
+    756;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 136;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    760;
+    784;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 40;
-static constexpr dart::compiler::target::word Thread_isolate_group_offset = 800;
+static constexpr dart::compiler::target::word Thread_isolate_group_offset = 824;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     64;
 static constexpr dart::compiler::target::word
@@ -1568,11 +1617,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 112;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 348;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 736;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 760;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 740;
+    Thread_saved_shadow_call_stack_offset = 764;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    748;
+    772;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 244;
 static constexpr dart::compiler::target::word
@@ -1593,6 +1642,16 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     76;
 static constexpr dart::compiler::target::word
+    Thread_suspend_state_await_async_entry_point_offset = 732;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_init_async_entry_point_offset = 728;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_entry_point_offset = 736;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 740;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_handle_exception_entry_point_offset = 744;
+static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 72;
 static constexpr dart::compiler::target::word Thread_top_offset = 48;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 16;
@@ -1606,13 +1665,13 @@
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     32;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 36;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 752;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 776;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 756;
-static constexpr dart::compiler::target::word Thread_random_offset = 776;
+    Thread_callback_stack_return_offset = 780;
+static constexpr dart::compiler::target::word Thread_random_offset = 800;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 328;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 784;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 808;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -1775,6 +1834,7 @@
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
     16;
 static constexpr dart::compiler::target::word StackTrace_InstanceSize = 20;
+static constexpr dart::compiler::target::word SuspendState_HeaderSize = 24;
 static constexpr dart::compiler::target::word String_InstanceSize = 12;
 static constexpr dart::compiler::target::word SubtypeTestCache_InstanceSize = 8;
 static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 20;
@@ -2030,11 +2090,20 @@
 static constexpr dart::compiler::target::word String_length_offset = 8;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
+    SuspendState_error_callback_offset = 40;
+static constexpr dart::compiler::target::word SuspendState_frame_size_offset =
+    8;
+static constexpr dart::compiler::target::word SuspendState_future_offset = 24;
+static constexpr dart::compiler::target::word SuspendState_payload_offset = 48;
+static constexpr dart::compiler::target::word SuspendState_pc_offset = 16;
+static constexpr dart::compiler::target::word
+    SuspendState_then_callback_offset = 32;
+static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 736;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1576;
+    1624;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1584;
+    1632;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
@@ -2058,7 +2127,7 @@
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 376;
 static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1656;
+    1704;
 static constexpr dart::compiler::target::word
     Thread_auto_scope_native_wrapper_entry_point_offset = 664;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 216;
@@ -2069,13 +2138,13 @@
     Thread_call_to_runtime_entry_point_offset = 528;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 256;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1696;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1744;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 1664;
+    Thread_double_truncate_round_supported_offset = 1712;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 1704;
+    Thread_service_extension_stream_offset = 1752;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     608;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 432;
@@ -2091,7 +2160,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1616;
+    1664;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
@@ -2113,14 +2182,14 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 728;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1592;
+    1640;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1648;
+    1696;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word Thread_isolate_group_offset =
-    1712;
+    1760;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     128;
 static constexpr dart::compiler::target::word
@@ -2162,11 +2231,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 200;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 672;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1600;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1648;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1608;
+    Thread_saved_shadow_call_stack_offset = 1656;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1624;
+    1672;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
@@ -2187,6 +2256,16 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     152;
 static constexpr dart::compiler::target::word
+    Thread_suspend_state_await_async_entry_point_offset = 1592;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_init_async_entry_point_offset = 1584;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_entry_point_offset = 1600;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 1608;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_handle_exception_entry_point_offset = 1616;
+static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word Thread_top_offset = 96;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 32;
@@ -2201,13 +2280,13 @@
     64;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1632;
+    1680;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 1640;
-static constexpr dart::compiler::target::word Thread_random_offset = 1672;
+    Thread_callback_stack_return_offset = 1688;
+static constexpr dart::compiler::target::word Thread_random_offset = 1720;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 632;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1680;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1728;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -2302,9 +2381,9 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        1424, 1432, 1440, 1448, 1456, 1464, 1472, 1480, 1488, 1496, 1504,
-        1512, 1520, 1528, 1536, -1,   -1,   -1,   -1,   1544, 1552, -1,
-        -1,   1560, 1568, 1576, -1,   -1,   -1,   -1,   -1,   -1};
+        1432, 1440, 1448, 1456, 1464, 1472, 1480, 1488, 1496, 1504, 1512,
+        1520, 1528, 1536, 1544, -1,   -1,   -1,   -1,   1552, 1560, -1,
+        -1,   1568, 1576, 1584, -1,   -1,   -1,   -1,   -1,   -1};
 static constexpr dart::compiler::target::word AbstractType_InstanceSize = 24;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_header_size = 24;
@@ -2377,6 +2456,7 @@
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
     32;
 static constexpr dart::compiler::target::word StackTrace_InstanceSize = 40;
+static constexpr dart::compiler::target::word SuspendState_HeaderSize = 48;
 static constexpr dart::compiler::target::word String_InstanceSize = 16;
 static constexpr dart::compiler::target::word SubtypeTestCache_InstanceSize =
     16;
@@ -2630,11 +2710,20 @@
 static constexpr dart::compiler::target::word String_length_offset = 8;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
+    SuspendState_error_callback_offset = 32;
+static constexpr dart::compiler::target::word SuspendState_frame_size_offset =
+    8;
+static constexpr dart::compiler::target::word SuspendState_future_offset = 24;
+static constexpr dart::compiler::target::word SuspendState_payload_offset = 40;
+static constexpr dart::compiler::target::word SuspendState_pc_offset = 16;
+static constexpr dart::compiler::target::word
+    SuspendState_then_callback_offset = 28;
+static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 736;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1512;
+    1560;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1520;
+    1568;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
@@ -2658,7 +2747,7 @@
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 376;
 static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1592;
+    1640;
 static constexpr dart::compiler::target::word
     Thread_auto_scope_native_wrapper_entry_point_offset = 664;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 216;
@@ -2669,13 +2758,13 @@
     Thread_call_to_runtime_entry_point_offset = 528;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 256;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1632;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1680;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 1600;
+    Thread_double_truncate_round_supported_offset = 1648;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 1640;
+    Thread_service_extension_stream_offset = 1688;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     608;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 432;
@@ -2691,7 +2780,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1552;
+    1600;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
@@ -2713,14 +2802,14 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 728;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1528;
+    1576;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1584;
+    1632;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word Thread_isolate_group_offset =
-    1648;
+    1696;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     128;
 static constexpr dart::compiler::target::word
@@ -2762,11 +2851,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 200;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 672;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1536;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1584;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1544;
+    Thread_saved_shadow_call_stack_offset = 1592;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1560;
+    1608;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
@@ -2787,6 +2876,16 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     152;
 static constexpr dart::compiler::target::word
+    Thread_suspend_state_await_async_entry_point_offset = 1528;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_init_async_entry_point_offset = 1520;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_entry_point_offset = 1536;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 1544;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_handle_exception_entry_point_offset = 1552;
+static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word Thread_top_offset = 96;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 32;
@@ -2801,13 +2900,13 @@
     64;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1568;
+    1616;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 1576;
-static constexpr dart::compiler::target::word Thread_random_offset = 1608;
+    Thread_callback_stack_return_offset = 1624;
+static constexpr dart::compiler::target::word Thread_random_offset = 1656;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 632;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1616;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1664;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -2902,8 +3001,8 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        1424, 1432, 1440, 1448, -1,   -1,   1456, 1464,
-        1472, 1480, 1488, -1,   1496, 1504, -1,   -1};
+        1432, 1440, 1448, 1456, -1,   -1,   1464, 1472,
+        1480, 1488, 1496, -1,   1504, 1512, -1,   -1};
 static constexpr dart::compiler::target::word AbstractType_InstanceSize = 24;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_header_size = 16;
@@ -2976,6 +3075,7 @@
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
     32;
 static constexpr dart::compiler::target::word StackTrace_InstanceSize = 24;
+static constexpr dart::compiler::target::word SuspendState_HeaderSize = 40;
 static constexpr dart::compiler::target::word String_InstanceSize = 16;
 static constexpr dart::compiler::target::word SubtypeTestCache_InstanceSize =
     16;
@@ -3229,11 +3329,20 @@
 static constexpr dart::compiler::target::word String_length_offset = 8;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
+    SuspendState_error_callback_offset = 32;
+static constexpr dart::compiler::target::word SuspendState_frame_size_offset =
+    8;
+static constexpr dart::compiler::target::word SuspendState_future_offset = 24;
+static constexpr dart::compiler::target::word SuspendState_payload_offset = 40;
+static constexpr dart::compiler::target::word SuspendState_pc_offset = 16;
+static constexpr dart::compiler::target::word
+    SuspendState_then_callback_offset = 28;
+static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 736;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1576;
+    1624;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1584;
+    1632;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
@@ -3257,7 +3366,7 @@
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 376;
 static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1656;
+    1704;
 static constexpr dart::compiler::target::word
     Thread_auto_scope_native_wrapper_entry_point_offset = 664;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 216;
@@ -3268,13 +3377,13 @@
     Thread_call_to_runtime_entry_point_offset = 528;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 256;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1696;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1744;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 1664;
+    Thread_double_truncate_round_supported_offset = 1712;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 1704;
+    Thread_service_extension_stream_offset = 1752;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     608;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 432;
@@ -3290,7 +3399,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1616;
+    1664;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
@@ -3312,14 +3421,14 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 728;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1592;
+    1640;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1648;
+    1696;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word Thread_isolate_group_offset =
-    1712;
+    1760;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     128;
 static constexpr dart::compiler::target::word
@@ -3361,11 +3470,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 200;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 672;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1600;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1648;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1608;
+    Thread_saved_shadow_call_stack_offset = 1656;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1624;
+    1672;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
@@ -3386,6 +3495,16 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     152;
 static constexpr dart::compiler::target::word
+    Thread_suspend_state_await_async_entry_point_offset = 1592;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_init_async_entry_point_offset = 1584;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_entry_point_offset = 1600;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 1608;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_handle_exception_entry_point_offset = 1616;
+static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word Thread_top_offset = 96;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 32;
@@ -3400,13 +3519,13 @@
     64;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1632;
+    1680;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 1640;
-static constexpr dart::compiler::target::word Thread_random_offset = 1672;
+    Thread_callback_stack_return_offset = 1688;
+static constexpr dart::compiler::target::word Thread_random_offset = 1720;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 632;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1680;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1728;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -3501,9 +3620,9 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        1424, 1432, 1440, 1448, 1456, 1464, 1472, 1480, 1488, 1496, 1504,
-        1512, 1520, 1528, 1536, -1,   -1,   -1,   -1,   1544, 1552, -1,
-        -1,   1560, 1568, 1576, -1,   -1,   -1,   -1,   -1,   -1};
+        1432, 1440, 1448, 1456, 1464, 1472, 1480, 1488, 1496, 1504, 1512,
+        1520, 1528, 1536, 1544, -1,   -1,   -1,   -1,   1552, 1560, -1,
+        -1,   1568, 1576, 1584, -1,   -1,   -1,   -1,   -1,   -1};
 static constexpr dart::compiler::target::word AbstractType_InstanceSize = 24;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_header_size = 16;
@@ -3576,6 +3695,7 @@
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
     32;
 static constexpr dart::compiler::target::word StackTrace_InstanceSize = 24;
+static constexpr dart::compiler::target::word SuspendState_HeaderSize = 40;
 static constexpr dart::compiler::target::word String_InstanceSize = 16;
 static constexpr dart::compiler::target::word SubtypeTestCache_InstanceSize =
     16;
@@ -3828,11 +3948,20 @@
 static constexpr dart::compiler::target::word String_length_offset = 4;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 4;
 static constexpr dart::compiler::target::word
+    SuspendState_error_callback_offset = 20;
+static constexpr dart::compiler::target::word SuspendState_frame_size_offset =
+    4;
+static constexpr dart::compiler::target::word SuspendState_future_offset = 12;
+static constexpr dart::compiler::target::word SuspendState_payload_offset = 24;
+static constexpr dart::compiler::target::word SuspendState_pc_offset = 8;
+static constexpr dart::compiler::target::word
+    SuspendState_then_callback_offset = 16;
+static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 380;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    796;
+    820;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    800;
+    824;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 272;
 static constexpr dart::compiler::target::word
@@ -3855,7 +3984,7 @@
     Thread_allocate_object_slow_entry_point_offset = 296;
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 200;
-static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 836;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 860;
 static constexpr dart::compiler::target::word
     Thread_auto_scope_native_wrapper_entry_point_offset = 344;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 120;
@@ -3866,13 +3995,13 @@
     Thread_call_to_runtime_entry_point_offset = 276;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 140;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 864;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 888;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 44;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 840;
+    Thread_double_truncate_round_supported_offset = 864;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 868;
+    Thread_service_extension_stream_offset = 892;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     316;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 228;
@@ -3888,7 +4017,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 252;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    816;
+    840;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 256;
 static constexpr dart::compiler::target::word
@@ -3910,13 +4039,13 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 376;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    804;
+    828;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 136;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    832;
+    856;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 40;
-static constexpr dart::compiler::target::word Thread_isolate_group_offset = 872;
+static constexpr dart::compiler::target::word Thread_isolate_group_offset = 896;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     64;
 static constexpr dart::compiler::target::word
@@ -3958,11 +4087,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 112;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 348;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 808;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 832;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 812;
+    Thread_saved_shadow_call_stack_offset = 836;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    820;
+    844;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 244;
 static constexpr dart::compiler::target::word
@@ -3983,6 +4112,16 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     76;
 static constexpr dart::compiler::target::word
+    Thread_suspend_state_await_async_entry_point_offset = 804;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_init_async_entry_point_offset = 800;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_entry_point_offset = 808;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 812;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_handle_exception_entry_point_offset = 816;
+static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 72;
 static constexpr dart::compiler::target::word Thread_top_offset = 48;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 16;
@@ -3996,13 +4135,13 @@
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     32;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 36;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 824;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 848;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 828;
-static constexpr dart::compiler::target::word Thread_random_offset = 848;
+    Thread_callback_stack_return_offset = 852;
+static constexpr dart::compiler::target::word Thread_random_offset = 872;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 328;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 856;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 880;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -4095,9 +4234,9 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        -1,  -1,  -1, -1, -1, 724, 728, 732, -1,  -1,  736,
-        740, 744, -1, -1, -1, 748, 752, 756, 760, 764, 768,
-        772, 776, -1, -1, -1, -1,  780, 784, 788, 792};
+        -1,  -1,  -1, -1, -1, 728, 732, 736, -1,  -1,  740,
+        744, 748, -1, -1, -1, 752, 756, 760, 764, 768, 772,
+        776, 780, -1, -1, -1, -1,  784, 788, 792, 796};
 static constexpr dart::compiler::target::word AbstractType_InstanceSize = 12;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 8;
 static constexpr dart::compiler::target::word Array_header_size = 12;
@@ -4170,6 +4309,7 @@
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
     16;
 static constexpr dart::compiler::target::word StackTrace_InstanceSize = 20;
+static constexpr dart::compiler::target::word SuspendState_HeaderSize = 24;
 static constexpr dart::compiler::target::word String_InstanceSize = 12;
 static constexpr dart::compiler::target::word SubtypeTestCache_InstanceSize = 8;
 static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 20;
@@ -4425,11 +4565,20 @@
 static constexpr dart::compiler::target::word String_length_offset = 8;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
+    SuspendState_error_callback_offset = 40;
+static constexpr dart::compiler::target::word SuspendState_frame_size_offset =
+    8;
+static constexpr dart::compiler::target::word SuspendState_future_offset = 24;
+static constexpr dart::compiler::target::word SuspendState_payload_offset = 48;
+static constexpr dart::compiler::target::word SuspendState_pc_offset = 16;
+static constexpr dart::compiler::target::word
+    SuspendState_then_callback_offset = 32;
+static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 736;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1568;
+    1616;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1576;
+    1624;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
@@ -4453,7 +4602,7 @@
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 376;
 static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1648;
+    1696;
 static constexpr dart::compiler::target::word
     Thread_auto_scope_native_wrapper_entry_point_offset = 664;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 216;
@@ -4464,13 +4613,13 @@
     Thread_call_to_runtime_entry_point_offset = 528;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 256;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1688;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1736;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 1656;
+    Thread_double_truncate_round_supported_offset = 1704;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 1696;
+    Thread_service_extension_stream_offset = 1744;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     608;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 432;
@@ -4486,7 +4635,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1608;
+    1656;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
@@ -4508,14 +4657,14 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 728;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1584;
+    1632;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1640;
+    1688;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word Thread_isolate_group_offset =
-    1704;
+    1752;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     128;
 static constexpr dart::compiler::target::word
@@ -4557,11 +4706,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 200;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 672;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1592;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1640;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1600;
+    Thread_saved_shadow_call_stack_offset = 1648;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1616;
+    1664;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
@@ -4582,6 +4731,16 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     152;
 static constexpr dart::compiler::target::word
+    Thread_suspend_state_await_async_entry_point_offset = 1584;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_init_async_entry_point_offset = 1576;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_entry_point_offset = 1592;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 1600;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_handle_exception_entry_point_offset = 1608;
+static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word Thread_top_offset = 96;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 32;
@@ -4596,13 +4755,13 @@
     64;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1624;
+    1672;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 1632;
-static constexpr dart::compiler::target::word Thread_random_offset = 1664;
+    Thread_callback_stack_return_offset = 1680;
+static constexpr dart::compiler::target::word Thread_random_offset = 1712;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 632;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1672;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1720;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -4697,9 +4856,9 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        -1,   -1,   -1, -1, -1, 1424, 1432, 1440, -1,   -1,   1448,
-        1456, 1464, -1, -1, -1, 1472, 1480, 1488, 1496, 1504, 1512,
-        1520, 1528, -1, -1, -1, -1,   1536, 1544, 1552, 1560};
+        -1,   -1,   -1, -1, -1, 1432, 1440, 1448, -1,   -1,   1456,
+        1464, 1472, -1, -1, -1, 1480, 1488, 1496, 1504, 1512, 1520,
+        1528, 1536, -1, -1, -1, -1,   1544, 1552, 1560, 1568};
 static constexpr dart::compiler::target::word AbstractType_InstanceSize = 24;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_header_size = 24;
@@ -4772,6 +4931,7 @@
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
     32;
 static constexpr dart::compiler::target::word StackTrace_InstanceSize = 40;
+static constexpr dart::compiler::target::word SuspendState_HeaderSize = 48;
 static constexpr dart::compiler::target::word String_InstanceSize = 16;
 static constexpr dart::compiler::target::word SubtypeTestCache_InstanceSize =
     16;
@@ -5020,11 +5180,20 @@
 static constexpr dart::compiler::target::word String_length_offset = 4;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 4;
 static constexpr dart::compiler::target::word
+    SuspendState_error_callback_offset = 20;
+static constexpr dart::compiler::target::word SuspendState_frame_size_offset =
+    4;
+static constexpr dart::compiler::target::word SuspendState_future_offset = 12;
+static constexpr dart::compiler::target::word SuspendState_payload_offset = 24;
+static constexpr dart::compiler::target::word SuspendState_pc_offset = 8;
+static constexpr dart::compiler::target::word
+    SuspendState_then_callback_offset = 16;
+static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 380;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    756;
+    780;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    760;
+    784;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 272;
 static constexpr dart::compiler::target::word
@@ -5047,7 +5216,7 @@
     Thread_allocate_object_slow_entry_point_offset = 296;
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 200;
-static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 796;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 820;
 static constexpr dart::compiler::target::word
     Thread_auto_scope_native_wrapper_entry_point_offset = 344;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 120;
@@ -5058,13 +5227,13 @@
     Thread_call_to_runtime_entry_point_offset = 276;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 140;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 824;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 848;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 44;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 800;
+    Thread_double_truncate_round_supported_offset = 824;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 828;
+    Thread_service_extension_stream_offset = 852;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     316;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 228;
@@ -5080,7 +5249,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 252;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    776;
+    800;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 256;
 static constexpr dart::compiler::target::word
@@ -5102,13 +5271,13 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 376;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    764;
+    788;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 136;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    792;
+    816;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 40;
-static constexpr dart::compiler::target::word Thread_isolate_group_offset = 832;
+static constexpr dart::compiler::target::word Thread_isolate_group_offset = 856;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     64;
 static constexpr dart::compiler::target::word
@@ -5150,11 +5319,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 112;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 348;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 768;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 792;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 772;
+    Thread_saved_shadow_call_stack_offset = 796;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    780;
+    804;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 244;
 static constexpr dart::compiler::target::word
@@ -5175,6 +5344,16 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     76;
 static constexpr dart::compiler::target::word
+    Thread_suspend_state_await_async_entry_point_offset = 764;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_init_async_entry_point_offset = 760;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_entry_point_offset = 768;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 772;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_handle_exception_entry_point_offset = 776;
+static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 72;
 static constexpr dart::compiler::target::word Thread_top_offset = 48;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 16;
@@ -5188,13 +5367,13 @@
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     32;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 36;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 784;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 808;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 788;
-static constexpr dart::compiler::target::word Thread_random_offset = 808;
+    Thread_callback_stack_return_offset = 812;
+static constexpr dart::compiler::target::word Thread_random_offset = 832;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 328;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 816;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 840;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -5287,7 +5466,7 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        724, 728, 732, 736, 740, -1, 744, -1, 748, 752, -1, -1, -1, -1, -1, -1};
+        728, 732, 736, 740, 744, -1, 748, -1, 752, 756, -1, -1, -1, -1, -1, -1};
 static constexpr dart::compiler::target::word AbstractType_InstanceSize = 12;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 8;
 static constexpr dart::compiler::target::word Array_header_size = 12;
@@ -5360,6 +5539,7 @@
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
     16;
 static constexpr dart::compiler::target::word StackTrace_InstanceSize = 20;
+static constexpr dart::compiler::target::word SuspendState_HeaderSize = 24;
 static constexpr dart::compiler::target::word String_InstanceSize = 12;
 static constexpr dart::compiler::target::word SubtypeTestCache_InstanceSize = 8;
 static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 20;
@@ -5609,11 +5789,20 @@
 static constexpr dart::compiler::target::word String_length_offset = 8;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
+    SuspendState_error_callback_offset = 40;
+static constexpr dart::compiler::target::word SuspendState_frame_size_offset =
+    8;
+static constexpr dart::compiler::target::word SuspendState_future_offset = 24;
+static constexpr dart::compiler::target::word SuspendState_payload_offset = 48;
+static constexpr dart::compiler::target::word SuspendState_pc_offset = 16;
+static constexpr dart::compiler::target::word
+    SuspendState_then_callback_offset = 32;
+static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 736;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1512;
+    1560;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1520;
+    1568;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
@@ -5637,7 +5826,7 @@
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 376;
 static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1592;
+    1640;
 static constexpr dart::compiler::target::word
     Thread_auto_scope_native_wrapper_entry_point_offset = 664;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 216;
@@ -5648,13 +5837,13 @@
     Thread_call_to_runtime_entry_point_offset = 528;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 256;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1632;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1680;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 1600;
+    Thread_double_truncate_round_supported_offset = 1648;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 1640;
+    Thread_service_extension_stream_offset = 1688;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     608;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 432;
@@ -5670,7 +5859,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1552;
+    1600;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
@@ -5692,14 +5881,14 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 728;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1528;
+    1576;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1584;
+    1632;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word Thread_isolate_group_offset =
-    1648;
+    1696;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     128;
 static constexpr dart::compiler::target::word
@@ -5741,11 +5930,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 200;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 672;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1536;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1584;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1544;
+    Thread_saved_shadow_call_stack_offset = 1592;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1560;
+    1608;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
@@ -5766,6 +5955,16 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     152;
 static constexpr dart::compiler::target::word
+    Thread_suspend_state_await_async_entry_point_offset = 1528;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_init_async_entry_point_offset = 1520;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_entry_point_offset = 1536;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 1544;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_handle_exception_entry_point_offset = 1552;
+static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word Thread_top_offset = 96;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 32;
@@ -5780,13 +5979,13 @@
     64;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1568;
+    1616;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 1576;
-static constexpr dart::compiler::target::word Thread_random_offset = 1608;
+    Thread_callback_stack_return_offset = 1624;
+static constexpr dart::compiler::target::word Thread_random_offset = 1656;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 632;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1616;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1664;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -5881,8 +6080,8 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        1424, 1432, 1440, 1448, -1,   -1,   1456, 1464,
-        1472, 1480, 1488, -1,   1496, 1504, -1,   -1};
+        1432, 1440, 1448, 1456, -1,   -1,   1464, 1472,
+        1480, 1488, 1496, -1,   1504, 1512, -1,   -1};
 static constexpr dart::compiler::target::word AbstractType_InstanceSize = 24;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_header_size = 24;
@@ -5955,6 +6154,7 @@
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
     32;
 static constexpr dart::compiler::target::word StackTrace_InstanceSize = 40;
+static constexpr dart::compiler::target::word SuspendState_HeaderSize = 48;
 static constexpr dart::compiler::target::word String_InstanceSize = 16;
 static constexpr dart::compiler::target::word SubtypeTestCache_InstanceSize =
     16;
@@ -6201,11 +6401,20 @@
 static constexpr dart::compiler::target::word String_length_offset = 4;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 4;
 static constexpr dart::compiler::target::word
+    SuspendState_error_callback_offset = 20;
+static constexpr dart::compiler::target::word SuspendState_frame_size_offset =
+    4;
+static constexpr dart::compiler::target::word SuspendState_future_offset = 12;
+static constexpr dart::compiler::target::word SuspendState_payload_offset = 24;
+static constexpr dart::compiler::target::word SuspendState_pc_offset = 8;
+static constexpr dart::compiler::target::word
+    SuspendState_then_callback_offset = 16;
+static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 380;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    724;
+    748;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    728;
+    752;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 272;
 static constexpr dart::compiler::target::word
@@ -6228,7 +6437,7 @@
     Thread_allocate_object_slow_entry_point_offset = 296;
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 200;
-static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 764;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 788;
 static constexpr dart::compiler::target::word
     Thread_auto_scope_native_wrapper_entry_point_offset = 344;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 120;
@@ -6239,13 +6448,13 @@
     Thread_call_to_runtime_entry_point_offset = 276;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 140;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 792;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 816;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 44;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 768;
+    Thread_double_truncate_round_supported_offset = 792;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 796;
+    Thread_service_extension_stream_offset = 820;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     316;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 228;
@@ -6261,7 +6470,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 252;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    744;
+    768;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 256;
 static constexpr dart::compiler::target::word
@@ -6283,13 +6492,13 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 376;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    732;
+    756;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 136;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    760;
+    784;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 40;
-static constexpr dart::compiler::target::word Thread_isolate_group_offset = 800;
+static constexpr dart::compiler::target::word Thread_isolate_group_offset = 824;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     64;
 static constexpr dart::compiler::target::word
@@ -6331,11 +6540,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 112;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 348;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 736;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 760;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 740;
+    Thread_saved_shadow_call_stack_offset = 764;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    748;
+    772;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 244;
 static constexpr dart::compiler::target::word
@@ -6356,6 +6565,16 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     76;
 static constexpr dart::compiler::target::word
+    Thread_suspend_state_await_async_entry_point_offset = 732;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_init_async_entry_point_offset = 728;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_entry_point_offset = 736;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 740;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_handle_exception_entry_point_offset = 744;
+static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 72;
 static constexpr dart::compiler::target::word Thread_top_offset = 48;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 16;
@@ -6369,13 +6588,13 @@
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     32;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 36;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 752;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 776;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 756;
-static constexpr dart::compiler::target::word Thread_random_offset = 776;
+    Thread_callback_stack_return_offset = 780;
+static constexpr dart::compiler::target::word Thread_random_offset = 800;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 328;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 784;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 808;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -6538,6 +6757,7 @@
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
     16;
 static constexpr dart::compiler::target::word StackTrace_InstanceSize = 20;
+static constexpr dart::compiler::target::word SuspendState_HeaderSize = 24;
 static constexpr dart::compiler::target::word String_InstanceSize = 12;
 static constexpr dart::compiler::target::word SubtypeTestCache_InstanceSize = 8;
 static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 20;
@@ -6787,11 +7007,20 @@
 static constexpr dart::compiler::target::word String_length_offset = 8;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
+    SuspendState_error_callback_offset = 40;
+static constexpr dart::compiler::target::word SuspendState_frame_size_offset =
+    8;
+static constexpr dart::compiler::target::word SuspendState_future_offset = 24;
+static constexpr dart::compiler::target::word SuspendState_payload_offset = 48;
+static constexpr dart::compiler::target::word SuspendState_pc_offset = 16;
+static constexpr dart::compiler::target::word
+    SuspendState_then_callback_offset = 32;
+static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 736;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1576;
+    1624;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1584;
+    1632;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
@@ -6815,7 +7044,7 @@
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 376;
 static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1656;
+    1704;
 static constexpr dart::compiler::target::word
     Thread_auto_scope_native_wrapper_entry_point_offset = 664;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 216;
@@ -6826,13 +7055,13 @@
     Thread_call_to_runtime_entry_point_offset = 528;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 256;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1696;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1744;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 1664;
+    Thread_double_truncate_round_supported_offset = 1712;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 1704;
+    Thread_service_extension_stream_offset = 1752;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     608;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 432;
@@ -6848,7 +7077,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1616;
+    1664;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
@@ -6870,14 +7099,14 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 728;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1592;
+    1640;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1648;
+    1696;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word Thread_isolate_group_offset =
-    1712;
+    1760;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     128;
 static constexpr dart::compiler::target::word
@@ -6919,11 +7148,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 200;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 672;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1600;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1648;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1608;
+    Thread_saved_shadow_call_stack_offset = 1656;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1624;
+    1672;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
@@ -6944,6 +7173,16 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     152;
 static constexpr dart::compiler::target::word
+    Thread_suspend_state_await_async_entry_point_offset = 1592;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_init_async_entry_point_offset = 1584;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_entry_point_offset = 1600;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 1608;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_handle_exception_entry_point_offset = 1616;
+static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word Thread_top_offset = 96;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 32;
@@ -6958,13 +7197,13 @@
     64;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1632;
+    1680;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 1640;
-static constexpr dart::compiler::target::word Thread_random_offset = 1672;
+    Thread_callback_stack_return_offset = 1688;
+static constexpr dart::compiler::target::word Thread_random_offset = 1720;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 632;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1680;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1728;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -7059,9 +7298,9 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        1424, 1432, 1440, 1448, 1456, 1464, 1472, 1480, 1488, 1496, 1504,
-        1512, 1520, 1528, 1536, -1,   -1,   -1,   -1,   1544, 1552, -1,
-        -1,   1560, 1568, 1576, -1,   -1,   -1,   -1,   -1,   -1};
+        1432, 1440, 1448, 1456, 1464, 1472, 1480, 1488, 1496, 1504, 1512,
+        1520, 1528, 1536, 1544, -1,   -1,   -1,   -1,   1552, 1560, -1,
+        -1,   1568, 1576, 1584, -1,   -1,   -1,   -1,   -1,   -1};
 static constexpr dart::compiler::target::word AbstractType_InstanceSize = 24;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_header_size = 24;
@@ -7134,6 +7373,7 @@
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
     32;
 static constexpr dart::compiler::target::word StackTrace_InstanceSize = 40;
+static constexpr dart::compiler::target::word SuspendState_HeaderSize = 48;
 static constexpr dart::compiler::target::word String_InstanceSize = 16;
 static constexpr dart::compiler::target::word SubtypeTestCache_InstanceSize =
     16;
@@ -7381,11 +7621,20 @@
 static constexpr dart::compiler::target::word String_length_offset = 8;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
+    SuspendState_error_callback_offset = 32;
+static constexpr dart::compiler::target::word SuspendState_frame_size_offset =
+    8;
+static constexpr dart::compiler::target::word SuspendState_future_offset = 24;
+static constexpr dart::compiler::target::word SuspendState_payload_offset = 40;
+static constexpr dart::compiler::target::word SuspendState_pc_offset = 16;
+static constexpr dart::compiler::target::word
+    SuspendState_then_callback_offset = 28;
+static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 736;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1512;
+    1560;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1520;
+    1568;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
@@ -7409,7 +7658,7 @@
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 376;
 static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1592;
+    1640;
 static constexpr dart::compiler::target::word
     Thread_auto_scope_native_wrapper_entry_point_offset = 664;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 216;
@@ -7420,13 +7669,13 @@
     Thread_call_to_runtime_entry_point_offset = 528;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 256;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1632;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1680;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 1600;
+    Thread_double_truncate_round_supported_offset = 1648;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 1640;
+    Thread_service_extension_stream_offset = 1688;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     608;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 432;
@@ -7442,7 +7691,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1552;
+    1600;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
@@ -7464,14 +7713,14 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 728;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1528;
+    1576;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1584;
+    1632;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word Thread_isolate_group_offset =
-    1648;
+    1696;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     128;
 static constexpr dart::compiler::target::word
@@ -7513,11 +7762,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 200;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 672;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1536;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1584;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1544;
+    Thread_saved_shadow_call_stack_offset = 1592;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1560;
+    1608;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
@@ -7538,6 +7787,16 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     152;
 static constexpr dart::compiler::target::word
+    Thread_suspend_state_await_async_entry_point_offset = 1528;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_init_async_entry_point_offset = 1520;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_entry_point_offset = 1536;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 1544;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_handle_exception_entry_point_offset = 1552;
+static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word Thread_top_offset = 96;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 32;
@@ -7552,13 +7811,13 @@
     64;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1568;
+    1616;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 1576;
-static constexpr dart::compiler::target::word Thread_random_offset = 1608;
+    Thread_callback_stack_return_offset = 1624;
+static constexpr dart::compiler::target::word Thread_random_offset = 1656;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 632;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1616;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1664;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -7653,8 +7912,8 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        1424, 1432, 1440, 1448, -1,   -1,   1456, 1464,
-        1472, 1480, 1488, -1,   1496, 1504, -1,   -1};
+        1432, 1440, 1448, 1456, -1,   -1,   1464, 1472,
+        1480, 1488, 1496, -1,   1504, 1512, -1,   -1};
 static constexpr dart::compiler::target::word AbstractType_InstanceSize = 24;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_header_size = 16;
@@ -7727,6 +7986,7 @@
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
     32;
 static constexpr dart::compiler::target::word StackTrace_InstanceSize = 24;
+static constexpr dart::compiler::target::word SuspendState_HeaderSize = 40;
 static constexpr dart::compiler::target::word String_InstanceSize = 16;
 static constexpr dart::compiler::target::word SubtypeTestCache_InstanceSize =
     16;
@@ -7974,11 +8234,20 @@
 static constexpr dart::compiler::target::word String_length_offset = 8;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
+    SuspendState_error_callback_offset = 32;
+static constexpr dart::compiler::target::word SuspendState_frame_size_offset =
+    8;
+static constexpr dart::compiler::target::word SuspendState_future_offset = 24;
+static constexpr dart::compiler::target::word SuspendState_payload_offset = 40;
+static constexpr dart::compiler::target::word SuspendState_pc_offset = 16;
+static constexpr dart::compiler::target::word
+    SuspendState_then_callback_offset = 28;
+static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 736;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1576;
+    1624;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1584;
+    1632;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
@@ -8002,7 +8271,7 @@
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 376;
 static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1656;
+    1704;
 static constexpr dart::compiler::target::word
     Thread_auto_scope_native_wrapper_entry_point_offset = 664;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 216;
@@ -8013,13 +8282,13 @@
     Thread_call_to_runtime_entry_point_offset = 528;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 256;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1696;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1744;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 1664;
+    Thread_double_truncate_round_supported_offset = 1712;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 1704;
+    Thread_service_extension_stream_offset = 1752;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     608;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 432;
@@ -8035,7 +8304,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1616;
+    1664;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
@@ -8057,14 +8326,14 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 728;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1592;
+    1640;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1648;
+    1696;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word Thread_isolate_group_offset =
-    1712;
+    1760;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     128;
 static constexpr dart::compiler::target::word
@@ -8106,11 +8375,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 200;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 672;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1600;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1648;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1608;
+    Thread_saved_shadow_call_stack_offset = 1656;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1624;
+    1672;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
@@ -8131,6 +8400,16 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     152;
 static constexpr dart::compiler::target::word
+    Thread_suspend_state_await_async_entry_point_offset = 1592;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_init_async_entry_point_offset = 1584;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_entry_point_offset = 1600;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 1608;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_handle_exception_entry_point_offset = 1616;
+static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word Thread_top_offset = 96;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 32;
@@ -8145,13 +8424,13 @@
     64;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1632;
+    1680;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 1640;
-static constexpr dart::compiler::target::word Thread_random_offset = 1672;
+    Thread_callback_stack_return_offset = 1688;
+static constexpr dart::compiler::target::word Thread_random_offset = 1720;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 632;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1680;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1728;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -8246,9 +8525,9 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        1424, 1432, 1440, 1448, 1456, 1464, 1472, 1480, 1488, 1496, 1504,
-        1512, 1520, 1528, 1536, -1,   -1,   -1,   -1,   1544, 1552, -1,
-        -1,   1560, 1568, 1576, -1,   -1,   -1,   -1,   -1,   -1};
+        1432, 1440, 1448, 1456, 1464, 1472, 1480, 1488, 1496, 1504, 1512,
+        1520, 1528, 1536, 1544, -1,   -1,   -1,   -1,   1552, 1560, -1,
+        -1,   1568, 1576, 1584, -1,   -1,   -1,   -1,   -1,   -1};
 static constexpr dart::compiler::target::word AbstractType_InstanceSize = 24;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_header_size = 16;
@@ -8321,6 +8600,7 @@
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
     32;
 static constexpr dart::compiler::target::word StackTrace_InstanceSize = 24;
+static constexpr dart::compiler::target::word SuspendState_HeaderSize = 40;
 static constexpr dart::compiler::target::word String_InstanceSize = 16;
 static constexpr dart::compiler::target::word SubtypeTestCache_InstanceSize =
     16;
@@ -8567,11 +8847,20 @@
 static constexpr dart::compiler::target::word String_length_offset = 4;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 4;
 static constexpr dart::compiler::target::word
+    SuspendState_error_callback_offset = 20;
+static constexpr dart::compiler::target::word SuspendState_frame_size_offset =
+    4;
+static constexpr dart::compiler::target::word SuspendState_future_offset = 12;
+static constexpr dart::compiler::target::word SuspendState_payload_offset = 24;
+static constexpr dart::compiler::target::word SuspendState_pc_offset = 8;
+static constexpr dart::compiler::target::word
+    SuspendState_then_callback_offset = 16;
+static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 380;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    796;
+    820;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    800;
+    824;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 272;
 static constexpr dart::compiler::target::word
@@ -8594,7 +8883,7 @@
     Thread_allocate_object_slow_entry_point_offset = 296;
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 200;
-static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 836;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 860;
 static constexpr dart::compiler::target::word
     Thread_auto_scope_native_wrapper_entry_point_offset = 344;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 120;
@@ -8605,13 +8894,13 @@
     Thread_call_to_runtime_entry_point_offset = 276;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 140;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 864;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 888;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 44;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 840;
+    Thread_double_truncate_round_supported_offset = 864;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 868;
+    Thread_service_extension_stream_offset = 892;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     316;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 228;
@@ -8627,7 +8916,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 252;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    816;
+    840;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 256;
 static constexpr dart::compiler::target::word
@@ -8649,13 +8938,13 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 376;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    804;
+    828;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 136;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    832;
+    856;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 40;
-static constexpr dart::compiler::target::word Thread_isolate_group_offset = 872;
+static constexpr dart::compiler::target::word Thread_isolate_group_offset = 896;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     64;
 static constexpr dart::compiler::target::word
@@ -8697,11 +8986,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 112;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 348;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 808;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 832;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 812;
+    Thread_saved_shadow_call_stack_offset = 836;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    820;
+    844;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 244;
 static constexpr dart::compiler::target::word
@@ -8722,6 +9011,16 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     76;
 static constexpr dart::compiler::target::word
+    Thread_suspend_state_await_async_entry_point_offset = 804;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_init_async_entry_point_offset = 800;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_entry_point_offset = 808;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 812;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_handle_exception_entry_point_offset = 816;
+static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 72;
 static constexpr dart::compiler::target::word Thread_top_offset = 48;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 16;
@@ -8735,13 +9034,13 @@
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     32;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 36;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 824;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 848;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 828;
-static constexpr dart::compiler::target::word Thread_random_offset = 848;
+    Thread_callback_stack_return_offset = 852;
+static constexpr dart::compiler::target::word Thread_random_offset = 872;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 328;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 856;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 880;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -8834,9 +9133,9 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        -1,  -1,  -1, -1, -1, 724, 728, 732, -1,  -1,  736,
-        740, 744, -1, -1, -1, 748, 752, 756, 760, 764, 768,
-        772, 776, -1, -1, -1, -1,  780, 784, 788, 792};
+        -1,  -1,  -1, -1, -1, 728, 732, 736, -1,  -1,  740,
+        744, 748, -1, -1, -1, 752, 756, 760, 764, 768, 772,
+        776, 780, -1, -1, -1, -1,  784, 788, 792, 796};
 static constexpr dart::compiler::target::word AbstractType_InstanceSize = 12;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 8;
 static constexpr dart::compiler::target::word Array_header_size = 12;
@@ -8909,6 +9208,7 @@
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
     16;
 static constexpr dart::compiler::target::word StackTrace_InstanceSize = 20;
+static constexpr dart::compiler::target::word SuspendState_HeaderSize = 24;
 static constexpr dart::compiler::target::word String_InstanceSize = 12;
 static constexpr dart::compiler::target::word SubtypeTestCache_InstanceSize = 8;
 static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 20;
@@ -9158,11 +9458,20 @@
 static constexpr dart::compiler::target::word String_length_offset = 8;
 static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
+    SuspendState_error_callback_offset = 40;
+static constexpr dart::compiler::target::word SuspendState_frame_size_offset =
+    8;
+static constexpr dart::compiler::target::word SuspendState_future_offset = 24;
+static constexpr dart::compiler::target::word SuspendState_payload_offset = 48;
+static constexpr dart::compiler::target::word SuspendState_pc_offset = 16;
+static constexpr dart::compiler::target::word
+    SuspendState_then_callback_offset = 32;
+static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 736;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1568;
+    1616;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1576;
+    1624;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
@@ -9186,7 +9495,7 @@
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 376;
 static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1648;
+    1696;
 static constexpr dart::compiler::target::word
     Thread_auto_scope_native_wrapper_entry_point_offset = 664;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 216;
@@ -9197,13 +9506,13 @@
     Thread_call_to_runtime_entry_point_offset = 528;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 256;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1688;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1736;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    Thread_double_truncate_round_supported_offset = 1656;
+    Thread_double_truncate_round_supported_offset = 1704;
 static constexpr dart::compiler::target::word
-    Thread_service_extension_stream_offset = 1696;
+    Thread_service_extension_stream_offset = 1744;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     608;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 432;
@@ -9219,7 +9528,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1608;
+    1656;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
@@ -9241,14 +9550,14 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 728;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1584;
+    1632;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1640;
+    1688;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word Thread_isolate_group_offset =
-    1704;
+    1752;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     128;
 static constexpr dart::compiler::target::word
@@ -9290,11 +9599,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 200;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 672;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1592;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1640;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1600;
+    Thread_saved_shadow_call_stack_offset = 1648;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1616;
+    1664;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
@@ -9315,6 +9624,16 @@
 static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
     152;
 static constexpr dart::compiler::target::word
+    Thread_suspend_state_await_async_entry_point_offset = 1584;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_init_async_entry_point_offset = 1576;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_entry_point_offset = 1592;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_return_async_not_future_entry_point_offset = 1600;
+static constexpr dart::compiler::target::word
+    Thread_suspend_state_handle_exception_entry_point_offset = 1608;
+static constexpr dart::compiler::target::word
     Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word Thread_top_offset = 96;
 static constexpr dart::compiler::target::word Thread_top_resource_offset = 32;
@@ -9329,13 +9648,13 @@
     64;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1624;
+    1672;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 1632;
-static constexpr dart::compiler::target::word Thread_random_offset = 1664;
+    Thread_callback_stack_return_offset = 1680;
+static constexpr dart::compiler::target::word Thread_random_offset = 1712;
 static constexpr dart::compiler::target::word
     Thread_jump_to_frame_entry_point_offset = 632;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1672;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1720;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
     0;
 static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -9430,9 +9749,9 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        -1,   -1,   -1, -1, -1, 1424, 1432, 1440, -1,   -1,   1448,
-        1456, 1464, -1, -1, -1, 1472, 1480, 1488, 1496, 1504, 1512,
-        1520, 1528, -1, -1, -1, -1,   1536, 1544, 1552, 1560};
+        -1,   -1,   -1, -1, -1, 1432, 1440, 1448, -1,   -1,   1456,
+        1464, 1472, -1, -1, -1, 1480, 1488, 1496, 1504, 1512, 1520,
+        1528, 1536, -1, -1, -1, -1,   1544, 1552, 1560, 1568};
 static constexpr dart::compiler::target::word AbstractType_InstanceSize = 24;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_header_size = 24;
@@ -9505,6 +9824,7 @@
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
     32;
 static constexpr dart::compiler::target::word StackTrace_InstanceSize = 40;
+static constexpr dart::compiler::target::word SuspendState_HeaderSize = 48;
 static constexpr dart::compiler::target::word String_InstanceSize = 16;
 static constexpr dart::compiler::target::word SubtypeTestCache_InstanceSize =
     16;
@@ -9789,11 +10109,22 @@
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_cache_offset = 4;
 static constexpr dart::compiler::target::word
+    AOT_SuspendState_error_callback_offset = 20;
+static constexpr dart::compiler::target::word
+    AOT_SuspendState_frame_size_offset = 4;
+static constexpr dart::compiler::target::word AOT_SuspendState_future_offset =
+    12;
+static constexpr dart::compiler::target::word AOT_SuspendState_payload_offset =
+    24;
+static constexpr dart::compiler::target::word AOT_SuspendState_pc_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_SuspendState_then_callback_offset = 16;
+static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 380;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 756;
+    AOT_Thread_active_exception_offset = 780;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 760;
+    AOT_Thread_active_stacktrace_offset = 784;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_entry_point_offset = 272;
 static constexpr dart::compiler::target::word
@@ -9817,7 +10148,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 200;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    796;
+    820;
 static constexpr dart::compiler::target::word
     AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 344;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
@@ -9830,13 +10161,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 140;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    824;
+    848;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 44;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_truncate_round_supported_offset = 800;
+    AOT_Thread_double_truncate_round_supported_offset = 824;
 static constexpr dart::compiler::target::word
-    AOT_Thread_service_extension_stream_offset = 828;
+    AOT_Thread_service_extension_stream_offset = 852;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     316;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -9853,7 +10184,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 252;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 776;
+    AOT_Thread_execution_state_offset = 800;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 256;
 static constexpr dart::compiler::target::word
@@ -9875,14 +10206,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 376;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 764;
+    AOT_Thread_global_object_pool_offset = 788;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 136;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 792;
+    AOT_Thread_exit_through_ffi_offset = 816;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 40;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    832;
+    856;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 64;
 static constexpr dart::compiler::target::word
@@ -9926,11 +10257,11 @@
     112;
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 348;
-static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 768;
+static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 792;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 772;
+    AOT_Thread_saved_shadow_call_stack_offset = 796;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 780;
+    AOT_Thread_safepoint_state_offset = 804;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 244;
 static constexpr dart::compiler::target::word
@@ -9952,6 +10283,16 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 76;
 static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_await_async_entry_point_offset = 764;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_init_async_entry_point_offset = 760;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_return_async_entry_point_offset = 768;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 772;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 776;
+static constexpr dart::compiler::target::word
     AOT_Thread_top_exit_frame_info_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_top_offset = 48;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
@@ -9967,14 +10308,14 @@
     AOT_Thread_write_barrier_mask_offset = 32;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 36;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    784;
+    808;
 static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 788;
-static constexpr dart::compiler::target::word AOT_Thread_random_offset = 808;
+    AOT_Thread_callback_stack_return_offset = 812;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 832;
 static constexpr dart::compiler::target::word
     AOT_Thread_jump_to_frame_entry_point_offset = 328;
 static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
-    816;
+    840;
 static constexpr dart::compiler::target::word
     AOT_TsanUtils_setjmp_function_offset = 0;
 static constexpr dart::compiler::target::word
@@ -10087,7 +10428,7 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        724, 728, 732, 736, 740, -1, 744, -1, 748, 752, -1, -1, -1, -1, -1, -1};
+        728, 732, 736, 740, 744, -1, 748, -1, 752, 756, -1, -1, -1, -1, -1, -1};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
     12;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 8;
@@ -10170,6 +10511,7 @@
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 20;
+static constexpr dart::compiler::target::word AOT_SuspendState_HeaderSize = 24;
 static constexpr dart::compiler::target::word AOT_String_InstanceSize = 12;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_InstanceSize = 8;
@@ -10458,11 +10800,22 @@
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
+    AOT_SuspendState_error_callback_offset = 40;
+static constexpr dart::compiler::target::word
+    AOT_SuspendState_frame_size_offset = 8;
+static constexpr dart::compiler::target::word AOT_SuspendState_future_offset =
+    24;
+static constexpr dart::compiler::target::word AOT_SuspendState_payload_offset =
+    48;
+static constexpr dart::compiler::target::word AOT_SuspendState_pc_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_SuspendState_then_callback_offset = 32;
+static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 736;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1512;
+    AOT_Thread_active_exception_offset = 1560;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1520;
+    AOT_Thread_active_stacktrace_offset = 1568;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
@@ -10486,7 +10839,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 376;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1592;
+    1640;
 static constexpr dart::compiler::target::word
     AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 664;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
@@ -10499,13 +10852,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 256;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1632;
+    1680;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_truncate_round_supported_offset = 1600;
+    AOT_Thread_double_truncate_round_supported_offset = 1648;
 static constexpr dart::compiler::target::word
-    AOT_Thread_service_extension_stream_offset = 1640;
+    AOT_Thread_service_extension_stream_offset = 1688;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     608;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -10522,7 +10875,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1552;
+    AOT_Thread_execution_state_offset = 1600;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
@@ -10544,14 +10897,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 728;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1528;
+    AOT_Thread_global_object_pool_offset = 1576;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1584;
+    AOT_Thread_exit_through_ffi_offset = 1632;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    1648;
+    1696;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 128;
 static constexpr dart::compiler::target::word
@@ -10596,11 +10949,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 672;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1536;
+    1584;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1544;
+    AOT_Thread_saved_shadow_call_stack_offset = 1592;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1560;
+    AOT_Thread_safepoint_state_offset = 1608;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
@@ -10622,6 +10975,16 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 152;
 static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_await_async_entry_point_offset = 1528;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_init_async_entry_point_offset = 1520;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_return_async_entry_point_offset = 1536;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 1544;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 1552;
+static constexpr dart::compiler::target::word
     AOT_Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word AOT_Thread_top_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
@@ -10637,14 +11000,14 @@
     AOT_Thread_write_barrier_mask_offset = 64;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1568;
+    1616;
 static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 1576;
-static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1608;
+    AOT_Thread_callback_stack_return_offset = 1624;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1656;
 static constexpr dart::compiler::target::word
     AOT_Thread_jump_to_frame_entry_point_offset = 632;
 static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
-    1616;
+    1664;
 static constexpr dart::compiler::target::word
     AOT_TsanUtils_setjmp_function_offset = 0;
 static constexpr dart::compiler::target::word
@@ -10758,8 +11121,8 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        1424, 1432, 1440, 1448, -1,   -1,   1456, 1464,
-        1472, 1480, 1488, -1,   1496, 1504, -1,   -1};
+        1432, 1440, 1448, 1456, -1,   -1,   1464, 1472,
+        1480, 1488, 1496, -1,   1504, 1512, -1,   -1};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
     24;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
@@ -10842,6 +11205,7 @@
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_InstanceSize = 32;
 static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_SuspendState_HeaderSize = 48;
 static constexpr dart::compiler::target::word AOT_String_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_InstanceSize = 16;
@@ -11133,11 +11497,22 @@
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
+    AOT_SuspendState_error_callback_offset = 40;
+static constexpr dart::compiler::target::word
+    AOT_SuspendState_frame_size_offset = 8;
+static constexpr dart::compiler::target::word AOT_SuspendState_future_offset =
+    24;
+static constexpr dart::compiler::target::word AOT_SuspendState_payload_offset =
+    48;
+static constexpr dart::compiler::target::word AOT_SuspendState_pc_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_SuspendState_then_callback_offset = 32;
+static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 736;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1576;
+    AOT_Thread_active_exception_offset = 1624;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1584;
+    AOT_Thread_active_stacktrace_offset = 1632;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
@@ -11161,7 +11536,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 376;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1656;
+    1704;
 static constexpr dart::compiler::target::word
     AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 664;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
@@ -11174,13 +11549,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 256;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1696;
+    1744;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_truncate_round_supported_offset = 1664;
+    AOT_Thread_double_truncate_round_supported_offset = 1712;
 static constexpr dart::compiler::target::word
-    AOT_Thread_service_extension_stream_offset = 1704;
+    AOT_Thread_service_extension_stream_offset = 1752;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     608;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -11197,7 +11572,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1616;
+    AOT_Thread_execution_state_offset = 1664;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
@@ -11219,14 +11594,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 728;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1592;
+    AOT_Thread_global_object_pool_offset = 1640;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1648;
+    AOT_Thread_exit_through_ffi_offset = 1696;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    1712;
+    1760;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 128;
 static constexpr dart::compiler::target::word
@@ -11271,11 +11646,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 672;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1600;
+    1648;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1608;
+    AOT_Thread_saved_shadow_call_stack_offset = 1656;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1624;
+    AOT_Thread_safepoint_state_offset = 1672;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
@@ -11297,6 +11672,16 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 152;
 static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_await_async_entry_point_offset = 1592;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_init_async_entry_point_offset = 1584;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_return_async_entry_point_offset = 1600;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 1608;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 1616;
+static constexpr dart::compiler::target::word
     AOT_Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word AOT_Thread_top_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
@@ -11312,14 +11697,14 @@
     AOT_Thread_write_barrier_mask_offset = 64;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1632;
+    1680;
 static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 1640;
-static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1672;
+    AOT_Thread_callback_stack_return_offset = 1688;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1720;
 static constexpr dart::compiler::target::word
     AOT_Thread_jump_to_frame_entry_point_offset = 632;
 static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
-    1680;
+    1728;
 static constexpr dart::compiler::target::word
     AOT_TsanUtils_setjmp_function_offset = 0;
 static constexpr dart::compiler::target::word
@@ -11433,9 +11818,9 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        1424, 1432, 1440, 1448, 1456, 1464, 1472, 1480, 1488, 1496, 1504,
-        1512, 1520, 1528, 1536, -1,   -1,   -1,   -1,   1544, 1552, -1,
-        -1,   1560, 1568, 1576, -1,   -1,   -1,   -1,   -1,   -1};
+        1432, 1440, 1448, 1456, 1464, 1472, 1480, 1488, 1496, 1504, 1512,
+        1520, 1528, 1536, 1544, -1,   -1,   -1,   -1,   1552, 1560, -1,
+        -1,   1568, 1576, 1584, -1,   -1,   -1,   -1,   -1,   -1};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
     24;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
@@ -11518,6 +11903,7 @@
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_InstanceSize = 32;
 static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_SuspendState_HeaderSize = 48;
 static constexpr dart::compiler::target::word AOT_String_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_InstanceSize = 16;
@@ -11805,11 +12191,22 @@
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
+    AOT_SuspendState_error_callback_offset = 32;
+static constexpr dart::compiler::target::word
+    AOT_SuspendState_frame_size_offset = 8;
+static constexpr dart::compiler::target::word AOT_SuspendState_future_offset =
+    24;
+static constexpr dart::compiler::target::word AOT_SuspendState_payload_offset =
+    40;
+static constexpr dart::compiler::target::word AOT_SuspendState_pc_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_SuspendState_then_callback_offset = 28;
+static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 736;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1512;
+    AOT_Thread_active_exception_offset = 1560;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1520;
+    AOT_Thread_active_stacktrace_offset = 1568;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
@@ -11833,7 +12230,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 376;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1592;
+    1640;
 static constexpr dart::compiler::target::word
     AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 664;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
@@ -11846,13 +12243,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 256;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1632;
+    1680;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_truncate_round_supported_offset = 1600;
+    AOT_Thread_double_truncate_round_supported_offset = 1648;
 static constexpr dart::compiler::target::word
-    AOT_Thread_service_extension_stream_offset = 1640;
+    AOT_Thread_service_extension_stream_offset = 1688;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     608;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -11869,7 +12266,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1552;
+    AOT_Thread_execution_state_offset = 1600;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
@@ -11891,14 +12288,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 728;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1528;
+    AOT_Thread_global_object_pool_offset = 1576;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1584;
+    AOT_Thread_exit_through_ffi_offset = 1632;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    1648;
+    1696;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 128;
 static constexpr dart::compiler::target::word
@@ -11943,11 +12340,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 672;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1536;
+    1584;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1544;
+    AOT_Thread_saved_shadow_call_stack_offset = 1592;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1560;
+    AOT_Thread_safepoint_state_offset = 1608;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
@@ -11969,6 +12366,16 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 152;
 static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_await_async_entry_point_offset = 1528;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_init_async_entry_point_offset = 1520;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_return_async_entry_point_offset = 1536;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 1544;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 1552;
+static constexpr dart::compiler::target::word
     AOT_Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word AOT_Thread_top_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
@@ -11984,14 +12391,14 @@
     AOT_Thread_write_barrier_mask_offset = 64;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1568;
+    1616;
 static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 1576;
-static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1608;
+    AOT_Thread_callback_stack_return_offset = 1624;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1656;
 static constexpr dart::compiler::target::word
     AOT_Thread_jump_to_frame_entry_point_offset = 632;
 static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
-    1616;
+    1664;
 static constexpr dart::compiler::target::word
     AOT_TsanUtils_setjmp_function_offset = 0;
 static constexpr dart::compiler::target::word
@@ -12105,8 +12512,8 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        1424, 1432, 1440, 1448, -1,   -1,   1456, 1464,
-        1472, 1480, 1488, -1,   1496, 1504, -1,   -1};
+        1432, 1440, 1448, 1456, -1,   -1,   1464, 1472,
+        1480, 1488, 1496, -1,   1504, 1512, -1,   -1};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
     24;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
@@ -12189,6 +12596,7 @@
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_InstanceSize = 32;
 static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_SuspendState_HeaderSize = 40;
 static constexpr dart::compiler::target::word AOT_String_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_InstanceSize = 16;
@@ -12476,11 +12884,22 @@
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
+    AOT_SuspendState_error_callback_offset = 32;
+static constexpr dart::compiler::target::word
+    AOT_SuspendState_frame_size_offset = 8;
+static constexpr dart::compiler::target::word AOT_SuspendState_future_offset =
+    24;
+static constexpr dart::compiler::target::word AOT_SuspendState_payload_offset =
+    40;
+static constexpr dart::compiler::target::word AOT_SuspendState_pc_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_SuspendState_then_callback_offset = 28;
+static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 736;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1576;
+    AOT_Thread_active_exception_offset = 1624;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1584;
+    AOT_Thread_active_stacktrace_offset = 1632;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
@@ -12504,7 +12923,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 376;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1656;
+    1704;
 static constexpr dart::compiler::target::word
     AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 664;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
@@ -12517,13 +12936,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 256;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1696;
+    1744;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_truncate_round_supported_offset = 1664;
+    AOT_Thread_double_truncate_round_supported_offset = 1712;
 static constexpr dart::compiler::target::word
-    AOT_Thread_service_extension_stream_offset = 1704;
+    AOT_Thread_service_extension_stream_offset = 1752;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     608;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -12540,7 +12959,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1616;
+    AOT_Thread_execution_state_offset = 1664;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
@@ -12562,14 +12981,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 728;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1592;
+    AOT_Thread_global_object_pool_offset = 1640;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1648;
+    AOT_Thread_exit_through_ffi_offset = 1696;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    1712;
+    1760;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 128;
 static constexpr dart::compiler::target::word
@@ -12614,11 +13033,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 672;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1600;
+    1648;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1608;
+    AOT_Thread_saved_shadow_call_stack_offset = 1656;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1624;
+    AOT_Thread_safepoint_state_offset = 1672;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
@@ -12640,6 +13059,16 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 152;
 static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_await_async_entry_point_offset = 1592;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_init_async_entry_point_offset = 1584;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_return_async_entry_point_offset = 1600;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 1608;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 1616;
+static constexpr dart::compiler::target::word
     AOT_Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word AOT_Thread_top_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
@@ -12655,14 +13084,14 @@
     AOT_Thread_write_barrier_mask_offset = 64;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1632;
+    1680;
 static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 1640;
-static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1672;
+    AOT_Thread_callback_stack_return_offset = 1688;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1720;
 static constexpr dart::compiler::target::word
     AOT_Thread_jump_to_frame_entry_point_offset = 632;
 static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
-    1680;
+    1728;
 static constexpr dart::compiler::target::word
     AOT_TsanUtils_setjmp_function_offset = 0;
 static constexpr dart::compiler::target::word
@@ -12776,9 +13205,9 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        1424, 1432, 1440, 1448, 1456, 1464, 1472, 1480, 1488, 1496, 1504,
-        1512, 1520, 1528, 1536, -1,   -1,   -1,   -1,   1544, 1552, -1,
-        -1,   1560, 1568, 1576, -1,   -1,   -1,   -1,   -1,   -1};
+        1432, 1440, 1448, 1456, 1464, 1472, 1480, 1488, 1496, 1504, 1512,
+        1520, 1528, 1536, 1544, -1,   -1,   -1,   -1,   1552, 1560, -1,
+        -1,   1568, 1576, 1584, -1,   -1,   -1,   -1,   -1,   -1};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
     24;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
@@ -12861,6 +13290,7 @@
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_InstanceSize = 32;
 static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_SuspendState_HeaderSize = 40;
 static constexpr dart::compiler::target::word AOT_String_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_InstanceSize = 16;
@@ -13148,11 +13578,22 @@
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_cache_offset = 4;
 static constexpr dart::compiler::target::word
+    AOT_SuspendState_error_callback_offset = 20;
+static constexpr dart::compiler::target::word
+    AOT_SuspendState_frame_size_offset = 4;
+static constexpr dart::compiler::target::word AOT_SuspendState_future_offset =
+    12;
+static constexpr dart::compiler::target::word AOT_SuspendState_payload_offset =
+    24;
+static constexpr dart::compiler::target::word AOT_SuspendState_pc_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_SuspendState_then_callback_offset = 16;
+static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 380;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 796;
+    AOT_Thread_active_exception_offset = 820;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 800;
+    AOT_Thread_active_stacktrace_offset = 824;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_entry_point_offset = 272;
 static constexpr dart::compiler::target::word
@@ -13176,7 +13617,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 200;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    836;
+    860;
 static constexpr dart::compiler::target::word
     AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 344;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
@@ -13189,13 +13630,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 140;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    864;
+    888;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 44;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_truncate_round_supported_offset = 840;
+    AOT_Thread_double_truncate_round_supported_offset = 864;
 static constexpr dart::compiler::target::word
-    AOT_Thread_service_extension_stream_offset = 868;
+    AOT_Thread_service_extension_stream_offset = 892;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     316;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -13212,7 +13653,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 252;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 816;
+    AOT_Thread_execution_state_offset = 840;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 256;
 static constexpr dart::compiler::target::word
@@ -13234,14 +13675,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 376;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 804;
+    AOT_Thread_global_object_pool_offset = 828;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 136;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 832;
+    AOT_Thread_exit_through_ffi_offset = 856;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 40;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    872;
+    896;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 64;
 static constexpr dart::compiler::target::word
@@ -13285,11 +13726,11 @@
     112;
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 348;
-static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 808;
+static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 832;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 812;
+    AOT_Thread_saved_shadow_call_stack_offset = 836;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 820;
+    AOT_Thread_safepoint_state_offset = 844;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 244;
 static constexpr dart::compiler::target::word
@@ -13311,6 +13752,16 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 76;
 static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_await_async_entry_point_offset = 804;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_init_async_entry_point_offset = 800;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_return_async_entry_point_offset = 808;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 812;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 816;
+static constexpr dart::compiler::target::word
     AOT_Thread_top_exit_frame_info_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_top_offset = 48;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
@@ -13326,14 +13777,14 @@
     AOT_Thread_write_barrier_mask_offset = 32;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 36;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    824;
+    848;
 static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 828;
-static constexpr dart::compiler::target::word AOT_Thread_random_offset = 848;
+    AOT_Thread_callback_stack_return_offset = 852;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 872;
 static constexpr dart::compiler::target::word
     AOT_Thread_jump_to_frame_entry_point_offset = 328;
 static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
-    856;
+    880;
 static constexpr dart::compiler::target::word
     AOT_TsanUtils_setjmp_function_offset = 0;
 static constexpr dart::compiler::target::word
@@ -13446,9 +13897,9 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        -1,  -1,  -1, -1, -1, 724, 728, 732, -1,  -1,  736,
-        740, 744, -1, -1, -1, 748, 752, 756, 760, 764, 768,
-        772, 776, -1, -1, -1, -1,  780, 784, 788, 792};
+        -1,  -1,  -1, -1, -1, 728, 732, 736, -1,  -1,  740,
+        744, 748, -1, -1, -1, 752, 756, 760, 764, 768, 772,
+        776, 780, -1, -1, -1, -1,  784, 788, 792, 796};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
     12;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 8;
@@ -13531,6 +13982,7 @@
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 20;
+static constexpr dart::compiler::target::word AOT_SuspendState_HeaderSize = 24;
 static constexpr dart::compiler::target::word AOT_String_InstanceSize = 12;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_InstanceSize = 8;
@@ -13819,11 +14271,22 @@
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
+    AOT_SuspendState_error_callback_offset = 40;
+static constexpr dart::compiler::target::word
+    AOT_SuspendState_frame_size_offset = 8;
+static constexpr dart::compiler::target::word AOT_SuspendState_future_offset =
+    24;
+static constexpr dart::compiler::target::word AOT_SuspendState_payload_offset =
+    48;
+static constexpr dart::compiler::target::word AOT_SuspendState_pc_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_SuspendState_then_callback_offset = 32;
+static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 736;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1568;
+    AOT_Thread_active_exception_offset = 1616;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1576;
+    AOT_Thread_active_stacktrace_offset = 1624;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
@@ -13847,7 +14310,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 376;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1648;
+    1696;
 static constexpr dart::compiler::target::word
     AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 664;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
@@ -13860,13 +14323,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 256;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1688;
+    1736;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_truncate_round_supported_offset = 1656;
+    AOT_Thread_double_truncate_round_supported_offset = 1704;
 static constexpr dart::compiler::target::word
-    AOT_Thread_service_extension_stream_offset = 1696;
+    AOT_Thread_service_extension_stream_offset = 1744;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     608;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -13883,7 +14346,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1608;
+    AOT_Thread_execution_state_offset = 1656;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
@@ -13905,14 +14368,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 728;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1584;
+    AOT_Thread_global_object_pool_offset = 1632;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1640;
+    AOT_Thread_exit_through_ffi_offset = 1688;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    1704;
+    1752;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 128;
 static constexpr dart::compiler::target::word
@@ -13957,11 +14420,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 672;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1592;
+    1640;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1600;
+    AOT_Thread_saved_shadow_call_stack_offset = 1648;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1616;
+    AOT_Thread_safepoint_state_offset = 1664;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
@@ -13983,6 +14446,16 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 152;
 static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_await_async_entry_point_offset = 1584;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_init_async_entry_point_offset = 1576;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_return_async_entry_point_offset = 1592;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 1600;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 1608;
+static constexpr dart::compiler::target::word
     AOT_Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word AOT_Thread_top_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
@@ -13998,14 +14471,14 @@
     AOT_Thread_write_barrier_mask_offset = 64;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1624;
+    1672;
 static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 1632;
-static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1664;
+    AOT_Thread_callback_stack_return_offset = 1680;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1712;
 static constexpr dart::compiler::target::word
     AOT_Thread_jump_to_frame_entry_point_offset = 632;
 static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
-    1672;
+    1720;
 static constexpr dart::compiler::target::word
     AOT_TsanUtils_setjmp_function_offset = 0;
 static constexpr dart::compiler::target::word
@@ -14119,9 +14592,9 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        -1,   -1,   -1, -1, -1, 1424, 1432, 1440, -1,   -1,   1448,
-        1456, 1464, -1, -1, -1, 1472, 1480, 1488, 1496, 1504, 1512,
-        1520, 1528, -1, -1, -1, -1,   1536, 1544, 1552, 1560};
+        -1,   -1,   -1, -1, -1, 1432, 1440, 1448, -1,   -1,   1456,
+        1464, 1472, -1, -1, -1, 1480, 1488, 1496, 1504, 1512, 1520,
+        1528, 1536, -1, -1, -1, -1,   1544, 1552, 1560, 1568};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
     24;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
@@ -14204,6 +14677,7 @@
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_InstanceSize = 32;
 static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_SuspendState_HeaderSize = 48;
 static constexpr dart::compiler::target::word AOT_String_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_InstanceSize = 16;
@@ -14486,11 +14960,22 @@
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_cache_offset = 4;
 static constexpr dart::compiler::target::word
+    AOT_SuspendState_error_callback_offset = 20;
+static constexpr dart::compiler::target::word
+    AOT_SuspendState_frame_size_offset = 4;
+static constexpr dart::compiler::target::word AOT_SuspendState_future_offset =
+    12;
+static constexpr dart::compiler::target::word AOT_SuspendState_payload_offset =
+    24;
+static constexpr dart::compiler::target::word AOT_SuspendState_pc_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_SuspendState_then_callback_offset = 16;
+static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 380;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 756;
+    AOT_Thread_active_exception_offset = 780;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 760;
+    AOT_Thread_active_stacktrace_offset = 784;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_entry_point_offset = 272;
 static constexpr dart::compiler::target::word
@@ -14514,7 +14999,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 200;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    796;
+    820;
 static constexpr dart::compiler::target::word
     AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 344;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
@@ -14527,13 +15012,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 140;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    824;
+    848;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 44;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_truncate_round_supported_offset = 800;
+    AOT_Thread_double_truncate_round_supported_offset = 824;
 static constexpr dart::compiler::target::word
-    AOT_Thread_service_extension_stream_offset = 828;
+    AOT_Thread_service_extension_stream_offset = 852;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     316;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -14550,7 +15035,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 252;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 776;
+    AOT_Thread_execution_state_offset = 800;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 256;
 static constexpr dart::compiler::target::word
@@ -14572,14 +15057,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 376;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 764;
+    AOT_Thread_global_object_pool_offset = 788;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 136;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 792;
+    AOT_Thread_exit_through_ffi_offset = 816;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 40;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    832;
+    856;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 64;
 static constexpr dart::compiler::target::word
@@ -14623,11 +15108,11 @@
     112;
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 348;
-static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 768;
+static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 792;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 772;
+    AOT_Thread_saved_shadow_call_stack_offset = 796;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 780;
+    AOT_Thread_safepoint_state_offset = 804;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 244;
 static constexpr dart::compiler::target::word
@@ -14649,6 +15134,16 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 76;
 static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_await_async_entry_point_offset = 764;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_init_async_entry_point_offset = 760;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_return_async_entry_point_offset = 768;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 772;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 776;
+static constexpr dart::compiler::target::word
     AOT_Thread_top_exit_frame_info_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_top_offset = 48;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
@@ -14664,14 +15159,14 @@
     AOT_Thread_write_barrier_mask_offset = 32;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 36;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    784;
+    808;
 static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 788;
-static constexpr dart::compiler::target::word AOT_Thread_random_offset = 808;
+    AOT_Thread_callback_stack_return_offset = 812;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 832;
 static constexpr dart::compiler::target::word
     AOT_Thread_jump_to_frame_entry_point_offset = 328;
 static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
-    816;
+    840;
 static constexpr dart::compiler::target::word
     AOT_TsanUtils_setjmp_function_offset = 0;
 static constexpr dart::compiler::target::word
@@ -14784,7 +15279,7 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        724, 728, 732, 736, 740, -1, 744, -1, 748, 752, -1, -1, -1, -1, -1, -1};
+        728, 732, 736, 740, 744, -1, 748, -1, 752, 756, -1, -1, -1, -1, -1, -1};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
     12;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 8;
@@ -14867,6 +15362,7 @@
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 20;
+static constexpr dart::compiler::target::word AOT_SuspendState_HeaderSize = 24;
 static constexpr dart::compiler::target::word AOT_String_InstanceSize = 12;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_InstanceSize = 8;
@@ -15148,11 +15644,22 @@
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
+    AOT_SuspendState_error_callback_offset = 40;
+static constexpr dart::compiler::target::word
+    AOT_SuspendState_frame_size_offset = 8;
+static constexpr dart::compiler::target::word AOT_SuspendState_future_offset =
+    24;
+static constexpr dart::compiler::target::word AOT_SuspendState_payload_offset =
+    48;
+static constexpr dart::compiler::target::word AOT_SuspendState_pc_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_SuspendState_then_callback_offset = 32;
+static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 736;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1512;
+    AOT_Thread_active_exception_offset = 1560;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1520;
+    AOT_Thread_active_stacktrace_offset = 1568;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
@@ -15176,7 +15683,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 376;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1592;
+    1640;
 static constexpr dart::compiler::target::word
     AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 664;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
@@ -15189,13 +15696,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 256;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1632;
+    1680;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_truncate_round_supported_offset = 1600;
+    AOT_Thread_double_truncate_round_supported_offset = 1648;
 static constexpr dart::compiler::target::word
-    AOT_Thread_service_extension_stream_offset = 1640;
+    AOT_Thread_service_extension_stream_offset = 1688;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     608;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -15212,7 +15719,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1552;
+    AOT_Thread_execution_state_offset = 1600;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
@@ -15234,14 +15741,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 728;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1528;
+    AOT_Thread_global_object_pool_offset = 1576;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1584;
+    AOT_Thread_exit_through_ffi_offset = 1632;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    1648;
+    1696;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 128;
 static constexpr dart::compiler::target::word
@@ -15286,11 +15793,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 672;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1536;
+    1584;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1544;
+    AOT_Thread_saved_shadow_call_stack_offset = 1592;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1560;
+    AOT_Thread_safepoint_state_offset = 1608;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
@@ -15312,6 +15819,16 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 152;
 static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_await_async_entry_point_offset = 1528;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_init_async_entry_point_offset = 1520;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_return_async_entry_point_offset = 1536;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 1544;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 1552;
+static constexpr dart::compiler::target::word
     AOT_Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word AOT_Thread_top_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
@@ -15327,14 +15844,14 @@
     AOT_Thread_write_barrier_mask_offset = 64;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1568;
+    1616;
 static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 1576;
-static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1608;
+    AOT_Thread_callback_stack_return_offset = 1624;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1656;
 static constexpr dart::compiler::target::word
     AOT_Thread_jump_to_frame_entry_point_offset = 632;
 static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
-    1616;
+    1664;
 static constexpr dart::compiler::target::word
     AOT_TsanUtils_setjmp_function_offset = 0;
 static constexpr dart::compiler::target::word
@@ -15448,8 +15965,8 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        1424, 1432, 1440, 1448, -1,   -1,   1456, 1464,
-        1472, 1480, 1488, -1,   1496, 1504, -1,   -1};
+        1432, 1440, 1448, 1456, -1,   -1,   1464, 1472,
+        1480, 1488, 1496, -1,   1504, 1512, -1,   -1};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
     24;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
@@ -15532,6 +16049,7 @@
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_InstanceSize = 32;
 static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_SuspendState_HeaderSize = 48;
 static constexpr dart::compiler::target::word AOT_String_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_InstanceSize = 16;
@@ -15816,11 +16334,22 @@
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
+    AOT_SuspendState_error_callback_offset = 40;
+static constexpr dart::compiler::target::word
+    AOT_SuspendState_frame_size_offset = 8;
+static constexpr dart::compiler::target::word AOT_SuspendState_future_offset =
+    24;
+static constexpr dart::compiler::target::word AOT_SuspendState_payload_offset =
+    48;
+static constexpr dart::compiler::target::word AOT_SuspendState_pc_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_SuspendState_then_callback_offset = 32;
+static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 736;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1576;
+    AOT_Thread_active_exception_offset = 1624;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1584;
+    AOT_Thread_active_stacktrace_offset = 1632;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
@@ -15844,7 +16373,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 376;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1656;
+    1704;
 static constexpr dart::compiler::target::word
     AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 664;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
@@ -15857,13 +16386,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 256;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1696;
+    1744;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_truncate_round_supported_offset = 1664;
+    AOT_Thread_double_truncate_round_supported_offset = 1712;
 static constexpr dart::compiler::target::word
-    AOT_Thread_service_extension_stream_offset = 1704;
+    AOT_Thread_service_extension_stream_offset = 1752;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     608;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -15880,7 +16409,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1616;
+    AOT_Thread_execution_state_offset = 1664;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
@@ -15902,14 +16431,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 728;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1592;
+    AOT_Thread_global_object_pool_offset = 1640;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1648;
+    AOT_Thread_exit_through_ffi_offset = 1696;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    1712;
+    1760;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 128;
 static constexpr dart::compiler::target::word
@@ -15954,11 +16483,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 672;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1600;
+    1648;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1608;
+    AOT_Thread_saved_shadow_call_stack_offset = 1656;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1624;
+    AOT_Thread_safepoint_state_offset = 1672;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
@@ -15980,6 +16509,16 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 152;
 static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_await_async_entry_point_offset = 1592;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_init_async_entry_point_offset = 1584;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_return_async_entry_point_offset = 1600;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 1608;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 1616;
+static constexpr dart::compiler::target::word
     AOT_Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word AOT_Thread_top_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
@@ -15995,14 +16534,14 @@
     AOT_Thread_write_barrier_mask_offset = 64;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1632;
+    1680;
 static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 1640;
-static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1672;
+    AOT_Thread_callback_stack_return_offset = 1688;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1720;
 static constexpr dart::compiler::target::word
     AOT_Thread_jump_to_frame_entry_point_offset = 632;
 static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
-    1680;
+    1728;
 static constexpr dart::compiler::target::word
     AOT_TsanUtils_setjmp_function_offset = 0;
 static constexpr dart::compiler::target::word
@@ -16116,9 +16655,9 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        1424, 1432, 1440, 1448, 1456, 1464, 1472, 1480, 1488, 1496, 1504,
-        1512, 1520, 1528, 1536, -1,   -1,   -1,   -1,   1544, 1552, -1,
-        -1,   1560, 1568, 1576, -1,   -1,   -1,   -1,   -1,   -1};
+        1432, 1440, 1448, 1456, 1464, 1472, 1480, 1488, 1496, 1504, 1512,
+        1520, 1528, 1536, 1544, -1,   -1,   -1,   -1,   1552, 1560, -1,
+        -1,   1568, 1576, 1584, -1,   -1,   -1,   -1,   -1,   -1};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
     24;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
@@ -16201,6 +16740,7 @@
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_InstanceSize = 32;
 static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_SuspendState_HeaderSize = 48;
 static constexpr dart::compiler::target::word AOT_String_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_InstanceSize = 16;
@@ -16481,11 +17021,22 @@
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
+    AOT_SuspendState_error_callback_offset = 32;
+static constexpr dart::compiler::target::word
+    AOT_SuspendState_frame_size_offset = 8;
+static constexpr dart::compiler::target::word AOT_SuspendState_future_offset =
+    24;
+static constexpr dart::compiler::target::word AOT_SuspendState_payload_offset =
+    40;
+static constexpr dart::compiler::target::word AOT_SuspendState_pc_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_SuspendState_then_callback_offset = 28;
+static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 736;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1512;
+    AOT_Thread_active_exception_offset = 1560;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1520;
+    AOT_Thread_active_stacktrace_offset = 1568;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
@@ -16509,7 +17060,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 376;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1592;
+    1640;
 static constexpr dart::compiler::target::word
     AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 664;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
@@ -16522,13 +17073,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 256;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1632;
+    1680;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_truncate_round_supported_offset = 1600;
+    AOT_Thread_double_truncate_round_supported_offset = 1648;
 static constexpr dart::compiler::target::word
-    AOT_Thread_service_extension_stream_offset = 1640;
+    AOT_Thread_service_extension_stream_offset = 1688;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     608;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -16545,7 +17096,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1552;
+    AOT_Thread_execution_state_offset = 1600;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
@@ -16567,14 +17118,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 728;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1528;
+    AOT_Thread_global_object_pool_offset = 1576;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1584;
+    AOT_Thread_exit_through_ffi_offset = 1632;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    1648;
+    1696;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 128;
 static constexpr dart::compiler::target::word
@@ -16619,11 +17170,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 672;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1536;
+    1584;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1544;
+    AOT_Thread_saved_shadow_call_stack_offset = 1592;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1560;
+    AOT_Thread_safepoint_state_offset = 1608;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
@@ -16645,6 +17196,16 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 152;
 static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_await_async_entry_point_offset = 1528;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_init_async_entry_point_offset = 1520;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_return_async_entry_point_offset = 1536;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 1544;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 1552;
+static constexpr dart::compiler::target::word
     AOT_Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word AOT_Thread_top_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
@@ -16660,14 +17221,14 @@
     AOT_Thread_write_barrier_mask_offset = 64;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1568;
+    1616;
 static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 1576;
-static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1608;
+    AOT_Thread_callback_stack_return_offset = 1624;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1656;
 static constexpr dart::compiler::target::word
     AOT_Thread_jump_to_frame_entry_point_offset = 632;
 static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
-    1616;
+    1664;
 static constexpr dart::compiler::target::word
     AOT_TsanUtils_setjmp_function_offset = 0;
 static constexpr dart::compiler::target::word
@@ -16781,8 +17342,8 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        1424, 1432, 1440, 1448, -1,   -1,   1456, 1464,
-        1472, 1480, 1488, -1,   1496, 1504, -1,   -1};
+        1432, 1440, 1448, 1456, -1,   -1,   1464, 1472,
+        1480, 1488, 1496, -1,   1504, 1512, -1,   -1};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
     24;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
@@ -16865,6 +17426,7 @@
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_InstanceSize = 32;
 static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_SuspendState_HeaderSize = 40;
 static constexpr dart::compiler::target::word AOT_String_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_InstanceSize = 16;
@@ -17145,11 +17707,22 @@
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
+    AOT_SuspendState_error_callback_offset = 32;
+static constexpr dart::compiler::target::word
+    AOT_SuspendState_frame_size_offset = 8;
+static constexpr dart::compiler::target::word AOT_SuspendState_future_offset =
+    24;
+static constexpr dart::compiler::target::word AOT_SuspendState_payload_offset =
+    40;
+static constexpr dart::compiler::target::word AOT_SuspendState_pc_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_SuspendState_then_callback_offset = 28;
+static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 736;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1576;
+    AOT_Thread_active_exception_offset = 1624;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1584;
+    AOT_Thread_active_stacktrace_offset = 1632;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
@@ -17173,7 +17746,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 376;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1656;
+    1704;
 static constexpr dart::compiler::target::word
     AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 664;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
@@ -17186,13 +17759,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 256;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1696;
+    1744;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_truncate_round_supported_offset = 1664;
+    AOT_Thread_double_truncate_round_supported_offset = 1712;
 static constexpr dart::compiler::target::word
-    AOT_Thread_service_extension_stream_offset = 1704;
+    AOT_Thread_service_extension_stream_offset = 1752;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     608;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -17209,7 +17782,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1616;
+    AOT_Thread_execution_state_offset = 1664;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
@@ -17231,14 +17804,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 728;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1592;
+    AOT_Thread_global_object_pool_offset = 1640;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1648;
+    AOT_Thread_exit_through_ffi_offset = 1696;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    1712;
+    1760;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 128;
 static constexpr dart::compiler::target::word
@@ -17283,11 +17856,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 672;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1600;
+    1648;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1608;
+    AOT_Thread_saved_shadow_call_stack_offset = 1656;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1624;
+    AOT_Thread_safepoint_state_offset = 1672;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
@@ -17309,6 +17882,16 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 152;
 static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_await_async_entry_point_offset = 1592;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_init_async_entry_point_offset = 1584;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_return_async_entry_point_offset = 1600;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 1608;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 1616;
+static constexpr dart::compiler::target::word
     AOT_Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word AOT_Thread_top_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
@@ -17324,14 +17907,14 @@
     AOT_Thread_write_barrier_mask_offset = 64;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1632;
+    1680;
 static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 1640;
-static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1672;
+    AOT_Thread_callback_stack_return_offset = 1688;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1720;
 static constexpr dart::compiler::target::word
     AOT_Thread_jump_to_frame_entry_point_offset = 632;
 static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
-    1680;
+    1728;
 static constexpr dart::compiler::target::word
     AOT_TsanUtils_setjmp_function_offset = 0;
 static constexpr dart::compiler::target::word
@@ -17445,9 +18028,9 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        1424, 1432, 1440, 1448, 1456, 1464, 1472, 1480, 1488, 1496, 1504,
-        1512, 1520, 1528, 1536, -1,   -1,   -1,   -1,   1544, 1552, -1,
-        -1,   1560, 1568, 1576, -1,   -1,   -1,   -1,   -1,   -1};
+        1432, 1440, 1448, 1456, 1464, 1472, 1480, 1488, 1496, 1504, 1512,
+        1520, 1528, 1536, 1544, -1,   -1,   -1,   -1,   1552, 1560, -1,
+        -1,   1568, 1576, 1584, -1,   -1,   -1,   -1,   -1,   -1};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
     24;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
@@ -17530,6 +18113,7 @@
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_InstanceSize = 32;
 static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_SuspendState_HeaderSize = 40;
 static constexpr dart::compiler::target::word AOT_String_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_InstanceSize = 16;
@@ -17810,11 +18394,22 @@
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_cache_offset = 4;
 static constexpr dart::compiler::target::word
+    AOT_SuspendState_error_callback_offset = 20;
+static constexpr dart::compiler::target::word
+    AOT_SuspendState_frame_size_offset = 4;
+static constexpr dart::compiler::target::word AOT_SuspendState_future_offset =
+    12;
+static constexpr dart::compiler::target::word AOT_SuspendState_payload_offset =
+    24;
+static constexpr dart::compiler::target::word AOT_SuspendState_pc_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_SuspendState_then_callback_offset = 16;
+static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 380;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 796;
+    AOT_Thread_active_exception_offset = 820;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 800;
+    AOT_Thread_active_stacktrace_offset = 824;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_entry_point_offset = 272;
 static constexpr dart::compiler::target::word
@@ -17838,7 +18433,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 200;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    836;
+    860;
 static constexpr dart::compiler::target::word
     AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 344;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
@@ -17851,13 +18446,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 140;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    864;
+    888;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 44;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_truncate_round_supported_offset = 840;
+    AOT_Thread_double_truncate_round_supported_offset = 864;
 static constexpr dart::compiler::target::word
-    AOT_Thread_service_extension_stream_offset = 868;
+    AOT_Thread_service_extension_stream_offset = 892;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     316;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -17874,7 +18469,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 252;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 816;
+    AOT_Thread_execution_state_offset = 840;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 256;
 static constexpr dart::compiler::target::word
@@ -17896,14 +18491,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 376;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 804;
+    AOT_Thread_global_object_pool_offset = 828;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 136;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 832;
+    AOT_Thread_exit_through_ffi_offset = 856;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 40;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    872;
+    896;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 64;
 static constexpr dart::compiler::target::word
@@ -17947,11 +18542,11 @@
     112;
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 348;
-static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 808;
+static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 832;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 812;
+    AOT_Thread_saved_shadow_call_stack_offset = 836;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 820;
+    AOT_Thread_safepoint_state_offset = 844;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 244;
 static constexpr dart::compiler::target::word
@@ -17973,6 +18568,16 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 76;
 static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_await_async_entry_point_offset = 804;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_init_async_entry_point_offset = 800;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_return_async_entry_point_offset = 808;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 812;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 816;
+static constexpr dart::compiler::target::word
     AOT_Thread_top_exit_frame_info_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_top_offset = 48;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
@@ -17988,14 +18593,14 @@
     AOT_Thread_write_barrier_mask_offset = 32;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 36;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    824;
+    848;
 static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 828;
-static constexpr dart::compiler::target::word AOT_Thread_random_offset = 848;
+    AOT_Thread_callback_stack_return_offset = 852;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 872;
 static constexpr dart::compiler::target::word
     AOT_Thread_jump_to_frame_entry_point_offset = 328;
 static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
-    856;
+    880;
 static constexpr dart::compiler::target::word
     AOT_TsanUtils_setjmp_function_offset = 0;
 static constexpr dart::compiler::target::word
@@ -18108,9 +18713,9 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        -1,  -1,  -1, -1, -1, 724, 728, 732, -1,  -1,  736,
-        740, 744, -1, -1, -1, 748, 752, 756, 760, 764, 768,
-        772, 776, -1, -1, -1, -1,  780, 784, 788, 792};
+        -1,  -1,  -1, -1, -1, 728, 732, 736, -1,  -1,  740,
+        744, 748, -1, -1, -1, 752, 756, 760, 764, 768, 772,
+        776, 780, -1, -1, -1, -1,  784, 788, 792, 796};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
     12;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 8;
@@ -18193,6 +18798,7 @@
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 20;
+static constexpr dart::compiler::target::word AOT_SuspendState_HeaderSize = 24;
 static constexpr dart::compiler::target::word AOT_String_InstanceSize = 12;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_InstanceSize = 8;
@@ -18474,11 +19080,22 @@
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_cache_offset = 8;
 static constexpr dart::compiler::target::word
+    AOT_SuspendState_error_callback_offset = 40;
+static constexpr dart::compiler::target::word
+    AOT_SuspendState_frame_size_offset = 8;
+static constexpr dart::compiler::target::word AOT_SuspendState_future_offset =
+    24;
+static constexpr dart::compiler::target::word AOT_SuspendState_payload_offset =
+    48;
+static constexpr dart::compiler::target::word AOT_SuspendState_pc_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_SuspendState_then_callback_offset = 32;
+static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 736;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1568;
+    AOT_Thread_active_exception_offset = 1616;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1576;
+    AOT_Thread_active_stacktrace_offset = 1624;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_entry_point_offset = 520;
 static constexpr dart::compiler::target::word
@@ -18502,7 +19119,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 376;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1648;
+    1696;
 static constexpr dart::compiler::target::word
     AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 664;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
@@ -18515,13 +19132,13 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 256;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1688;
+    1736;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 88;
 static constexpr dart::compiler::target::word
-    AOT_Thread_double_truncate_round_supported_offset = 1656;
+    AOT_Thread_double_truncate_round_supported_offset = 1704;
 static constexpr dart::compiler::target::word
-    AOT_Thread_service_extension_stream_offset = 1696;
+    AOT_Thread_service_extension_stream_offset = 1744;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     608;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -18538,7 +19155,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1608;
+    AOT_Thread_execution_state_offset = 1656;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
@@ -18560,14 +19177,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 728;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1584;
+    AOT_Thread_global_object_pool_offset = 1632;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1640;
+    AOT_Thread_exit_through_ffi_offset = 1688;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    1704;
+    1752;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 128;
 static constexpr dart::compiler::target::word
@@ -18612,11 +19229,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 672;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1592;
+    1640;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1600;
+    AOT_Thread_saved_shadow_call_stack_offset = 1648;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1616;
+    AOT_Thread_safepoint_state_offset = 1664;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 464;
 static constexpr dart::compiler::target::word
@@ -18638,6 +19255,16 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_store_buffer_block_offset = 152;
 static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_await_async_entry_point_offset = 1584;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_init_async_entry_point_offset = 1576;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_return_async_entry_point_offset = 1592;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_return_async_not_future_entry_point_offset = 1600;
+static constexpr dart::compiler::target::word
+    AOT_Thread_suspend_state_handle_exception_entry_point_offset = 1608;
+static constexpr dart::compiler::target::word
     AOT_Thread_top_exit_frame_info_offset = 144;
 static constexpr dart::compiler::target::word AOT_Thread_top_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
@@ -18653,14 +19280,14 @@
     AOT_Thread_write_barrier_mask_offset = 64;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1624;
+    1672;
 static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 1632;
-static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1664;
+    AOT_Thread_callback_stack_return_offset = 1680;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1712;
 static constexpr dart::compiler::target::word
     AOT_Thread_jump_to_frame_entry_point_offset = 632;
 static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
-    1672;
+    1720;
 static constexpr dart::compiler::target::word
     AOT_TsanUtils_setjmp_function_offset = 0;
 static constexpr dart::compiler::target::word
@@ -18774,9 +19401,9 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        -1,   -1,   -1, -1, -1, 1424, 1432, 1440, -1,   -1,   1448,
-        1456, 1464, -1, -1, -1, 1472, 1480, 1488, 1496, 1504, 1512,
-        1520, 1528, -1, -1, -1, -1,   1536, 1544, 1552, 1560};
+        -1,   -1,   -1, -1, -1, 1432, 1440, 1448, -1,   -1,   1456,
+        1464, 1472, -1, -1, -1, 1480, 1488, 1496, 1504, 1512, 1520,
+        1528, 1536, -1, -1, -1, -1,   1544, 1552, 1560, 1568};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
     24;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
@@ -18859,6 +19486,7 @@
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_InstanceSize = 32;
 static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_SuspendState_HeaderSize = 48;
 static constexpr dart::compiler::target::word AOT_String_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_InstanceSize = 16;
diff --git a/runtime/vm/compiler/runtime_offsets_list.h b/runtime/vm/compiler/runtime_offsets_list.h
index 65982cf..8fa14a3 100644
--- a/runtime/vm/compiler/runtime_offsets_list.h
+++ b/runtime/vm/compiler/runtime_offsets_list.h
@@ -190,6 +190,12 @@
   FIELD(String, hash_offset)                                                   \
   FIELD(String, length_offset)                                                 \
   FIELD(SubtypeTestCache, cache_offset)                                        \
+  FIELD(SuspendState, error_callback_offset)                                   \
+  FIELD(SuspendState, frame_size_offset)                                       \
+  FIELD(SuspendState, future_offset)                                           \
+  FIELD(SuspendState, payload_offset)                                          \
+  FIELD(SuspendState, pc_offset)                                               \
+  FIELD(SuspendState, then_callback_offset)                                    \
   FIELD(Thread, AllocateArray_entry_point_offset)                              \
   FIELD(Thread, active_exception_offset)                                       \
   FIELD(Thread, active_stacktrace_offset)                                      \
@@ -275,6 +281,11 @@
                                                                                \
   FIELD(Thread, stack_overflow_shared_without_fpu_regs_stub_offset)            \
   FIELD(Thread, store_buffer_block_offset)                                     \
+  FIELD(Thread, suspend_state_await_async_entry_point_offset)                  \
+  FIELD(Thread, suspend_state_init_async_entry_point_offset)                   \
+  FIELD(Thread, suspend_state_return_async_entry_point_offset)                 \
+  FIELD(Thread, suspend_state_return_async_not_future_entry_point_offset)      \
+  FIELD(Thread, suspend_state_handle_exception_entry_point_offset)             \
   FIELD(Thread, top_exit_frame_info_offset)                                    \
   FIELD(Thread, top_offset)                                                    \
   FIELD(Thread, top_resource_offset)                                           \
@@ -416,6 +427,7 @@
   SIZEOF(Sentinel, InstanceSize, UntaggedSentinel)                             \
   SIZEOF(SingleTargetCache, InstanceSize, UntaggedSingleTargetCache)           \
   SIZEOF(StackTrace, InstanceSize, UntaggedStackTrace)                         \
+  SIZEOF(SuspendState, HeaderSize, UntaggedSuspendState)                       \
   SIZEOF(String, InstanceSize, UntaggedString)                                 \
   SIZEOF(SubtypeTestCache, InstanceSize, UntaggedSubtypeTestCache)             \
   SIZEOF(LoadingUnit, InstanceSize, UntaggedLoadingUnit)                       \
@@ -439,6 +451,7 @@
   PAYLOAD_SIZEOF(CompressedStackMaps, InstanceSize, HeaderSize)                \
   PAYLOAD_SIZEOF(InstructionsSection, InstanceSize, HeaderSize)                \
   PAYLOAD_SIZEOF(PcDescriptors, InstanceSize, HeaderSize)                      \
+  PAYLOAD_SIZEOF(SuspendState, InstanceSize, HeaderSize)                       \
   PAYLOAD_SIZEOF(TypedData, InstanceSize, HeaderSize)
 
 #define JIT_OFFSETS_LIST(FIELD, ARRAY, SIZEOF, ARRAY_SIZEOF, PAYLOAD_SIZEOF,   \
diff --git a/runtime/vm/compiler/stub_code_compiler.cc b/runtime/vm/compiler/stub_code_compiler.cc
index 2f3601c..9a145c4 100644
--- a/runtime/vm/compiler/stub_code_compiler.cc
+++ b/runtime/vm/compiler/stub_code_compiler.cc
@@ -15,6 +15,7 @@
 
 #include "vm/compiler/api/type_check_mode.h"
 #include "vm/compiler/assembler/assembler.h"
+#include "vm/stack_frame.h"
 
 #define __ assembler->
 
@@ -1273,6 +1274,434 @@
   __ Ret();
 }
 
+static intptr_t SuspendStateFpOffset() {
+  return compiler::target::frame_layout.FrameSlotForVariableIndex(
+             SuspendState::kSuspendStateVarIndex) *
+         compiler::target::kWordSize;
+}
+
+void StubCodeCompiler::GenerateSuspendStub(
+    Assembler* assembler,
+    intptr_t suspend_entry_point_offset) {
+  const Register kArgument = SuspendStubABI::kArgumentReg;
+  const Register kTemp = SuspendStubABI::kTempReg;
+  const Register kFrameSize = SuspendStubABI::kFrameSizeReg;
+  const Register kSuspendState = SuspendStubABI::kSuspendStateReg;
+  const Register kFuture = SuspendStubABI::kFutureReg;
+  const Register kSrcFrame = SuspendStubABI::kSrcFrameReg;
+  const Register kDstFrame = SuspendStubABI::kDstFrameReg;
+  Label alloc_slow_case, alloc_done, init_done, old_gen_object, call_await;
+
+#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64)
+  SPILLS_LR_TO_FRAME({});  // Simulate entering the caller (Dart) frame.
+#endif
+
+  __ LoadFromOffset(kSuspendState, Address(FPREG, SuspendStateFpOffset()));
+
+  __ AddImmediate(
+      kFrameSize, FPREG,
+      -target::frame_layout.last_param_from_entry_sp * target::kWordSize);
+  __ SubRegisters(kFrameSize, SPREG);
+
+  __ EnterStubFrame();
+
+  __ CompareClassId(kSuspendState, kSuspendStateCid, kTemp);
+  __ BranchIf(EQUAL, &init_done);
+
+  __ MoveRegister(kFuture, kSuspendState);
+  __ Comment("Allocate SuspendState");
+
+  // Check for allocation tracing.
+  NOT_IN_PRODUCT(
+      __ MaybeTraceAllocation(kSuspendStateCid, &alloc_slow_case, kTemp));
+
+  // Compute the rounded instance size.
+  const intptr_t fixed_size_plus_alignment_padding =
+      (target::SuspendState::HeaderSize() +
+       target::ObjectAlignment::kObjectAlignment - 1);
+  __ AddImmediate(kTemp, kFrameSize, fixed_size_plus_alignment_padding);
+  __ AndImmediate(kTemp, -target::ObjectAlignment::kObjectAlignment);
+
+  // Now allocate the object.
+  __ LoadFromOffset(kSuspendState, Address(THR, target::Thread::top_offset()));
+  __ AddRegisters(kTemp, kSuspendState);
+  // Check if the allocation fits into the remaining space.
+  __ CompareWithMemoryValue(kTemp, Address(THR, target::Thread::end_offset()));
+  __ BranchIf(UNSIGNED_GREATER_EQUAL, &alloc_slow_case);
+
+  // Successfully allocated the object, now update top to point to
+  // next object start and initialize the object.
+  __ StoreToOffset(kTemp, Address(THR, target::Thread::top_offset()));
+  __ SubRegisters(kTemp, kSuspendState);
+  __ AddImmediate(kSuspendState, kHeapObjectTag);
+
+  // Calculate the size tag.
+  {
+    Label size_tag_overflow, done;
+    __ CompareImmediate(kTemp, target::UntaggedObject::kSizeTagMaxSizeTag);
+    __ BranchIf(UNSIGNED_GREATER, &size_tag_overflow, Assembler::kNearJump);
+    __ LslImmediate(kTemp, target::UntaggedObject::kTagBitsSizeTagPos -
+                               target::ObjectAlignment::kObjectAlignmentLog2);
+    __ Jump(&done, Assembler::kNearJump);
+
+    __ Bind(&size_tag_overflow);
+    // Set overflow size tag value.
+    __ LoadImmediate(kTemp, 0);
+
+    __ Bind(&done);
+    uword tags = target::MakeTagWordForNewSpaceObject(kSuspendStateCid, 0);
+    __ OrImmediate(kTemp, tags);
+    __ StoreToOffset(
+        kTemp,
+        FieldAddress(kSuspendState, target::Object::tags_offset()));  // Tags.
+  }
+
+  __ StoreToOffset(
+      kFrameSize,
+      FieldAddress(kSuspendState, target::SuspendState::frame_size_offset()));
+  __ StoreCompressedIntoObjectNoBarrier(
+      kSuspendState,
+      FieldAddress(kSuspendState, target::SuspendState::future_offset()),
+      kFuture);
+
+  {
+#if defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_RISCV32) ||              \
+    defined(TARGET_ARCH_RISCV64)
+    const Register kNullReg = NULL_REG;
+#else
+    const Register kNullReg = kTemp;
+    __ LoadObject(kNullReg, NullObject());
+#endif
+    __ StoreCompressedIntoObjectNoBarrier(
+        kSuspendState,
+        FieldAddress(kSuspendState,
+                     target::SuspendState::then_callback_offset()),
+        kNullReg);
+    __ StoreCompressedIntoObjectNoBarrier(
+        kSuspendState,
+        FieldAddress(kSuspendState,
+                     target::SuspendState::error_callback_offset()),
+        kNullReg);
+  }
+
+  __ Bind(&alloc_done);
+
+  __ Comment("Save SuspendState to frame");
+  __ LoadFromOffset(kTemp, Address(FPREG, kSavedCallerFpSlotFromFp *
+                                              compiler::target::kWordSize));
+  __ StoreToOffset(kSuspendState, Address(kTemp, SuspendStateFpOffset()));
+
+  __ Bind(&init_done);
+  __ Comment("Copy frame to SuspendState");
+
+  __ LoadFromOffset(
+      kTemp, Address(FPREG, kSavedCallerPcSlotFromFp * target::kWordSize));
+  __ StoreToOffset(
+      kTemp, FieldAddress(kSuspendState, target::SuspendState::pc_offset()));
+
+  if (kSrcFrame == THR) {
+    __ PushRegister(THR);
+  }
+  __ AddImmediate(kSrcFrame, FPREG, kCallerSpSlotFromFp * target::kWordSize);
+  __ AddImmediate(kDstFrame, kSuspendState,
+                  target::SuspendState::payload_offset() - kHeapObjectTag);
+  __ CopyMemoryWords(kSrcFrame, kDstFrame, kFrameSize, kTemp);
+  if (kSrcFrame == THR) {
+    __ PopRegister(THR);
+  }
+
+#ifdef DEBUG
+  {
+    Label okay;
+    __ LoadFromOffset(
+        kTemp,
+        FieldAddress(kSuspendState, target::SuspendState::frame_size_offset()));
+    __ AddRegisters(kTemp, kSuspendState);
+    __ LoadFromOffset(
+        kTemp, FieldAddress(kTemp, target::SuspendState::payload_offset() +
+                                       SuspendStateFpOffset()));
+    __ CompareRegisters(kTemp, kSuspendState);
+    __ BranchIf(EQUAL, &okay);
+    __ Breakpoint();
+    __ Bind(&okay);
+  }
+#endif
+
+  // Push arguments for _SuspendState._await* method.
+  __ PushRegister(kSuspendState);
+  __ PushRegister(kArgument);
+
+  // Write barrier.
+  __ BranchIfBit(kSuspendState, target::ObjectAlignment::kNewObjectBitPosition,
+                 ZERO, &old_gen_object);
+
+  __ Bind(&call_await);
+  __ Comment("Call _SuspendState._await method");
+  __ Call(Address(THR, suspend_entry_point_offset));
+
+  __ LeaveStubFrame();
+#if !defined(TARGET_ARCH_X64) && !defined(TARGET_ARCH_IA32)
+  // Drop caller frame on all architectures except x86 which needs to maintain
+  // call/return balance to avoid performance regressions.
+  __ LeaveDartFrame();
+#endif
+  __ Ret();
+
+#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64)
+  // Slow path is executed with Dart and stub frames still on the stack.
+  SPILLS_LR_TO_FRAME({});
+  SPILLS_LR_TO_FRAME({});
+#endif
+  __ Bind(&alloc_slow_case);
+  __ Comment("SuspendState Allocation slow case");
+  __ PushRegister(kArgument);   // Save argument.
+  __ PushRegister(kFrameSize);  // Save frame size.
+  __ PushObject(NullObject());  // Make space on stack for the return value.
+  __ SmiTag(kFrameSize);
+  __ PushRegister(kFrameSize);  // Pass frame size to runtime entry.
+  __ PushRegister(kFuture);     // Pass future.
+  __ CallRuntime(kAllocateSuspendStateRuntimeEntry, 2);
+  __ Drop(2);                     // Drop arguments
+  __ PopRegister(kSuspendState);  // Get result.
+  __ PopRegister(kFrameSize);     // Restore frame size.
+  __ PopRegister(kArgument);      // Restore argument.
+  __ Jump(&alloc_done);
+
+  __ Bind(&old_gen_object);
+  __ Comment("Old gen SuspendState slow case");
+  {
+#if defined(TARGET_ARCH_IA32)
+    LeafRuntimeScope rt(assembler, /*frame_size=*/2 * target::kWordSize,
+                        /*preserve_registers=*/false);
+    __ movl(Address(ESP, 1 * target::kWordSize), THR);
+    __ movl(Address(ESP, 0 * target::kWordSize), kSuspendState);
+#else
+    LeafRuntimeScope rt(assembler, /*frame_size=*/0,
+                        /*preserve_registers=*/false);
+    __ MoveRegister(CallingConventions::ArgumentRegisters[0], kSuspendState);
+    __ MoveRegister(CallingConventions::ArgumentRegisters[1], THR);
+#endif
+    rt.Call(kEnsureRememberedAndMarkingDeferredRuntimeEntry, 2);
+  }
+  __ Jump(&call_await);
+}
+
+void StubCodeCompiler::GenerateAwaitAsyncStub(Assembler* assembler) {
+  GenerateSuspendStub(
+      assembler,
+      target::Thread::suspend_state_await_async_entry_point_offset());
+}
+
+void StubCodeCompiler::GenerateInitSuspendableFunctionStub(
+    Assembler* assembler,
+    intptr_t init_entry_point_offset) {
+  const Register kTypeArgs = InitSuspendableFunctionStubABI::kTypeArgsReg;
+
+  __ EnterStubFrame();
+  __ LoadObject(ARGS_DESC_REG, ArgumentsDescriptorBoxed(/*type_args_len=*/1,
+                                                        /*num_arguments=*/0));
+  __ PushRegister(kTypeArgs);
+  __ Call(Address(THR, init_entry_point_offset));
+  __ LeaveStubFrame();
+
+  // Set :suspend_state in the caller frame.
+  __ StoreToOffset(CallingConventions::kReturnReg,
+                   Address(FPREG, SuspendStateFpOffset()));
+  __ Ret();
+}
+
+void StubCodeCompiler::GenerateInitAsyncStub(Assembler* assembler) {
+  GenerateInitSuspendableFunctionStub(
+      assembler, target::Thread::suspend_state_init_async_entry_point_offset());
+}
+
+void StubCodeCompiler::GenerateResumeStub(Assembler* assembler) {
+  const Register kSuspendState = ResumeStubABI::kSuspendStateReg;
+  const Register kTemp = ResumeStubABI::kTempReg;
+  const Register kFrameSize = ResumeStubABI::kFrameSizeReg;
+  const Register kSrcFrame = ResumeStubABI::kSrcFrameReg;
+  const Register kDstFrame = ResumeStubABI::kDstFrameReg;
+  const Register kResumePc = ResumeStubABI::kResumePcReg;
+  const Register kException = ResumeStubABI::kExceptionReg;
+  const Register kStackTrace = ResumeStubABI::kStackTraceReg;
+  Label rethrow_exception;
+
+  // Top of the stack on entry:
+  // ... [SuspendState] [value] [exception] [stackTrace] [ReturnAddress]
+
+  __ EnterDartFrame(0);
+
+  const intptr_t param_offset =
+      target::frame_layout.param_end_from_fp * target::kWordSize;
+  __ LoadFromOffset(kSuspendState,
+                    Address(FPREG, param_offset + 4 * target::kWordSize));
+#ifdef DEBUG
+  {
+    Label okay;
+    __ CompareClassId(kSuspendState, kSuspendStateCid, kTemp);
+    __ BranchIf(EQUAL, &okay);
+    __ Breakpoint();
+    __ Bind(&okay);
+  }
+#endif
+
+  __ LoadFromOffset(
+      kFrameSize,
+      FieldAddress(kSuspendState, target::SuspendState::frame_size_offset()));
+#ifdef DEBUG
+  {
+    Label okay;
+    __ MoveRegister(kTemp, kFrameSize);
+    __ AddRegisters(kTemp, kSuspendState);
+    __ LoadFromOffset(
+        kTemp, FieldAddress(kTemp, target::SuspendState::payload_offset() +
+                                       SuspendStateFpOffset()));
+    __ CompareRegisters(kTemp, kSuspendState);
+    __ BranchIf(EQUAL, &okay);
+    __ Breakpoint();
+    __ Bind(&okay);
+  }
+#endif
+  // Do not copy fixed frame between the first local and FP.
+  __ AddImmediate(kFrameSize, (target::frame_layout.first_local_from_fp + 1) *
+                                  target::kWordSize);
+  __ SubRegisters(SPREG, kFrameSize);
+
+  __ Comment("Copy frame from SuspendState");
+  __ AddImmediate(kSrcFrame, kSuspendState,
+                  target::SuspendState::payload_offset() - kHeapObjectTag);
+  __ MoveRegister(kDstFrame, SPREG);
+  __ CopyMemoryWords(kSrcFrame, kDstFrame, kFrameSize, kTemp);
+
+  __ Comment("Transfer control");
+
+  __ LoadFromOffset(kResumePc, FieldAddress(kSuspendState,
+                                            target::SuspendState::pc_offset()));
+  __ StoreZero(FieldAddress(kSuspendState, target::SuspendState::pc_offset()),
+               kTemp);
+
+  __ LoadFromOffset(kException,
+                    Address(FPREG, param_offset + 2 * target::kWordSize));
+  __ CompareObject(kException, NullObject());
+  __ BranchIf(NOT_EQUAL, &rethrow_exception);
+
+#if defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_IA32)
+  // Adjust resume PC to skip extra epilogue generated on x86
+  // right after the call to suspend stub in order to maintain
+  // call/return balance.
+  __ AddImmediate(kResumePc, SuspendStubABI::kResumePcDistance);
+#endif
+
+  __ LoadFromOffset(CallingConventions::kReturnReg,
+                    Address(FPREG, param_offset + 3 * target::kWordSize));
+
+  __ Jump(kResumePc);
+
+  __ Comment("Rethrow exception");
+  __ Bind(&rethrow_exception);
+
+  __ LoadFromOffset(kStackTrace,
+                    Address(FPREG, param_offset + 1 * target::kWordSize));
+
+  // Adjust stack/LR/RA as if suspended Dart function called
+  // stub with kResumePc as a return address.
+#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
+  __ PushRegister(kResumePc);
+#elif defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64)
+  RESTORES_RETURN_ADDRESS_FROM_REGISTER_TO_LR(__ MoveRegister(LR, kResumePc));
+#elif defined(TARGET_ARCH_RISCV32) || defined(TARGET_ARCH_RISCV64)
+  __ MoveRegister(RA, kResumePc);
+#else
+#error Unknown target
+#endif
+
+#if !defined(TARGET_ARCH_IA32)
+  __ set_constant_pool_allowed(false);
+#endif
+  __ EnterStubFrame();
+  __ PushObject(NullObject());  // Make room for (unused) result.
+  __ PushRegister(kException);
+  __ PushRegister(kStackTrace);
+  __ CallRuntime(kReThrowRuntimeEntry, /*argument_count=*/2);
+  __ Breakpoint();
+}
+
+void StubCodeCompiler::GenerateReturnStub(Assembler* assembler,
+                                          intptr_t return_entry_point_offset) {
+  const Register kSuspendState = ReturnStubABI::kSuspendStateReg;
+
+#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64)
+  SPILLS_LR_TO_FRAME({});  // Simulate entering the caller (Dart) frame.
+#endif
+
+  __ LoadFromOffset(kSuspendState, Address(FPREG, SuspendStateFpOffset()));
+  __ LeaveDartFrame();
+
+  __ EnterStubFrame();
+  __ PushRegister(kSuspendState);
+  __ PushRegister(CallingConventions::kReturnReg);
+  __ Call(Address(THR, return_entry_point_offset));
+  __ LeaveStubFrame();
+  __ Ret();
+}
+
+void StubCodeCompiler::GenerateReturnAsyncStub(Assembler* assembler) {
+  GenerateReturnStub(
+      assembler,
+      target::Thread::suspend_state_return_async_entry_point_offset());
+}
+
+void StubCodeCompiler::GenerateReturnAsyncNotFutureStub(Assembler* assembler) {
+  GenerateReturnStub(
+      assembler,
+      target::Thread::
+          suspend_state_return_async_not_future_entry_point_offset());
+}
+
+void StubCodeCompiler::GenerateAsyncExceptionHandlerStub(Assembler* assembler) {
+  const Register kSuspendState = AsyncExceptionHandlerStubABI::kSuspendStateReg;
+  ASSERT(kSuspendState != kExceptionObjectReg);
+  ASSERT(kSuspendState != kStackTraceObjectReg);
+  Label rethrow_exception;
+
+#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64)
+  SPILLS_LR_TO_FRAME({});  // Simulate entering the caller (Dart) frame.
+#endif
+
+  __ LoadFromOffset(kSuspendState, Address(FPREG, SuspendStateFpOffset()));
+
+  // Check if suspend_state is initialized. Otherwise
+  // exception was thrown from the prologue code and
+  // should be synchronuously propagated.
+  __ CompareObject(kSuspendState, NullObject());
+  __ BranchIf(EQUAL, &rethrow_exception);
+
+  __ LeaveDartFrame();
+  __ EnterStubFrame();
+  __ PushRegister(kSuspendState);
+  __ PushRegister(kExceptionObjectReg);
+  __ PushRegister(kStackTraceObjectReg);
+  __ Call(Address(
+      THR,
+      target::Thread::suspend_state_handle_exception_entry_point_offset()));
+  __ LeaveStubFrame();
+  __ Ret();
+
+#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64)
+  // Rethrow case is used when Dart frame is still on the stack.
+  SPILLS_LR_TO_FRAME({});
+#endif
+  __ Comment("Rethrow exception");
+  __ Bind(&rethrow_exception);
+  __ LeaveDartFrame();
+  __ EnterStubFrame();
+  __ PushObject(NullObject());  // Make room for (unused) result.
+  __ PushRegister(kExceptionObjectReg);
+  __ PushRegister(kStackTraceObjectReg);
+  __ CallRuntime(kReThrowRuntimeEntry, /*argument_count=*/2);
+  __ Breakpoint();
+}
+
 }  // namespace compiler
 
 }  // namespace dart
diff --git a/runtime/vm/compiler/stub_code_compiler.h b/runtime/vm/compiler/stub_code_compiler.h
index 7dd9e8f..7cd39e1 100644
--- a/runtime/vm/compiler/stub_code_compiler.h
+++ b/runtime/vm/compiler/stub_code_compiler.h
@@ -198,6 +198,14 @@
                                               bool with_fpu_regs);
 
   static void GenerateRangeError(Assembler* assembler, bool with_fpu_regs);
+
+  static void GenerateSuspendStub(Assembler* assembler,
+                                  intptr_t suspend_entry_point_offset);
+  static void GenerateInitSuspendableFunctionStub(
+      Assembler* assembler,
+      intptr_t init_entry_point_offset);
+  static void GenerateReturnStub(Assembler* assembler,
+                                 intptr_t return_entry_point_offset);
 };
 
 }  // namespace compiler
diff --git a/runtime/vm/compiler/stub_code_compiler_arm.cc b/runtime/vm/compiler/stub_code_compiler_arm.cc
index dda5901..177186a 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm.cc
@@ -1040,8 +1040,7 @@
     __ b(&slow_case, HI);
 
     const intptr_t cid = kArrayCid;
-    NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R4, cid));
-    NOT_IN_PRODUCT(__ MaybeTraceAllocation(R4, &slow_case));
+    NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, &slow_case, R4));
 
     const intptr_t fixed_size_plus_alignment_padding =
         target::Array::header_size() +
@@ -1346,8 +1345,7 @@
   ASSERT(kSmiTagShift == 1);
   __ bic(R2, R2, Operand(target::ObjectAlignment::kObjectAlignment - 1));
 
-  NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R8, kContextCid));
-  NOT_IN_PRODUCT(__ MaybeTraceAllocation(R8, slow_case));
+  NOT_IN_PRODUCT(__ MaybeTraceAllocation(kContextCid, slow_case, R8));
   // Now allocate the object.
   // R1: number of context variables.
   // R2: object size.
@@ -3432,8 +3430,7 @@
 
   if (!FLAG_use_slow_path && FLAG_inline_alloc) {
     Label call_runtime;
-    NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R2, cid));
-    NOT_IN_PRODUCT(__ MaybeTraceAllocation(R2, &call_runtime));
+    NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, &call_runtime, R2));
     __ mov(R2, Operand(AllocateTypedDataArrayABI::kLengthReg));
     /* Check that length is a positive Smi. */
     /* R2: requested array length argument. */
diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc
index 3a5737b..a3cb533 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc
@@ -1285,7 +1285,7 @@
     __ b(&slow_case, HI);
 
     const intptr_t cid = kArrayCid;
-    NOT_IN_PRODUCT(__ MaybeTraceAllocation(kArrayCid, R4, &slow_case));
+    NOT_IN_PRODUCT(__ MaybeTraceAllocation(kArrayCid, &slow_case, R4));
 
     // Calculate and align allocation size.
     // Load new object start and calculate next object start.
@@ -1630,7 +1630,7 @@
   ASSERT(kSmiTagShift == 1);
   __ andi(R2, R2, Immediate(~(target::ObjectAlignment::kObjectAlignment - 1)));
 
-  NOT_IN_PRODUCT(__ MaybeTraceAllocation(kContextCid, R4, slow_case));
+  NOT_IN_PRODUCT(__ MaybeTraceAllocation(kContextCid, slow_case, R4));
   // Now allocate the object.
   // R1: number of context variables.
   // R2: object size.
@@ -3784,7 +3784,7 @@
 
   if (!FLAG_use_slow_path && FLAG_inline_alloc) {
     Label call_runtime;
-    NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, R2, &call_runtime));
+    NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, &call_runtime, R2));
     __ mov(R2, AllocateTypedDataArrayABI::kLengthReg);
     /* Check that length is a positive Smi. */
     /* R2: requested array length argument. */
diff --git a/runtime/vm/compiler/stub_code_compiler_ia32.cc b/runtime/vm/compiler/stub_code_compiler_ia32.cc
index 05c9646..60760eb 100644
--- a/runtime/vm/compiler/stub_code_compiler_ia32.cc
+++ b/runtime/vm/compiler/stub_code_compiler_ia32.cc
@@ -673,7 +673,7 @@
             Address(EBP, saved_stacktrace_slot_from_fp * target::kWordSize));
   }
 
-  __ LeaveFrame();
+  __ LeaveDartFrame();
   __ popl(EDX);       // Preserve return address.
   __ movl(ESP, EBP);  // Discard optimized frame.
   __ subl(ESP, EAX);  // Reserve space for deoptimized frame.
@@ -706,7 +706,7 @@
                                   target::kWordSize));
   }
   // Code above cannot cause GC.
-  __ LeaveFrame();
+  __ LeaveDartFrame();
 
   // Frame is fully rewritten at this point and it is safe to perform a GC.
   // Materialize any objects that were deferred by FillFrame because they
@@ -730,7 +730,7 @@
     __ popl(EDX);  // Restore exception.
     __ popl(EAX);  // Restore stacktrace.
   }
-  __ LeaveFrame();
+  __ LeaveStubFrame();
 
   __ popl(ECX);       // Pop return address.
   __ addl(ESP, EBX);  // Remove materialization arguments.
@@ -838,9 +838,8 @@
     __ cmpl(AllocateArrayABI::kLengthReg, max_len);
     __ j(ABOVE, &slow_case);
 
-    NOT_IN_PRODUCT(__ MaybeTraceAllocation(kArrayCid,
-                                           AllocateArrayABI::kResultReg,
-                                           &slow_case, Assembler::kFarJump));
+    NOT_IN_PRODUCT(__ MaybeTraceAllocation(kArrayCid, &slow_case,
+                                           AllocateArrayABI::kResultReg));
 
     const intptr_t fixed_size_plus_alignment_padding =
         target::Array::header_size() +
@@ -1116,8 +1115,7 @@
   __ leal(EBX, Address(EDX, TIMES_4, fixed_size_plus_alignment_padding));
   __ andl(EBX, Immediate(-target::ObjectAlignment::kObjectAlignment));
 
-  NOT_IN_PRODUCT(__ MaybeTraceAllocation(kContextCid, EAX, slow_case,
-                                         Assembler::kFarJump));
+  NOT_IN_PRODUCT(__ MaybeTraceAllocation(kContextCid, slow_case, EAX));
 
   // Now allocate the object.
   // EDX: number of context variables.
@@ -2988,8 +2986,7 @@
     Label call_runtime;
     __ pushl(AllocateTypedDataArrayABI::kLengthReg);
 
-    NOT_IN_PRODUCT(
-        __ MaybeTraceAllocation(cid, ECX, &call_runtime, Assembler::kFarJump));
+    NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, &call_runtime, ECX));
     __ movl(EDI, AllocateTypedDataArrayABI::kLengthReg);
     /* Check that length is a positive Smi. */
     /* EDI: requested array length argument. */
diff --git a/runtime/vm/compiler/stub_code_compiler_riscv.cc b/runtime/vm/compiler/stub_code_compiler_riscv.cc
index b9b67fd..55fc441 100644
--- a/runtime/vm/compiler/stub_code_compiler_riscv.cc
+++ b/runtime/vm/compiler/stub_code_compiler_riscv.cc
@@ -1103,7 +1103,7 @@
     __ BranchIf(HI, &slow_case);
 
     const intptr_t cid = kArrayCid;
-    NOT_IN_PRODUCT(__ MaybeTraceAllocation(kArrayCid, T4, &slow_case));
+    NOT_IN_PRODUCT(__ MaybeTraceAllocation(kArrayCid, &slow_case, T4));
 
     // Calculate and align allocation size.
     // Load new object start and calculate next object start.
@@ -1431,7 +1431,7 @@
   __ AddImmediate(T2, fixed_size_plus_alignment_padding);
   __ andi(T2, T2, ~(target::ObjectAlignment::kObjectAlignment - 1));
 
-  NOT_IN_PRODUCT(__ MaybeTraceAllocation(kContextCid, T4, slow_case));
+  NOT_IN_PRODUCT(__ MaybeTraceAllocation(kContextCid, slow_case, T4));
   // Now allocate the object.
   // T1: number of context variables.
   // T2: object size.
@@ -3562,7 +3562,7 @@
 
   if (!FLAG_use_slow_path && FLAG_inline_alloc) {
     Label call_runtime;
-    NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, T3, &call_runtime));
+    NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, &call_runtime, T3));
     __ mv(T3, AllocateTypedDataArrayABI::kLengthReg);
     /* Check that length is a positive Smi. */
     /* T3: requested array length argument. */
diff --git a/runtime/vm/compiler/stub_code_compiler_x64.cc b/runtime/vm/compiler/stub_code_compiler_x64.cc
index c549f75..0dc8e25 100644
--- a/runtime/vm/compiler/stub_code_compiler_x64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_x64.cc
@@ -1207,8 +1207,7 @@
     __ j(ABOVE, &slow_case);
 
     // Check for allocation tracing.
-    NOT_IN_PRODUCT(
-        __ MaybeTraceAllocation(kArrayCid, &slow_case, Assembler::kFarJump));
+    NOT_IN_PRODUCT(__ MaybeTraceAllocation(kArrayCid, &slow_case));
 
     const intptr_t fixed_size_plus_alignment_padding =
         target::Array::header_size() +
@@ -1542,8 +1541,7 @@
   __ andq(R13, Immediate(-target::ObjectAlignment::kObjectAlignment));
 
   // Check for allocation tracing.
-  NOT_IN_PRODUCT(
-      __ MaybeTraceAllocation(kContextCid, slow_case, Assembler::kFarJump));
+  NOT_IN_PRODUCT(__ MaybeTraceAllocation(kContextCid, slow_case));
 
   // Now allocate the object.
   // R10: number of context variables.
@@ -3691,8 +3689,7 @@
     Label call_runtime;
     __ pushq(AllocateTypedDataArrayABI::kLengthReg);
 
-    NOT_IN_PRODUCT(
-        __ MaybeTraceAllocation(cid, &call_runtime, Assembler::kFarJump));
+    NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, &call_runtime));
     __ movq(RDI, AllocateTypedDataArrayABI::kLengthReg);
     /* Check that length is a positive Smi. */
     /* RDI: requested array length argument. */
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index e3dc87a..722f126 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -532,6 +532,47 @@
   static const Register kResultReg = R0;
 };
 
+// ABI for SuspendStub (AwaitAsyncStub).
+struct SuspendStubABI {
+  static const Register kArgumentReg = R0;
+  static const Register kTempReg = R1;
+  static const Register kFrameSizeReg = R2;
+  static const Register kSuspendStateReg = R3;
+  static const Register kFutureReg = R4;
+  static const Register kSrcFrameReg = R8;
+  static const Register kDstFrameReg = R9;
+};
+
+// ABI for InitSuspendableFunctionStub (InitAsyncStub).
+struct InitSuspendableFunctionStubABI {
+  static const Register kTypeArgsReg = R0;
+};
+
+// ABI for ResumeStub
+struct ResumeStubABI {
+  static const Register kSuspendStateReg = R2;
+  static const Register kTempReg = R0;
+  // Registers for the frame copying (the 1st part).
+  static const Register kFrameSizeReg = R1;
+  static const Register kSrcFrameReg = R3;
+  static const Register kDstFrameReg = R4;
+  // Registers for control transfer.
+  // (the 2nd part, can reuse registers from the 1st part)
+  static const Register kResumePcReg = R1;
+  static const Register kExceptionReg = R3;
+  static const Register kStackTraceReg = R4;
+};
+
+// ABI for ReturnStub (ReturnAsyncStub, ReturnAsyncNotFutureStub).
+struct ReturnStubABI {
+  static const Register kSuspendStateReg = R2;
+};
+
+// ABI for AsyncExceptionHandlerStub.
+struct AsyncExceptionHandlerStubABI {
+  static const Register kSuspendStateReg = R2;
+};
+
 // ABI for DispatchTableNullErrorStub and consequently for all dispatch
 // table calls (though normal functions will not expect or use this
 // register). This ABI is added to distinguish memory corruption errors from
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index 03fc499..da0c132 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -366,6 +366,47 @@
   static const Register kResultReg = R0;
 };
 
+// ABI for SuspendStub (AwaitAsyncStub).
+struct SuspendStubABI {
+  static const Register kArgumentReg = R0;
+  static const Register kTempReg = R1;
+  static const Register kFrameSizeReg = R2;
+  static const Register kSuspendStateReg = R3;
+  static const Register kFutureReg = R4;
+  static const Register kSrcFrameReg = R5;
+  static const Register kDstFrameReg = R6;
+};
+
+// ABI for InitSuspendableFunctionStub (InitAsyncStub).
+struct InitSuspendableFunctionStubABI {
+  static const Register kTypeArgsReg = R0;
+};
+
+// ABI for ResumeStub
+struct ResumeStubABI {
+  static const Register kSuspendStateReg = R2;
+  static const Register kTempReg = R0;
+  // Registers for the frame copying (the 1st part).
+  static const Register kFrameSizeReg = R1;
+  static const Register kSrcFrameReg = R3;
+  static const Register kDstFrameReg = R4;
+  // Registers for control transfer.
+  // (the 2nd part, can reuse registers from the 1st part)
+  static const Register kResumePcReg = R1;
+  static const Register kExceptionReg = R3;
+  static const Register kStackTraceReg = R4;
+};
+
+// ABI for ReturnStub (ReturnAsyncStub, ReturnAsyncNotFutureStub).
+struct ReturnStubABI {
+  static const Register kSuspendStateReg = R2;
+};
+
+// ABI for AsyncExceptionHandlerStub.
+struct AsyncExceptionHandlerStubABI {
+  static const Register kSuspendStateReg = R2;
+};
+
 // ABI for DispatchTableNullErrorStub and consequently for all dispatch
 // table calls (though normal functions will not expect or use this
 // register). This ABI is added to distinguish memory corruption errors from
diff --git a/runtime/vm/constants_ia32.h b/runtime/vm/constants_ia32.h
index ab67693..2fa9890 100644
--- a/runtime/vm/constants_ia32.h
+++ b/runtime/vm/constants_ia32.h
@@ -260,6 +260,54 @@
   static const Register kResultReg = EAX;
 };
 
+// ABI for SuspendStub (AwaitAsyncStub).
+struct SuspendStubABI {
+  static const Register kArgumentReg = EAX;
+  static const Register kTempReg = EDX;
+  static const Register kFrameSizeReg = ECX;
+  static const Register kSuspendStateReg = EBX;
+  static const Register kFutureReg = EDI;
+  // Can reuse THR.
+  static const Register kSrcFrameReg = ESI;
+  // Can reuse kFutureReg.
+  static const Register kDstFrameReg = EDI;
+
+  // Number of bytes to skip after
+  // suspend stub return address in order to resume.
+  // IA32: mov esp, ebp; pop ebp; ret
+  static const intptr_t kResumePcDistance = 5;
+};
+
+// ABI for InitSuspendableFunctionStub (InitAsyncStub).
+struct InitSuspendableFunctionStubABI {
+  static const Register kTypeArgsReg = EAX;
+};
+
+// ABI for ResumeStub
+struct ResumeStubABI {
+  static const Register kSuspendStateReg = EBX;
+  static const Register kTempReg = EDX;
+  // Registers for the frame copying (the 1st part).
+  static const Register kFrameSizeReg = ECX;
+  static const Register kSrcFrameReg = ESI;
+  static const Register kDstFrameReg = EDI;
+  // Registers for control transfer.
+  // (the 2nd part, can reuse registers from the 1st part)
+  static const Register kResumePcReg = ECX;
+  static const Register kExceptionReg = ESI;
+  static const Register kStackTraceReg = EDI;
+};
+
+// ABI for ReturnStub (ReturnAsyncStub, ReturnAsyncNotFutureStub).
+struct ReturnStubABI {
+  static const Register kSuspendStateReg = EBX;
+};
+
+// ABI for AsyncExceptionHandlerStub.
+struct AsyncExceptionHandlerStubABI {
+  static const Register kSuspendStateReg = EBX;
+};
+
 // ABI for DispatchTableNullErrorStub and consequently for all dispatch
 // table calls (though normal functions will not expect or use this
 // register). This ABI is added to distinguish memory corruption errors from
diff --git a/runtime/vm/constants_riscv.h b/runtime/vm/constants_riscv.h
index 707caf7..8d7a085 100644
--- a/runtime/vm/constants_riscv.h
+++ b/runtime/vm/constants_riscv.h
@@ -378,6 +378,47 @@
   static constexpr Register kResultReg = A0;
 };
 
+// ABI for SuspendStub (AwaitAsyncStub).
+struct SuspendStubABI {
+  static const Register kArgumentReg = A0;
+  static const Register kTempReg = T0;
+  static const Register kFrameSizeReg = T1;
+  static const Register kSuspendStateReg = T2;
+  static const Register kFutureReg = T3;
+  static const Register kSrcFrameReg = T4;
+  static const Register kDstFrameReg = T5;
+};
+
+// ABI for InitSuspendableFunctionStub (InitAsyncStub).
+struct InitSuspendableFunctionStubABI {
+  static const Register kTypeArgsReg = A0;
+};
+
+// ABI for ResumeStub
+struct ResumeStubABI {
+  static const Register kSuspendStateReg = T1;
+  static const Register kTempReg = T0;
+  // Registers for the frame copying (the 1st part).
+  static const Register kFrameSizeReg = T2;
+  static const Register kSrcFrameReg = T3;
+  static const Register kDstFrameReg = T4;
+  // Registers for control transfer.
+  // (the 2nd part, can reuse registers from the 1st part)
+  static const Register kResumePcReg = T2;
+  static const Register kExceptionReg = T3;
+  static const Register kStackTraceReg = T4;
+};
+
+// ABI for ReturnStub (ReturnAsyncStub, ReturnAsyncNotFutureStub).
+struct ReturnStubABI {
+  static const Register kSuspendStateReg = T1;
+};
+
+// ABI for AsyncExceptionHandlerStub.
+struct AsyncExceptionHandlerStubABI {
+  static const Register kSuspendStateReg = T1;
+};
+
 // ABI for DispatchTableNullErrorStub and consequently for all dispatch
 // table calls (though normal functions will not expect or use this
 // register). This ABI is added to distinguish memory corruption errors from
diff --git a/runtime/vm/constants_x64.h b/runtime/vm/constants_x64.h
index 9b8e5c2..1f22126 100644
--- a/runtime/vm/constants_x64.h
+++ b/runtime/vm/constants_x64.h
@@ -335,6 +335,52 @@
   static const Register kResultReg = RAX;
 };
 
+// ABI for SuspendStub (AwaitAsyncStub).
+struct SuspendStubABI {
+  static const Register kArgumentReg = RAX;
+  static const Register kTempReg = RDX;
+  static const Register kFrameSizeReg = RCX;
+  static const Register kSuspendStateReg = RBX;
+  static const Register kFutureReg = R8;
+  static const Register kSrcFrameReg = RSI;
+  static const Register kDstFrameReg = RDI;
+
+  // Number of bytes to skip after
+  // suspend stub return address in order to resume.
+  // X64: mov rsp, rbp; pop rbp; ret
+  static const intptr_t kResumePcDistance = 5;
+};
+
+// ABI for InitSuspendableFunctionStub (InitAsyncStub).
+struct InitSuspendableFunctionStubABI {
+  static const Register kTypeArgsReg = RAX;
+};
+
+// ABI for ResumeStub
+struct ResumeStubABI {
+  static const Register kSuspendStateReg = RBX;
+  static const Register kTempReg = RDX;
+  // Registers for the frame copying (the 1st part).
+  static const Register kFrameSizeReg = RCX;
+  static const Register kSrcFrameReg = RSI;
+  static const Register kDstFrameReg = RDI;
+  // Registers for control transfer.
+  // (the 2nd part, can reuse registers from the 1st part)
+  static const Register kResumePcReg = RCX;
+  static const Register kExceptionReg = RSI;
+  static const Register kStackTraceReg = RDI;
+};
+
+// ABI for ReturnStub (ReturnAsyncStub, ReturnAsyncNotFutureStub).
+struct ReturnStubABI {
+  static const Register kSuspendStateReg = RBX;
+};
+
+// ABI for AsyncExceptionHandlerStub.
+struct AsyncExceptionHandlerStubABI {
+  static const Register kSuspendStateReg = RBX;
+};
+
 // ABI for DispatchTableNullErrorStub and consequently for all dispatch
 // table calls (though normal functions will not expect or use this
 // register). This ABI is added to distinguish memory corruption errors from
diff --git a/runtime/vm/datastream.h b/runtime/vm/datastream.h
index 09ec2e7..974cb88 100644
--- a/runtime/vm/datastream.h
+++ b/runtime/vm/datastream.h
@@ -313,10 +313,14 @@
   }
 
  private:
+  ReadStream(const uint8_t* buffer, const uint8_t* current, const uint8_t* end)
+      : buffer_(buffer), current_(current), end_(end) {}
+
   const uint8_t* buffer_;
   const uint8_t* current_;
   const uint8_t* end_;
 
+  friend class Deserializer;
   DISALLOW_COPY_AND_ASSIGN(ReadStream);
 };
 
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index 76ee165c..11e6086 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -71,12 +71,12 @@
   // Do not include incoming arguments if there are optional arguments
   // (they are copied into local space at method entry).
   num_args_ =
-      function.HasOptionalParameters() ? 0 : function.num_fixed_parameters();
+      function.MakesCopyOfParameters() ? 0 : function.num_fixed_parameters();
 
-// The fixed size section of the (fake) Dart frame called via a stub by the
-// optimized function contains FP, PP (ARM only), PC-marker and
-// return-address. This section is copied as well, so that its contained
-// values can be updated before returning to the deoptimized function.
+  // The fixed size section of the (fake) Dart frame called via a stub by the
+  // optimized function contains FP, PP (ARM only), PC-marker and
+  // return-address. This section is copied as well, so that its contained
+  // values can be updated before returning to the deoptimized function.
   ASSERT(frame->fp() >= frame->sp());
   const intptr_t frame_size = (frame->fp() - frame->sp()) / kWordSize;
 
@@ -326,7 +326,7 @@
 
   Function& function = Function::Handle(zone(), code.function());
   intptr_t params =
-      function.HasOptionalParameters() ? 0 : function.num_fixed_parameters();
+      function.MakesCopyOfParameters() ? 0 : function.num_fixed_parameters();
   for (intptr_t i = 0; i < num_vars; i++) {
     const intptr_t len = deopt_instructions.length();
     intptr_t slot = i < params ? i
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index aeb4640..8d08c18 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -149,7 +149,9 @@
             handler_pc = temp_handler_pc;
             handler_sp = frame->sp();
             handler_fp = frame->fp();
-            if (is_optimized) {
+            if (is_optimized &&
+                (handler_pc !=
+                 StubCode::AsyncExceptionHandler().EntryPoint())) {
               pc_ = frame->pc();
               code_ = &Code::Handle(frame->LookupDartCode());
               CatchEntryMovesRefPtr* cached_catch_entry_moves =
diff --git a/runtime/vm/heap/compactor.cc b/runtime/vm/heap/compactor.cc
index 2051b0c..e5a5c3e 100644
--- a/runtime/vm/heap/compactor.cc
+++ b/runtime/vm/heap/compactor.cc
@@ -313,6 +313,19 @@
     ForwardStackPointers();
   }
 
+  {
+    TIMELINE_FUNCTION_GC_DURATION(thread(),
+                                  "ForwardPostponedSuspendStatePointers");
+    // After heap sliding is complete and ObjectStore pointers are forwarded
+    // it is finally safe to visit SuspendState objects with copied frames.
+    can_visit_stack_frames_ = true;
+    const intptr_t length = postponed_suspend_states_.length();
+    for (intptr_t i = 0; i < length; ++i) {
+      auto suspend_state = postponed_suspend_states_[i];
+      suspend_state->untag()->VisitPointers(this);
+    }
+  }
+
   heap_->old_space()->VisitRoots(this);
 
   {
@@ -741,6 +754,21 @@
   }
 }
 
+bool GCCompactor::CanVisitSuspendStatePointers(SuspendStatePtr suspend_state) {
+  if ((suspend_state->untag()->pc() != 0) && !can_visit_stack_frames_) {
+    // Visiting pointers of SuspendState objects with copied stack frame
+    // needs to query stack map, which can touch other Dart objects
+    // (such as GrowableObjectArray of InstructionsTable).
+    // Those objects may have an inconsistent state during compaction,
+    // so processing of SuspendState objects is postponed to the later
+    // stage of compaction.
+    MutexLocker ml(&postponed_suspend_states_mutex_);
+    postponed_suspend_states_.Add(suspend_state);
+    return false;
+  }
+  return true;
+}
+
 void GCCompactor::VisitHandle(uword addr) {
   FinalizablePersistentHandle* handle =
       reinterpret_cast<FinalizablePersistentHandle*>(addr);
diff --git a/runtime/vm/heap/compactor.h b/runtime/vm/heap/compactor.h
index 164c214..cff7736 100644
--- a/runtime/vm/heap/compactor.h
+++ b/runtime/vm/heap/compactor.h
@@ -41,12 +41,13 @@
   void ForwardCompressedPointer(uword heap_base, CompressedObjectPtr* ptr);
   void VisitTypedDataViewPointers(TypedDataViewPtr view,
                                   CompressedObjectPtr* first,
-                                  CompressedObjectPtr* last);
-  void VisitPointers(ObjectPtr* first, ObjectPtr* last);
+                                  CompressedObjectPtr* last) override;
+  void VisitPointers(ObjectPtr* first, ObjectPtr* last) override;
   void VisitCompressedPointers(uword heap_base,
                                CompressedObjectPtr* first,
-                               CompressedObjectPtr* last);
-  void VisitHandle(uword addr);
+                               CompressedObjectPtr* last) override;
+  bool CanVisitSuspendStatePointers(SuspendStatePtr suspend_state) override;
+  void VisitHandle(uword addr) override;
 
   Heap* heap_;
 
@@ -71,6 +72,12 @@
   // complete.
   Mutex typed_data_view_mutex_;
   MallocGrowableArray<TypedDataViewPtr> typed_data_views_;
+
+  // SuspendState objects with copied frame must be updated after sliding is
+  // complete.
+  bool can_visit_stack_frames_ = false;
+  Mutex postponed_suspend_states_mutex_;
+  MallocGrowableArray<SuspendStatePtr> postponed_suspend_states_;
 };
 
 }  // namespace dart
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index ae4909f..3fa948a 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -48,6 +48,7 @@
 #include "vm/stub_code.h"
 #include "vm/symbols.h"
 #include "vm/tags.h"
+#include "vm/thread.h"
 #include "vm/thread_interrupter.h"
 #include "vm/thread_registry.h"
 #include "vm/timeline.h"
@@ -613,6 +614,12 @@
     thread->isolate_ = nullptr;
     thread->isolate_group_ = this;
     thread->field_table_values_ = nullptr;
+    if (object_store() != nullptr) {
+#define INIT_ENTRY_POINT(name)                                                 \
+  thread->name##_entry_point_ = Function::EntryPointOf(object_store()->name());
+      CACHED_FUNCTION_ENTRY_POINTS_LIST(INIT_ENTRY_POINT)
+#undef INIT_ENTRY_POINT
+    }
     ASSERT(heap() != nullptr);
     thread->heap_ = heap();
     thread->set_os_thread(os_thread);
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 269048c..ffb8a64 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -574,7 +574,7 @@
   void IncreaseMutatorCount(Isolate* mutator, bool is_nested_reenter);
   void DecreaseMutatorCount(Isolate* mutator, bool is_nested_exit);
   intptr_t MutatorCount() const {
-    ASSERT(Thread::Current()->IsAtSafepoint());  // Otherwise lock is needed.
+    MonitorLocker ml(active_mutators_monitor_.get());
     return active_mutators_;
   }
 
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index f5e8986..3dcbc81 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -2030,28 +2030,40 @@
 
   FunctionNodeHelper function_node_helper(&helper_);
   function_node_helper.ReadUntilIncluding(FunctionNodeHelper::kDartAsyncMarker);
-  function.set_is_debuggable(function_node_helper.dart_async_marker_ ==
-                             FunctionNodeHelper::kSync);
-  switch (function_node_helper.dart_async_marker_) {
-    case FunctionNodeHelper::kSyncStar:
-      function.set_modifier(UntaggedFunction::kSyncGen);
-      function.set_is_visible(!FLAG_lazy_async_stacks);
-      break;
-    case FunctionNodeHelper::kAsync:
-      function.set_modifier(UntaggedFunction::kAsync);
-      function.set_is_inlinable(!FLAG_lazy_async_stacks);
-      function.set_is_visible(!FLAG_lazy_async_stacks);
-      break;
-    case FunctionNodeHelper::kAsyncStar:
-      function.set_modifier(UntaggedFunction::kAsyncGen);
-      function.set_is_inlinable(!FLAG_lazy_async_stacks);
-      function.set_is_visible(!FLAG_lazy_async_stacks);
-      break;
-    default:
-      // no special modifier
-      break;
+  if (function_node_helper.async_marker_ == FunctionNodeHelper::kAsync) {
+    if (!FLAG_precompiled_mode) {
+      FATAL("Compact async functions are only supported in AOT mode.");
+    }
+    function.set_modifier(UntaggedFunction::kAsync);
+    function.set_is_debuggable(true);
+    function.set_is_inlinable(false);
+    function.set_is_visible(true);
+    ASSERT(function.IsCompactAsyncFunction());
+  } else {
+    ASSERT(function_node_helper.async_marker_ == FunctionNodeHelper::kSync);
+    function.set_is_debuggable(function_node_helper.dart_async_marker_ ==
+                               FunctionNodeHelper::kSync);
+    switch (function_node_helper.dart_async_marker_) {
+      case FunctionNodeHelper::kSyncStar:
+        function.set_modifier(UntaggedFunction::kSyncGen);
+        function.set_is_visible(!FLAG_lazy_async_stacks);
+        break;
+      case FunctionNodeHelper::kAsync:
+        function.set_modifier(UntaggedFunction::kAsync);
+        function.set_is_inlinable(!FLAG_lazy_async_stacks);
+        function.set_is_visible(!FLAG_lazy_async_stacks);
+        break;
+      case FunctionNodeHelper::kAsyncStar:
+        function.set_modifier(UntaggedFunction::kAsyncGen);
+        function.set_is_inlinable(!FLAG_lazy_async_stacks);
+        function.set_is_visible(!FLAG_lazy_async_stacks);
+        break;
+      default:
+        // no special modifier
+        break;
+    }
+    ASSERT(!function.IsCompactAsyncFunction());
   }
-  ASSERT(function_node_helper.async_marker_ == FunctionNodeHelper::kSync);
 
   if (!native_name.IsNull()) {
     function.set_native_name(native_name);
diff --git a/runtime/vm/message_snapshot.cc b/runtime/vm/message_snapshot.cc
index 9bd1a91..48f6aec 100644
--- a/runtime/vm/message_snapshot.cc
+++ b/runtime/vm/message_snapshot.cc
@@ -3241,6 +3241,7 @@
     ILLEGAL(MirrorReference)
     ILLEGAL(ReceivePort)
     ILLEGAL(StackTrace)
+    ILLEGAL(SuspendState)
     ILLEGAL(UserTag)
 
     // From "dart:ffi" we handle only Pointer/DynamicLibrary specially, since
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index bc8a1fe..a9fffe2 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -55,6 +55,7 @@
 #include "vm/regexp.h"
 #include "vm/resolver.h"
 #include "vm/reusable_handles.h"
+#include "vm/reverse_pc_lookup_cache.h"
 #include "vm/runtime_entry.h"
 #include "vm/scopes.h"
 #include "vm/stack_frame.h"
@@ -949,6 +950,8 @@
   cls.set_type_arguments_field_offset(Array::type_arguments_offset(),
                                       RTN::Array::type_arguments_offset());
   cls.set_num_type_arguments_unsafe(1);
+  // In order to be able to canonicalize arguments descriptors early.
+  cls.set_is_prefinalized();
   cls =
       Class::New<GrowableObjectArray, RTN::GrowableObjectArray>(isolate_group);
   isolate_group->object_store()->set_growable_object_array_class(cls);
@@ -1090,10 +1093,26 @@
         empty_exception_handlers_,
         static_cast<ExceptionHandlersPtr>(address + kHeapObjectTag));
     empty_exception_handlers_->StoreNonPointer(
-        &empty_exception_handlers_->untag()->num_entries_, 0);
+        &empty_exception_handlers_->untag()->packed_fields_, 0);
     empty_exception_handlers_->SetCanonical();
   }
 
+  // Empty exception handlers for async/async* functions.
+  {
+    uword address =
+        heap->Allocate(thread, ExceptionHandlers::InstanceSize(0), Heap::kOld);
+    InitializeObject(address, kExceptionHandlersCid,
+                     ExceptionHandlers::InstanceSize(0),
+                     ExceptionHandlers::ContainsCompressedPointers());
+    ExceptionHandlers::initializeHandle(
+        empty_async_exception_handlers_,
+        static_cast<ExceptionHandlersPtr>(address + kHeapObjectTag));
+    empty_async_exception_handlers_->StoreNonPointer(
+        &empty_async_exception_handlers_->untag()->packed_fields_,
+        UntaggedExceptionHandlers::AsyncHandlerBit::update(true, 0));
+    empty_async_exception_handlers_->SetCanonical();
+  }
+
   // Allocate and initialize the canonical empty type arguments object.
   {
     uword address =
@@ -1239,6 +1258,8 @@
   ASSERT(empty_var_descriptors_->IsLocalVarDescriptors());
   ASSERT(!empty_exception_handlers_->IsSmi());
   ASSERT(empty_exception_handlers_->IsExceptionHandlers());
+  ASSERT(!empty_async_exception_handlers_->IsSmi());
+  ASSERT(empty_async_exception_handlers_->IsExceptionHandlers());
   ASSERT(!sentinel_->IsSmi());
   ASSERT(sentinel_->IsSentinel());
   ASSERT(!transition_sentinel_->IsSmi());
@@ -2039,6 +2060,10 @@
     RegisterClass(cls, Symbols::FutureOr(), lib);
     pending_classes.Add(cls);
 
+    cls = Class::New<SuspendState, RTN::SuspendState>(isolate_group);
+    RegisterPrivateClass(cls, Symbols::_SuspendState(), lib);
+    pending_classes.Add(cls);
+
     // Pre-register the developer library so we can place the vm class
     // UserTag there rather than the core library.
     lib = Library::LookupLibrary(thread, Symbols::DartDeveloper());
@@ -2542,6 +2567,7 @@
     cls = Class::New<ReceivePort, RTN::ReceivePort>(isolate_group);
     cls = Class::New<SendPort, RTN::SendPort>(isolate_group);
     cls = Class::New<StackTrace, RTN::StackTrace>(isolate_group);
+    cls = Class::New<SuspendState, RTN::SuspendState>(isolate_group);
     cls = Class::New<RegExp, RTN::RegExp>(isolate_group);
     cls = Class::New<Number, RTN::Number>(isolate_group);
 
@@ -3592,10 +3618,21 @@
   auto& cache = Array::Handle(zone, invocation_dispatcher_cache());
   InvocationDispatcherTable dispatchers(cache);
   intptr_t i = 0;
-  for (auto dispatcher : dispatchers) {
-    if (dispatcher.Get<kInvocationDispatcherName>() == String::null()) {
+#if defined(DEBUG)
+  auto& function = Function::Handle();
+#endif
+  for (auto entry : dispatchers) {
+    if (entry.Get<kInvocationDispatcherName>() == String::null()) {
       break;
     }
+
+#if defined(DEBUG)
+    // Check for duplicate entries in the cache.
+    function = entry.Get<kInvocationDispatcherFunction>();
+    ASSERT(entry.Get<kInvocationDispatcherName>() != target_name.ptr() ||
+           function.kind() != dispatcher.kind() ||
+           entry.Get<kInvocationDispatcherArgsDesc>() != args_desc.ptr());
+#endif  // defined(DEBUG)
     i++;
   }
   if (i == dispatchers.Length()) {
@@ -3973,8 +4010,12 @@
 
   const bool needs_dyn_forwarder =
       kernel::NeedsDynamicInvocationForwarder(*this);
+  if (!needs_dyn_forwarder) {
+    return ptr();
+  }
+
   if (!allow_add) {
-    return needs_dyn_forwarder ? Function::null() : ptr();
+    return Function::null();
   }
 
   // If we failed to find it and possibly need to create it, use a write lock.
@@ -3988,10 +4029,8 @@
   if (!result.IsNull()) return result.ptr();
 
   // Otherwise create it & add it.
-  result = needs_dyn_forwarder ? CreateDynamicInvocationForwarder(mangled_name)
-                               : ptr();
+  result = CreateDynamicInvocationForwarder(mangled_name);
   owner.AddInvocationDispatcher(mangled_name, Array::null_array(), result);
-
   return result.ptr();
 }
 
@@ -13260,6 +13299,10 @@
   untag()->set_exported_names(Array::null());
   untag()->set_loaded_scripts(Array::null());
   untag()->set_dependencies(Array::null());
+#if defined(PRODUCT)
+  // used_scripts is only used by vm-service.
+  untag()->set_used_scripts(GrowableObjectArray::null());
+#endif
 }
 
 void Library::AddImport(const Namespace& ns) const {
@@ -15341,7 +15384,18 @@
 }
 
 intptr_t ExceptionHandlers::num_entries() const {
-  return untag()->num_entries_;
+  return untag()->num_entries();
+}
+
+bool ExceptionHandlers::has_async_handler() const {
+  return UntaggedExceptionHandlers::AsyncHandlerBit::decode(
+      untag()->packed_fields_);
+}
+
+void ExceptionHandlers::set_has_async_handler(bool value) const {
+  StoreNonPointer(&untag()->packed_fields_,
+                  UntaggedExceptionHandlers::AsyncHandlerBit::update(
+                      value, untag()->packed_fields_));
 }
 
 void ExceptionHandlers::SetHandlerInfo(intptr_t try_index,
@@ -15433,7 +15487,9 @@
                          ExceptionHandlers::ContainsCompressedPointers());
     NoSafepointScope no_safepoint;
     result ^= raw;
-    result.StoreNonPointer(&result.untag()->num_entries_, num_handlers);
+    result.StoreNonPointer(
+        &result.untag()->packed_fields_,
+        UntaggedExceptionHandlers::NumEntriesBits::update(num_handlers, 0));
   }
   const Array& handled_types_data =
       (num_handlers == 0) ? Object::empty_array()
@@ -15459,7 +15515,9 @@
                          ExceptionHandlers::ContainsCompressedPointers());
     NoSafepointScope no_safepoint;
     result ^= raw;
-    result.StoreNonPointer(&result.untag()->num_entries_, num_handlers);
+    result.StoreNonPointer(
+        &result.untag()->packed_fields_,
+        UntaggedExceptionHandlers::NumEntriesBits::update(num_handlers, 0));
   }
   result.set_handled_types_data(handled_types_data);
   return result.ptr();
@@ -15468,8 +15526,11 @@
 const char* ExceptionHandlers::ToCString() const {
 #define FORMAT1 "%" Pd " => %#x  (%" Pd " types) (outer %d)%s%s\n"
 #define FORMAT2 "  %d. %s\n"
+#define FORMAT3 "<async handler>\n"
   if (num_entries() == 0) {
-    return "empty ExceptionHandlers\n";
+    return has_async_handler()
+               ? "empty ExceptionHandlers (with <async handler>)\n"
+               : "empty ExceptionHandlers\n";
   }
   auto& handled_types = Array::Handle();
   auto& type = AbstractType::Handle();
@@ -15492,6 +15553,9 @@
       len += Utils::SNPrint(NULL, 0, FORMAT2, k, type.ToCString());
     }
   }
+  if (has_async_handler()) {
+    len += Utils::SNPrint(NULL, 0, FORMAT3);
+  }
   // Allocate the buffer.
   char* buffer = Thread::Current()->zone()->Alloc<char>(len);
   // Layout the fields in the buffer.
@@ -15512,9 +15576,14 @@
                                   FORMAT2, k, type.ToCString());
     }
   }
+  if (has_async_handler()) {
+    num_chars +=
+        Utils::SNPrint((buffer + num_chars), (len - num_chars), FORMAT3);
+  }
   return buffer;
 #undef FORMAT1
 #undef FORMAT2
+#undef FORMAT3
 }
 
 void SingleTargetCache::set_target(const Code& value) const {
@@ -25966,6 +26035,54 @@
                     "Omit CodeSourceMaps in precompiled snapshots and don't "
                     "symbolize stack traces in the precompiled runtime.");
 
+SuspendStatePtr SuspendState::New(intptr_t frame_size,
+                                  const Instance& future,
+                                  Heap::Space space) {
+  SuspendState& result = SuspendState::Handle();
+  {
+    ObjectPtr raw = Object::Allocate(
+        SuspendState::kClassId, SuspendState::InstanceSize(frame_size), space,
+        SuspendState::ContainsCompressedPointers());
+    NoSafepointScope no_safepoint;
+    result ^= raw;
+    result.set_frame_size(frame_size);
+    result.set_pc(0);
+    result.set_future(future);
+  }
+  return result.ptr();
+}
+
+void SuspendState::set_frame_size(intptr_t frame_size) const {
+  ASSERT(frame_size >= 0);
+  StoreNonPointer(&untag()->frame_size_, frame_size);
+}
+
+void SuspendState::set_pc(uword pc) const {
+  StoreNonPointer(&untag()->pc_, pc);
+}
+
+void SuspendState::set_future(const Instance& future) const {
+  untag()->set_future(future.ptr());
+}
+
+const char* SuspendState::ToCString() const {
+  return "SuspendState";
+}
+
+CodePtr SuspendState::GetCodeObject() const {
+  ASSERT(pc() != 0);
+#if defined(DART_PRECOMPILED_RUNTIME)
+  NoSafepointScope no_safepoint;
+  CodePtr code = ReversePc::Lookup(IsolateGroup::Current(), pc(),
+                                   /*is_return_address=*/true);
+  ASSERT(code != Code::null());
+  return code;
+#else
+  UNIMPLEMENTED();
+  return Code::null();
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+}
+
 void RegExp::set_pattern(const String& pattern) const {
   untag()->set_pattern(pattern.ptr());
 }
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 3bd1912..0ea4197 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -447,6 +447,7 @@
   V(PcDescriptors, empty_descriptors)                                          \
   V(LocalVarDescriptors, empty_var_descriptors)                                \
   V(ExceptionHandlers, empty_exception_handlers)                               \
+  V(ExceptionHandlers, empty_async_exception_handlers)                         \
   V(Array, extractor_parameter_types)                                          \
   V(Array, extractor_parameter_names)                                          \
   V(Sentinel, sentinel)                                                        \
@@ -2891,7 +2892,12 @@
 
   static intptr_t code_offset() { return OFFSET_OF(UntaggedFunction, code_); }
 
-  uword entry_point() const { return untag()->entry_point_; }
+  uword entry_point() const {
+    return EntryPointOf(ptr());
+  }
+  static uword EntryPointOf(const FunctionPtr function) {
+    return function->untag()->entry_point_;
+  }
 
   static intptr_t entry_point_offset(
       CodeEntryKind entry_kind = CodeEntryKind::kNormal) {
@@ -3162,6 +3168,12 @@
   // Returns the number of implicit parameters, e.g., this for instance methods.
   intptr_t NumImplicitParameters() const;
 
+  // Returns true if parameters of this function are copied into the frame
+  // in the function prologue.
+  bool MakesCopyOfParameters() const {
+    return HasOptionalParameters() || IsCompactAsyncFunction();
+  }
+
 #if defined(DART_PRECOMPILED_RUNTIME)
 #define DEFINE_GETTERS_AND_SETTERS(return_type, type, name)                    \
   static intptr_t name##_offset() {                                            \
@@ -3558,6 +3570,12 @@
     return modifier() == UntaggedFunction::kAsync;
   }
 
+  // TODO(alexmarkov): replace this predicate with IsAsyncFunction() after
+  // old async functions are removed.
+  bool IsCompactAsyncFunction() const {
+    return IsAsyncFunction() && is_debuggable();
+  }
+
   // Recognise synthetic sync-yielding functions like the inner-most:
   //   user_func /* was async */ {
   //      :async_op(..) yielding {
@@ -6220,6 +6238,9 @@
 
   intptr_t num_entries() const;
 
+  bool has_async_handler() const;
+  void set_has_async_handler(bool value) const;
+
   void GetHandlerInfo(intptr_t try_index, ExceptionHandlerInfo* info) const;
 
   uword HandlerPCOffset(intptr_t try_index) const;
@@ -11763,6 +11784,63 @@
   friend class DebuggerStackTrace;
 };
 
+class SuspendState : public Instance {
+ public:
+  // :suspend_state local variable index
+  static constexpr intptr_t kSuspendStateVarIndex = 0;
+
+  static intptr_t HeaderSize() { return sizeof(UntaggedSuspendState); }
+  static intptr_t UnroundedSize(SuspendStatePtr ptr) {
+    return UnroundedSize(ptr->untag()->frame_size_);
+  }
+  static intptr_t UnroundedSize(intptr_t frame_size) {
+    return HeaderSize() + frame_size;
+  }
+  static intptr_t InstanceSize() {
+    ASSERT_EQUAL(sizeof(UntaggedSuspendState),
+                 OFFSET_OF_RETURNED_VALUE(UntaggedSuspendState, payload));
+    return 0;
+  }
+  static intptr_t InstanceSize(intptr_t frame_size) {
+    return RoundedAllocationSize(UnroundedSize(frame_size));
+  }
+
+  static intptr_t frame_size_offset() {
+    return OFFSET_OF(UntaggedSuspendState, frame_size_);
+  }
+  static intptr_t pc_offset() { return OFFSET_OF(UntaggedSuspendState, pc_); }
+  static intptr_t future_offset() {
+    return OFFSET_OF(UntaggedSuspendState, future_);
+  }
+  static intptr_t then_callback_offset() {
+    return OFFSET_OF(UntaggedSuspendState, then_callback_);
+  }
+  static intptr_t error_callback_offset() {
+    return OFFSET_OF(UntaggedSuspendState, error_callback_);
+  }
+  static intptr_t payload_offset() {
+    return UntaggedSuspendState::payload_offset();
+  }
+
+  static SuspendStatePtr New(intptr_t frame_size,
+                             const Instance& future,
+                             Heap::Space space = Heap::kNew);
+
+  InstancePtr future() const { return untag()->future(); }
+  uword pc() const { return untag()->pc_; }
+
+  // Returns Code object corresponding to the suspended function.
+  CodePtr GetCodeObject() const;
+
+ private:
+  void set_frame_size(intptr_t frame_size) const;
+  void set_pc(uword pc) const;
+  void set_future(const Instance& future) const;
+
+  FINAL_HEAP_OBJECT_IMPLEMENTATION(SuspendState, Instance);
+  friend class Class;
+};
+
 class RegExpFlags {
  public:
   // Flags are passed to a regex object as follows:
diff --git a/runtime/vm/object_graph_copy.cc b/runtime/vm/object_graph_copy.cc
index 66ebd79..c49af9a 100644
--- a/runtime/vm/object_graph_copy.cc
+++ b/runtime/vm/object_graph_copy.cc
@@ -74,6 +74,7 @@
   V(Smi)                                                                       \
   V(StackTrace)                                                                \
   V(SubtypeTestCache)                                                          \
+  V(SuspendState)                                                              \
   V(Type)                                                                      \
   V(TypeArguments)                                                             \
   V(TypeParameter)                                                             \
@@ -619,6 +620,7 @@
       HANDLE_ILLEGAL_CASE(MirrorReference)
       HANDLE_ILLEGAL_CASE(Pointer)
       HANDLE_ILLEGAL_CASE(ReceivePort)
+      HANDLE_ILLEGAL_CASE(SuspendState)
       HANDLE_ILLEGAL_CASE(UserTag)
       default:
         return true;
diff --git a/runtime/vm/object_service.cc b/runtime/vm/object_service.cc
index eab9078..0653fe4 100644
--- a/runtime/vm/object_service.cc
+++ b/runtime/vm/object_service.cc
@@ -1760,6 +1760,10 @@
   Instance::PrintJSONImpl(stream, ref);
 }
 
+void SuspendState::PrintJSONImpl(JSONStream* stream, bool ref) const {
+  Instance::PrintJSONImpl(stream, ref);
+}
+
 #endif
 
 }  // namespace dart
diff --git a/runtime/vm/object_store.cc b/runtime/vm/object_store.cc
index 056d9e6..7cc7f02 100644
--- a/runtime/vm/object_store.cc
+++ b/runtime/vm/object_store.cc
@@ -301,6 +301,31 @@
     }
   }
 
+  cls = async_lib.LookupClassAllowPrivate(Symbols::_SuspendState());
+  ASSERT(!cls.IsNull());
+  const auto& error = cls.EnsureIsFinalized(thread);
+  ASSERT(error == Error::null());
+
+  function = cls.LookupFunctionAllowPrivate(Symbols::_initAsync());
+  ASSERT(!function.IsNull());
+  set_suspend_state_init_async(function);
+
+  function = cls.LookupFunctionAllowPrivate(Symbols::_awaitAsync());
+  ASSERT(!function.IsNull());
+  set_suspend_state_await_async(function);
+
+  function = cls.LookupFunctionAllowPrivate(Symbols::_returnAsync());
+  ASSERT(!function.IsNull());
+  set_suspend_state_return_async(function);
+
+  function = cls.LookupFunctionAllowPrivate(Symbols::_returnAsyncNotFuture());
+  ASSERT(!function.IsNull());
+  set_suspend_state_return_async_not_future(function);
+
+  function = cls.LookupFunctionAllowPrivate(Symbols::_handleException());
+  ASSERT(!function.IsNull());
+  set_suspend_state_handle_exception(function);
+
   const Library& core_lib = Library::Handle(zone, core_library());
   cls = core_lib.LookupClassAllowPrivate(Symbols::_CompileTimeError());
   ASSERT(!cls.IsNull());
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index b9ba248..ee7844a 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -168,6 +168,11 @@
   RW(Function, complete_on_async_return)                                       \
   RW(Function, complete_with_no_future_on_async_return)                        \
   RW(Function, complete_on_async_error)                                        \
+  RW(Function, suspend_state_init_async)                                       \
+  RW(Function, suspend_state_await_async)                                      \
+  RW(Function, suspend_state_return_async)                                     \
+  RW(Function, suspend_state_return_async_not_future)                          \
+  RW(Function, suspend_state_handle_exception)                                 \
   RW(Class, async_star_stream_controller)                                      \
   ARW_RELAXED(Smi, future_timeout_future_index)                                \
   ARW_RELAXED(Smi, future_wait_future_index)                                   \
@@ -239,6 +244,11 @@
   RW(Code, type_parameter_tts_stub)                                            \
   RW(Code, unreachable_tts_stub)                                               \
   RW(Code, slow_tts_stub)                                                      \
+  RW(Code, await_async_stub)                                                   \
+  RW(Code, init_async_stub)                                                    \
+  RW(Code, resume_stub)                                                        \
+  RW(Code, return_async_stub)                                                  \
+  RW(Code, return_async_not_future_stub)                                       \
   RW(Array, dispatch_table_code_entries)                                       \
   RW(GrowableObjectArray, instructions_tables)                                 \
   RW(Array, obfuscation_map)                                                   \
@@ -314,6 +324,11 @@
   DO(init_instance_field_stub, InitInstanceField)                              \
   DO(init_late_instance_field_stub, InitLateInstanceField)                     \
   DO(init_late_final_instance_field_stub, InitLateFinalInstanceField)          \
+  DO(await_async_stub, AwaitAsync)                                             \
+  DO(init_async_stub, InitAsync)                                               \
+  DO(resume_stub, Resume)                                                      \
+  DO(return_async_stub, ReturnAsync)                                           \
+  DO(return_async_not_future_stub, ReturnAsyncNotFuture)                       \
   DO(instance_of_stub, InstanceOf)
 
 #define ISOLATE_OBJECT_STORE_FIELD_LIST(R_, RW)                                \
diff --git a/runtime/vm/os.h b/runtime/vm/os.h
index aab5c4d..ccc0bf7 100644
--- a/runtime/vm/os.h
+++ b/runtime/vm/os.h
@@ -63,6 +63,9 @@
   // NOTE: This function will return -1 on OSs that are not supported.
   static int64_t GetCurrentThreadCPUMicros();
 
+  // If the tracing/timeline configuration on takes timestamps as input, returns
+  // the same value as |GetCurrentMonotonicMicros|. Otherwise, returns -1.
+  static int64_t GetCurrentMonotonicMicrosForTimeline();
   // If the tracing/timeline configuration on the current OS supports thread
   // timestamps, returns the same value as |GetCurrentThreadCPUMicros|.
   // Otherwise, returns -1.
diff --git a/runtime/vm/os_android.cc b/runtime/vm/os_android.cc
index 3a32eec..adc2a06 100644
--- a/runtime/vm/os_android.cc
+++ b/runtime/vm/os_android.cc
@@ -21,6 +21,7 @@
 #include "vm/code_observers.h"
 #include "vm/dart.h"
 #include "vm/isolate.h"
+#include "vm/timeline.h"
 #include "vm/zone.h"
 
 namespace dart {
@@ -177,8 +178,22 @@
   return result;
 }
 
+int64_t OS::GetCurrentMonotonicMicrosForTimeline() {
+#if defined(SUPPORT_TIMELINE)
+  if (Timeline::recorder_discards_clock_values()) return -1;
+  return GetCurrentMonotonicMicros();
+#else
+  return -1;
+#endif
+}
+
 int64_t OS::GetCurrentThreadCPUMicrosForTimeline() {
+#if defined(SUPPORT_TIMELINE)
+  if (Timeline::recorder_discards_clock_values()) return -1;
   return OS::GetCurrentThreadCPUMicros();
+#else
+  return -1;
+#endif
 }
 
 // TODO(5411554):  May need to hoist these architecture dependent code
diff --git a/runtime/vm/os_fuchsia.cc b/runtime/vm/os_fuchsia.cc
index 84bf154..aa9684c 100644
--- a/runtime/vm/os_fuchsia.cc
+++ b/runtime/vm/os_fuchsia.cc
@@ -453,6 +453,14 @@
   return status == ZX_OK ? info.total_runtime / kNanosecondsPerMicrosecond : 0;
 }
 
+int64_t OS::GetCurrentMonotonicMicrosForTimeline() {
+#if defined(SUPPORT_TIMELINE)
+  return OS::GetCurrentMonotonicMicros();
+#else
+  return -1;
+#endif
+}
+
 // On Fuchsia, thread timestamp values are not used in the tracing/timeline
 // integration. Because of this, we try to avoid querying them, since doing so
 // has both a runtime and trace buffer storage cost.
diff --git a/runtime/vm/os_linux.cc b/runtime/vm/os_linux.cc
index aed7558..782cd0e 100644
--- a/runtime/vm/os_linux.cc
+++ b/runtime/vm/os_linux.cc
@@ -29,6 +29,7 @@
 #include "vm/isolate.h"
 #include "vm/lockers.h"
 #include "vm/os_thread.h"
+#include "vm/timeline.h"
 #include "vm/zone.h"
 
 namespace dart {
@@ -496,10 +497,23 @@
   return result;
 }
 
-int64_t OS::GetCurrentThreadCPUMicrosForTimeline() {
-  return OS::GetCurrentThreadCPUMicros();
+int64_t OS::GetCurrentMonotonicMicrosForTimeline() {
+#if defined(SUPPORT_TIMELINE)
+  if (Timeline::recorder_discards_clock_values()) return -1;
+  return GetCurrentMonotonicMicros();
+#else
+  return -1;
+#endif
 }
 
+int64_t OS::GetCurrentThreadCPUMicrosForTimeline() {
+#if defined(SUPPORT_TIMELINE)
+  if (Timeline::recorder_discards_clock_values()) return -1;
+  return OS::GetCurrentThreadCPUMicros();
+#else
+  return -1;
+#endif
+}
 // TODO(5411554):  May need to hoist these architecture dependent code
 // into a architecture specific file e.g: os_ia32_linux.cc
 intptr_t OS::ActivationFrameAlignment() {
diff --git a/runtime/vm/os_macos.cc b/runtime/vm/os_macos.cc
index 05f9ee4..97090fc 100644
--- a/runtime/vm/os_macos.cc
+++ b/runtime/vm/os_macos.cc
@@ -21,6 +21,7 @@
 
 #include "platform/utils.h"
 #include "vm/isolate.h"
+#include "vm/timeline.h"
 #include "vm/zone.h"
 
 namespace dart {
@@ -127,8 +128,22 @@
   return thread_cpu_micros;
 }
 
+int64_t OS::GetCurrentMonotonicMicrosForTimeline() {
+#if defined(SUPPORT_TIMELINE)
+  if (Timeline::recorder_discards_clock_values()) return -1;
+  return GetCurrentMonotonicMicros();
+#else
+  return -1;
+#endif
+}
+
 int64_t OS::GetCurrentThreadCPUMicrosForTimeline() {
+#if defined(SUPPORT_TIMELINE)
+  if (Timeline::recorder_discards_clock_values()) return -1;
   return OS::GetCurrentThreadCPUMicros();
+#else
+  return -1;
+#endif
 }
 
 intptr_t OS::ActivationFrameAlignment() {
diff --git a/runtime/vm/os_win.cc b/runtime/vm/os_win.cc
index 3eb9be0..5a4b01c 100644
--- a/runtime/vm/os_win.cc
+++ b/runtime/vm/os_win.cc
@@ -174,8 +174,20 @@
   return -1;
 }
 
+int64_t OS::GetCurrentMonotonicMicrosForTimeline() {
+#if defined(SUPPORT_TIMELINE)
+  return OS::GetCurrentMonotonicMicros();
+#else
+  return -1;
+#endif
+}
+
 int64_t OS::GetCurrentThreadCPUMicrosForTimeline() {
+#if defined(SUPPORT_TIMELINE)
   return OS::GetCurrentThreadCPUMicros();
+#else
+  return -1;
+#endif
 }
 
 intptr_t OS::ActivationFrameAlignment() {
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 7c6592f..7b89702 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -187,6 +187,7 @@
   const intptr_t num_fixed_params = function().num_fixed_parameters();
   const intptr_t num_opt_params = function().NumOptionalParameters();
   const intptr_t num_params = num_fixed_params + num_opt_params;
+  const bool copy_parameters = function().MakesCopyOfParameters();
 
   // Before we start allocating indices to variables, we'll setup the
   // parameters array, which can be used to access the raw parameters (i.e. not
@@ -212,7 +213,7 @@
         raw_parameter->set_needs_covariant_check_in_method();
       }
       raw_parameter->set_type_check_mode(variable->type_check_mode());
-      if (function().HasOptionalParameters()) {
+      if (copy_parameters) {
         bool ok = scope->AddVariable(raw_parameter);
         ASSERT(ok);
 
@@ -261,33 +262,30 @@
 
   // The copy parameters implementation will still write to local variables
   // which we assign indices as with the old CopyParams implementation.
-  VariableIndex parameter_index_start;
-  VariableIndex reamining_local_variables_start;
+  VariableIndex first_local_index;
   {
     // Compute start indices to parameters and locals, and the number of
     // parameters to copy.
-    if (num_opt_params == 0) {
-      parameter_index_start = first_parameter_index_ =
-          VariableIndex(num_params);
-      reamining_local_variables_start = VariableIndex(0);
+    if (!copy_parameters) {
+      ASSERT(suspend_state_var() == nullptr);
+      first_parameter_index_ = VariableIndex(num_params);
+      first_local_index = VariableIndex(0);
     } else {
-      parameter_index_start = first_parameter_index_ = VariableIndex(0);
-      reamining_local_variables_start = VariableIndex(-num_params);
+      // :suspend_state variable is inserted at the fixed slot
+      // before the copied parameters.
+      const intptr_t reserved_var_slot_count =
+          (suspend_state_var() != nullptr) ? 1 : 0;
+      first_parameter_index_ = VariableIndex(-reserved_var_slot_count);
+      first_local_index =
+          VariableIndex(first_parameter_index_.value() - num_params);
     }
   }
 
-  if (function_type_arguments_ != NULL && num_opt_params > 0) {
-    reamining_local_variables_start =
-        VariableIndex(reamining_local_variables_start.value() - 1);
-  }
-
   // Allocate parameters and local variables, either in the local frame or
   // in the context(s).
   bool found_captured_variables = false;
-  VariableIndex first_local_index =
-      VariableIndex(parameter_index_start.value() > 0 ? 0 : -num_params);
   VariableIndex next_free_index = scope->AllocateVariables(
-      function(), parameter_index_start, num_params, first_local_index, NULL,
+      function(), first_parameter_index_, num_params, first_local_index, NULL,
       &found_captured_variables);
 
   num_stack_locals_ = -next_free_index.value();
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index 2a6d1b8..fde06a9 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -74,6 +74,12 @@
     parent_type_arguments_ = parent_type_arguments;
   }
 
+  LocalVariable* suspend_state_var() const { return suspend_state_var_; }
+  void set_suspend_state_var(LocalVariable* suspend_state_var) {
+    ASSERT(suspend_state_var != nullptr);
+    suspend_state_var_ = suspend_state_var;
+  }
+
   void set_default_parameter_values(ZoneGrowableArray<const Instance*>* list) {
     default_parameter_values_ = list;
 #if defined(DEBUG)
@@ -260,6 +266,7 @@
   RegExpCompileData* regexp_compile_data_;
   LocalVariable* function_type_arguments_;
   LocalVariable* parent_type_arguments_;
+  LocalVariable* suspend_state_var_ = nullptr;
   LocalVariable* current_context_var_;
   LocalVariable* arg_desc_var_;
   LocalVariable* receiver_var_ = nullptr;
diff --git a/runtime/vm/program_visitor.cc b/runtime/vm/program_visitor.cc
index d813ce9..1b22693 100644
--- a/runtime/vm/program_visitor.cc
+++ b/runtime/vm/program_visitor.cc
@@ -218,13 +218,11 @@
   auto const heap = isolate_group->heap();
   ProgramWalker walker(zone, heap, visitor);
 
-  // Walk through the libraries and patches, looking for visitable objects.
+  // Walk through the libraries looking for visitable objects.
   const auto& libraries =
       GrowableObjectArray::Handle(zone, object_store->libraries());
   auto& lib = Library::Handle(zone);
   auto& cls = Class::Handle(zone);
-  auto& entry = Object::Handle(zone);
-  auto& patches = GrowableObjectArray::Handle(zone);
 
   for (intptr_t i = 0; i < libraries.Length(); i++) {
     lib ^= libraries.At(i);
@@ -233,11 +231,6 @@
       cls = it.GetNextClass();
       walker.AddToWorklist(cls);
     }
-    patches = lib.used_scripts();
-    for (intptr_t j = 0; j < patches.Length(); j++) {
-      entry = patches.At(j);
-      walker.AddToWorklist(entry);
-    }
   }
 
   // If there's a global object pool, add any visitable objects.
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index 80c1008..07b74a2 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -12,6 +12,7 @@
 #include "vm/isolate_reload.h"
 #include "vm/object.h"
 #include "vm/runtime_entry.h"
+#include "vm/stack_frame.h"
 #include "vm/visitor.h"
 
 namespace dart {
@@ -170,6 +171,13 @@
     case kPointerCid:
       instance_size = Pointer::InstanceSize();
       break;
+    case kSuspendStateCid: {
+      const SuspendStatePtr raw_suspend_state =
+          static_cast<const SuspendStatePtr>(this);
+      intptr_t frame_size = raw_suspend_state->untag()->frame_size_;
+      instance_size = SuspendState::InstanceSize(frame_size);
+      break;
+    }
     case kTypeArgumentsCid: {
       const TypeArgumentsPtr raw_array =
           static_cast<const TypeArgumentsPtr>(this);
@@ -208,7 +216,7 @@
     case kExceptionHandlersCid: {
       const ExceptionHandlersPtr raw_handlers =
           static_cast<const ExceptionHandlersPtr>(this);
-      intptr_t num_handlers = raw_handlers->untag()->num_entries_;
+      intptr_t num_handlers = raw_handlers->untag()->num_entries();
       instance_size = ExceptionHandlers::InstanceSize(num_handlers);
       break;
     }
@@ -563,7 +571,7 @@
 VARIABLE_COMPRESSED_VISITOR(TypeArguments,
                             Smi::Value(raw_obj->untag()->length()))
 VARIABLE_COMPRESSED_VISITOR(LocalVarDescriptors, raw_obj->untag()->num_entries_)
-VARIABLE_COMPRESSED_VISITOR(ExceptionHandlers, raw_obj->untag()->num_entries_)
+VARIABLE_COMPRESSED_VISITOR(ExceptionHandlers, raw_obj->untag()->num_entries())
 VARIABLE_COMPRESSED_VISITOR(Context, raw_obj->untag()->num_variables_)
 VARIABLE_COMPRESSED_VISITOR(Array, Smi::Value(raw_obj->untag()->length()))
 VARIABLE_COMPRESSED_VISITOR(
@@ -626,6 +634,33 @@
   return Field::InstanceSize();
 }
 
+intptr_t UntaggedSuspendState::VisitSuspendStatePointers(
+    SuspendStatePtr raw_obj,
+    ObjectPointerVisitor* visitor) {
+  ASSERT(raw_obj->IsHeapObject());
+  ASSERT_COMPRESSED(SuspendState);
+
+  if (visitor->CanVisitSuspendStatePointers(raw_obj)) {
+    visitor->VisitCompressedPointers(
+        raw_obj->heap_base(), raw_obj->untag()->from(), raw_obj->untag()->to());
+
+    const uword pc = raw_obj->untag()->pc_;
+    if (pc != 0) {
+      Thread* thread = Thread::Current();
+      ASSERT(thread != nullptr);
+      ASSERT(thread->isolate_group() == visitor->isolate_group());
+      const uword sp = reinterpret_cast<uword>(raw_obj->untag()->payload());
+      StackFrame frame(thread);
+      frame.pc_ = pc;
+      frame.sp_ = sp;
+      frame.fp_ = sp + raw_obj->untag()->frame_size_;
+      frame.VisitObjectPointers(visitor);
+    }
+  }
+
+  return SuspendState::InstanceSize(raw_obj->untag()->frame_size_);
+}
+
 bool UntaggedCode::ContainsPC(const ObjectPtr raw_obj, uword pc) {
   if (!raw_obj->IsCode()) return false;
   auto const raw_code = static_cast<const CodePtr>(raw_obj);
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 8e50977..5677ff9 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -2249,16 +2249,30 @@
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(ExceptionHandlers);
 
-  // Number of exception handler entries.
-  int32_t num_entries_;
+  // Number of exception handler entries and
+  // async handler.
+  uint32_t packed_fields_;
 
-  // Array with [num_entries_] entries. Each entry is an array of all handled
+  // Async handler is used in the async/async* functions.
+  // It's an implicit exception handler (stub) which runs when
+  // exception is not handled within the function.
+  using AsyncHandlerBit = BitField<decltype(packed_fields_), bool, 0, 1>;
+  using NumEntriesBits = BitField<decltype(packed_fields_),
+                                  uint32_t,
+                                  AsyncHandlerBit::kNextBit,
+                                  31>;
+
+  intptr_t num_entries() const {
+    return NumEntriesBits::decode(packed_fields_);
+  }
+
+  // Array with [num_entries] entries. Each entry is an array of all handled
   // exception types.
   COMPRESSED_POINTER_FIELD(ArrayPtr, handled_types_data)
   VISIT_FROM(handled_types_data)
   VISIT_TO(handled_types_data)
 
-  // Exception handler info of length [num_entries_].
+  // Exception handler info of length [num_entries].
   const ExceptionHandlerInfo* data() const {
     OPEN_ARRAY_START(ExceptionHandlerInfo, intptr_t);
   }
@@ -3272,6 +3286,30 @@
   bool skip_sync_start_in_parent_stack;
 };
 
+class UntaggedSuspendState : public UntaggedInstance {
+  RAW_HEAP_OBJECT_IMPLEMENTATION(SuspendState);
+
+  intptr_t frame_size_;
+  uword pc_;
+
+  COMPRESSED_POINTER_FIELD(InstancePtr, future)
+  COMPRESSED_POINTER_FIELD(ClosurePtr, then_callback)
+  COMPRESSED_POINTER_FIELD(ClosurePtr, error_callback)
+  VISIT_FROM(future)
+  VISIT_TO(error_callback)
+
+ public:
+  uword pc() const { return pc_; }
+
+  static intptr_t payload_offset() {
+    return OFFSET_OF_RETURNED_VALUE(UntaggedSuspendState, payload);
+  }
+
+  // Variable length payload follows here.
+  uint8_t* payload() { OPEN_ARRAY_START(uint8_t, uint8_t); }
+  const uint8_t* payload() const { OPEN_ARRAY_START(uint8_t, uint8_t); }
+};
+
 // VM type for capturing JS regular expressions.
 class UntaggedRegExp : public UntaggedInstance {
   RAW_HEAP_OBJECT_IMPLEMENTATION(RegExp);
diff --git a/runtime/vm/raw_object_fields.cc b/runtime/vm/raw_object_fields.cc
index d62f9ef..749e1d2 100644
--- a/runtime/vm/raw_object_fields.cc
+++ b/runtime/vm/raw_object_fields.cc
@@ -191,6 +191,9 @@
   F(RegExp, two_byte_sticky_)                                                  \
   F(RegExp, external_one_byte_sticky_)                                         \
   F(RegExp, external_two_byte_sticky_)                                         \
+  F(SuspendState, future_)                                                     \
+  F(SuspendState, then_callback_)                                              \
+  F(SuspendState, error_callback_)                                             \
   F(WeakProperty, key_)                                                        \
   F(WeakProperty, value_)                                                      \
   F(WeakReference, target_)                                                    \
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index 99601df..b1b3345 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -709,6 +709,19 @@
   arguments.SetReturn(cloned_ctx);
 }
 
+// Allocate a SuspendState object.
+// Arg0: frame size.
+// Arg1: future.
+// Return value: newly allocated object.
+DEFINE_RUNTIME_ENTRY(AllocateSuspendState, 2) {
+  const Smi& frame_size = Smi::CheckedHandle(zone, arguments.ArgAt(0));
+  const Instance& future = Instance::CheckedHandle(zone, arguments.ArgAt(1));
+  const SuspendState& result = SuspendState::Handle(
+      zone, SuspendState::New(frame_size.Value(), future,
+                              SpaceForRuntimeAllocation()));
+  arguments.SetReturn(result);
+}
+
 // Helper routine for tracing a type check.
 static void PrintTypeCheck(const char* message,
                            const Instance& instance,
diff --git a/runtime/vm/runtime_entry_list.h b/runtime/vm/runtime_entry_list.h
index 857784b..685c56d 100644
--- a/runtime/vm/runtime_entry_list.h
+++ b/runtime/vm/runtime_entry_list.h
@@ -18,6 +18,7 @@
   V(AllocateClosure)                                                           \
   V(AllocateContext)                                                           \
   V(AllocateObject)                                                            \
+  V(AllocateSuspendState)                                                      \
   V(BoxDouble)                                                                 \
   V(BreakpointRuntimeHandler)                                                  \
   V(SingleStepHandler)                                                         \
diff --git a/runtime/vm/scopes.cc b/runtime/vm/scopes.cc
index b155a46..412c3b3 100644
--- a/runtime/vm/scopes.cc
+++ b/runtime/vm/scopes.cc
@@ -149,6 +149,7 @@
   LocalVariable* controller = nullptr;
   LocalVariable* chained_future = nullptr;
   LocalVariable* is_sync = nullptr;
+  LocalVariable* suspend_state_var = nullptr;
   for (intptr_t i = 0; i < num_variables(); i++) {
     LocalVariable* variable = VariableAt(i);
     if (variable->owner() == this) {
@@ -164,6 +165,10 @@
         } else if (variable->name().Equals(Symbols::is_sync())) {
           is_sync = variable;
         }
+      } else {
+        if (variable->name().Equals(Symbols::SuspendStateVar())) {
+          suspend_state_var = variable;
+        }
       }
     }
   }
@@ -218,6 +223,12 @@
     ASSERT(is_sync->index().value() == Context::kIsSyncIndex);
   }
 
+  if (suspend_state_var != nullptr) {
+    suspend_state_var->set_index(
+        VariableIndex(SuspendState::kSuspendStateVarIndex));
+    ASSERT(next_index.value() == SuspendState::kSuspendStateVarIndex - 1);
+  }
+
   while (pos < num_parameters) {
     LocalVariable* parameter = VariableAt(pos);
     pos++;
@@ -253,8 +264,10 @@
           *found_captured_variables = true;
         }
       } else {
-        variable->set_index(next_index);
-        next_index = VariableIndex(next_index.value() - 1);
+        if (variable != suspend_state_var) {
+          variable->set_index(next_index);
+          next_index = VariableIndex(next_index.value() - 1);
+        }
       }
     }
     pos++;
diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc
index 7a43ea7..ad22d03 100644
--- a/runtime/vm/stack_frame.cc
+++ b/runtime/vm/stack_frame.cc
@@ -394,21 +394,25 @@
     return true;
   }
 
-  if (handlers.num_entries() == 0) {
-    return false;
-  }
-
   intptr_t try_index = -1;
-  uword pc_offset = pc() - code.PayloadStart();
-  PcDescriptors::Iterator iter(descriptors, UntaggedPcDescriptors::kAnyKind);
-  while (iter.MoveNext()) {
-    const intptr_t current_try_index = iter.TryIndex();
-    if ((iter.PcOffset() == pc_offset) && (current_try_index != -1)) {
-      try_index = current_try_index;
-      break;
+  if (handlers.num_entries() != 0) {
+    uword pc_offset = pc() - code.PayloadStart();
+    PcDescriptors::Iterator iter(descriptors, UntaggedPcDescriptors::kAnyKind);
+    while (iter.MoveNext()) {
+      const intptr_t current_try_index = iter.TryIndex();
+      if ((iter.PcOffset() == pc_offset) && (current_try_index != -1)) {
+        try_index = current_try_index;
+        break;
+      }
     }
   }
   if (try_index == -1) {
+    if (handlers.has_async_handler()) {
+      *handler_pc = StubCode::AsyncExceptionHandler().EntryPoint();
+      *needs_stacktrace = true;
+      *has_catch_all = true;
+      return true;
+    }
     return false;
   }
   ExceptionHandlerInfo handler_info;
diff --git a/runtime/vm/stack_frame.h b/runtime/vm/stack_frame.h
index 3574ec3..c25e0cd 100644
--- a/runtime/vm/stack_frame.h
+++ b/runtime/vm/stack_frame.h
@@ -159,6 +159,9 @@
   // fields fp_ and sp_ when they return the respective frame objects.
   friend class FrameSetIterator;
   friend class StackFrameIterator;
+  // UntaggedSuspendState::VisitSuspendStatePointers creates a temporary
+  // StackFrame objects for the copied frames of the suspended functions.
+  friend class UntaggedSuspendState;
   friend class ProfilerDartStackWalker;
   DISALLOW_COPY_AND_ASSIGN(StackFrame);
 };
diff --git a/runtime/vm/stack_trace.cc b/runtime/vm/stack_trace.cc
index eee21f8..d172704 100644
--- a/runtime/vm/stack_trace.cc
+++ b/runtime/vm/stack_trace.cc
@@ -59,6 +59,7 @@
       receiver_context_(Context::Handle(zone)),
       receiver_function_(Function::Handle(zone)),
       parent_function_(Function::Handle(zone)),
+      suspend_state_(SuspendState::Handle(zone)),
       context_entry_(Object::Handle(zone)),
       future_(Object::Handle(zone)),
       listener_(Object::Handle(zone)),
@@ -266,6 +267,12 @@
   return UnwrapAsyncThen(closure_);
 }
 
+ClosurePtr CallerClosureFinder::FindCallerFromSuspendState(
+    const SuspendState& suspend_state) {
+  future_ = suspend_state.future();
+  return GetCallerInFutureImpl(future_);
+}
+
 ClosurePtr CallerClosureFinder::UnwrapAsyncThen(const Closure& closure) {
   if (closure.IsNull()) return closure.ptr();
 
@@ -280,11 +287,31 @@
   return closure.ptr();
 }
 
+bool CallerClosureFinder::IsCompactAsyncCallback(const Function& function) {
+  parent_function_ = function.parent_function();
+  return parent_function_.recognized_kind() ==
+         MethodRecognizer::kSuspendState_createAsyncCallbacks;
+}
+
+SuspendStatePtr CallerClosureFinder::GetSuspendStateFromAsyncCallback(
+    const Closure& closure) {
+  ASSERT(IsCompactAsyncCallback(Function::Handle(closure.function())));
+  // Async handler only captures the receiver (SuspendState).
+  receiver_context_ = closure.context();
+  RELEASE_ASSERT(receiver_context_.num_variables() == 1);
+  return SuspendState::RawCast(receiver_context_.At(0));
+}
+
 ClosurePtr CallerClosureFinder::FindCallerInternal(
     const Closure& receiver_closure) {
   receiver_function_ = receiver_closure.function();
   receiver_context_ = receiver_closure.context();
 
+  if (IsCompactAsyncCallback(receiver_function_)) {
+    suspend_state_ = GetSuspendStateFromAsyncCallback(receiver_closure);
+    return FindCallerFromSuspendState(suspend_state_);
+  }
+
   if (receiver_function_.IsAsyncGenClosure()) {
     return FindCallerInAsyncGenClosure(receiver_context_);
   }
@@ -442,6 +469,21 @@
     return Closure::null();
   }
 
+  if (function.IsCompactAsyncFunction()) {
+    auto& suspend_state = Object::Handle(
+        zone, *reinterpret_cast<ObjectPtr*>(LocalVarAddress(
+                  frame->fp(), runtime_frame_layout.FrameSlotForVariableIndex(
+                                   SuspendState::kSuspendStateVarIndex))));
+    if (suspend_state.IsSuspendState()) {
+      *is_async = true;
+      return caller_closure_finder->FindCallerFromSuspendState(
+          SuspendState::Cast(suspend_state));
+    }
+
+    // Still running the sync part before the first await.
+    return Closure::null();
+  }
+
   if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) {
     // Next, look up caller's closure on the stack and walk backwards
     // through the yields.
@@ -506,6 +548,7 @@
   auto& function = Function::Handle(zone);
   auto& closure = Closure::Handle(zone, leaf_closure.ptr());
   auto& pc_descs = PcDescriptors::Handle(zone);
+  auto& suspend_state = SuspendState::Handle(zone);
 
   // Inject async suspension marker.
   code_array.Add(StubCode::AsynchronousGapMarker());
@@ -518,16 +561,31 @@
     if (function.IsNull()) {
       continue;
     }
-    // In hot-reload-test-mode we sometimes have to do this:
-    code = function.EnsureHasCode();
-    RELEASE_ASSERT(!code.IsNull());
-    code_array.Add(code);
-    pc_descs = code.pc_descriptors();
-    const intptr_t pc_offset = FindPcOffset(pc_descs, GetYieldIndex(closure));
-    // Unlike other sources of PC offsets, the offset may be 0 here if we
-    // reach a non-async closure receiving the yielded value.
-    ASSERT(pc_offset >= 0);
-    pc_offset_array->Add(pc_offset);
+    if (caller_closure_finder->IsCompactAsyncCallback(function)) {
+      suspend_state =
+          caller_closure_finder->GetSuspendStateFromAsyncCallback(closure);
+      const uword pc = suspend_state.pc();
+      if (pc == 0) {
+        // Async function is already resumed.
+        continue;
+      }
+      code = suspend_state.GetCodeObject();
+      code_array.Add(code);
+      const uword pc_offset = pc - code.PayloadStart();
+      ASSERT(pc_offset > 0 && pc_offset <= code.Size());
+      pc_offset_array->Add(pc_offset);
+    } else {
+      // In hot-reload-test-mode we sometimes have to do this:
+      code = function.EnsureHasCode();
+      RELEASE_ASSERT(!code.IsNull());
+      code_array.Add(code);
+      pc_descs = code.pc_descriptors();
+      const intptr_t pc_offset = FindPcOffset(pc_descs, GetYieldIndex(closure));
+      // Unlike other sources of PC offsets, the offset may be 0 here if we
+      // reach a non-async closure receiving the yielded value.
+      ASSERT(pc_offset >= 0);
+      pc_offset_array->Add(pc_offset);
+    }
 
     // Inject async suspension marker.
     code_array.Add(StubCode::AsynchronousGapMarker());
diff --git a/runtime/vm/stack_trace.h b/runtime/vm/stack_trace.h
index 58a4cba..bab4fd1 100644
--- a/runtime/vm/stack_trace.h
+++ b/runtime/vm/stack_trace.h
@@ -36,6 +36,17 @@
   // we can do this by finding and following their awaited Futures.
   ClosurePtr FindCaller(const Closure& receiver_closure);
 
+  // Find caller closure from a SuspendState of a resumed async function.
+  ClosurePtr FindCallerFromSuspendState(const SuspendState& suspend_state);
+
+  // Returns true if given closure function is a Future callback
+  // corresponding to an async function.
+  bool IsCompactAsyncCallback(const Function& function);
+
+  // Returns SuspendState from the given Future callback which corresponds
+  // to an async function.
+  SuspendStatePtr GetSuspendStateFromAsyncCallback(const Closure& closure);
+
   // Finds the awaited Future from an async function receiver closure.
   ObjectPtr GetAsyncFuture(const Closure& receiver_closure);
 
@@ -64,6 +75,7 @@
   Context& receiver_context_;
   Function& receiver_function_;
   Function& parent_function_;
+  SuspendState& suspend_state_;
 
   Object& context_entry_;
   Object& future_;
diff --git a/runtime/vm/stub_code_list.h b/runtime/vm/stub_code_list.h
index 7ac3cde..b035700 100644
--- a/runtime/vm/stub_code_list.h
+++ b/runtime/vm/stub_code_list.h
@@ -149,6 +149,12 @@
   V(InstantiateTypeArgumentsMayShareInstantiatorTA)                            \
   V(InstantiateTypeArgumentsMayShareFunctionTA)                                \
   V(NoSuchMethodDispatcher)                                                    \
+  V(AwaitAsync)                                                                \
+  V(InitAsync)                                                                 \
+  V(Resume)                                                                    \
+  V(ReturnAsync)                                                               \
+  V(ReturnAsyncNotFuture)                                                      \
+  V(AsyncExceptionHandler)                                                     \
   V(UnknownDartCode)
 
 }  // namespace dart
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index f96d8d3..34053dc 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -244,6 +244,7 @@
   V(StringBase, "_StringBase")                                                 \
   V(Struct, "Struct")                                                          \
   V(SubtypeTestCache, "SubtypeTestCache")                                      \
+  V(SuspendStateVar, ":suspend_state_var")                                     \
   V(LoadingUnit, "LoadingUnit")                                                \
   V(SwitchExpr, ":switch_expr")                                                \
   V(Symbol, "Symbol")                                                          \
@@ -379,6 +380,7 @@
   V(_StreamController, "_StreamController")                                    \
   V(_StreamIterator, "_StreamIterator")                                        \
   V(_String, "String")                                                         \
+  V(_SuspendState, "_SuspendState")                                            \
   V(_SyncIterator, "_SyncIterator")                                            \
   V(_SyncStreamController, "_SyncStreamController")                            \
   V(_TransferableTypedDataImpl, "_TransferableTypedDataImpl")                  \
@@ -408,13 +410,16 @@
   V(_WeakProperty, "_WeakProperty")                                            \
   V(_WeakReferenceImpl, "_WeakReferenceImpl")                                  \
   V(_typedDataBase, "_typedDataBase")                                          \
+  V(_awaitAsync, "_awaitAsync")                                                \
   V(_classRangeCheck, "_classRangeCheck")                                      \
   V(_ensureScheduleImmediate, "_ensureScheduleImmediate")                      \
   V(_future, "_future")                                                        \
+  V(_handleException, "_handleException")                                      \
   V(_handleMessage, "_handleMessage")                                          \
   V(_handleFinalizerMessage, "_handleFinalizerMessage")                        \
   V(_handleNativeFinalizerMessage, "_handleNativeFinalizerMessage")            \
   V(_hasValue, "_hasValue")                                                    \
+  V(_initAsync, "_initAsync")                                                  \
   V(_instanceOf, "_instanceOf")                                                \
   V(_listGetAt, "_listGetAt")                                                  \
   V(_listLength, "_listLength")                                                \
@@ -432,6 +437,8 @@
   V(_onData, "_onData")                                                        \
   V(_rehashObjects, "_rehashObjects")                                          \
   V(_resultOrListeners, "_resultOrListeners")                                  \
+  V(_returnAsync, "_returnAsync")                                              \
+  V(_returnAsyncNotFuture, "_returnAsyncNotFuture")                            \
   V(_runExtension, "_runExtension")                                            \
   V(_runPendingImmediateCallback, "_runPendingImmediateCallback")              \
   V(_scanFlags, "_scanFlags")                                                  \
diff --git a/runtime/vm/tagged_pointer.h b/runtime/vm/tagged_pointer.h
index 09968d4..172831f 100644
--- a/runtime/vm/tagged_pointer.h
+++ b/runtime/vm/tagged_pointer.h
@@ -410,6 +410,7 @@
 DEFINE_TAGGED_POINTER(ReceivePort, Instance)
 DEFINE_TAGGED_POINTER(TransferableTypedData, Instance)
 DEFINE_TAGGED_POINTER(StackTrace, Instance)
+DEFINE_TAGGED_POINTER(SuspendState, Instance)
 DEFINE_TAGGED_POINTER(RegExp, Instance)
 DEFINE_TAGGED_POINTER(WeakProperty, Instance)
 DEFINE_TAGGED_POINTER(WeakReference, Instance)
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index f742cd0..32dc3ba 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -166,6 +166,13 @@
   CACHED_NON_VM_STUB_LIST(V)                                                   \
   CACHED_VM_STUBS_LIST(V)
 
+#define CACHED_FUNCTION_ENTRY_POINTS_LIST(V)                                   \
+  V(suspend_state_init_async)                                                  \
+  V(suspend_state_await_async)                                                 \
+  V(suspend_state_return_async)                                                \
+  V(suspend_state_return_async_not_future)                                     \
+  V(suspend_state_handle_exception)
+
 // This assertion marks places which assume that boolean false immediate
 // follows bool true in the CACHED_VM_OBJECTS_LIST
 #define ASSERT_BOOL_FALSE_FOLLOWS_BOOL_TRUE()                                  \
@@ -724,6 +731,13 @@
   static bool ObjectAtOffset(intptr_t offset, Object* object);
   static intptr_t OffsetFromThread(const RuntimeEntry* runtime_entry);
 
+#define DEFINE_OFFSET_METHOD(name)                                             \
+  static intptr_t name##_entry_point_offset() {                                \
+    return OFFSET_OF(Thread, name##_entry_point_);                             \
+  }
+  CACHED_FUNCTION_ENTRY_POINTS_LIST(DEFINE_OFFSET_METHOD)
+#undef DEFINE_OFFSET_METHOD
+
 #if defined(DEBUG)
   // For asserts only. Has false positives when running with a simulator or
   // SafeStack.
@@ -1153,6 +1167,10 @@
   uword write_barrier_wrappers_entry_points_[kNumberOfDartAvailableCpuRegs];
 #endif
 
+#define DECLARE_MEMBERS(name) uword name##_entry_point_ = 0;
+  CACHED_FUNCTION_ENTRY_POINTS_LIST(DECLARE_MEMBERS)
+#undef DECLARE_MEMBERS
+
   // JumpToExceptionHandler state:
   ObjectPtr active_exception_;
   ObjectPtr active_stacktrace_;
diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc
index fc57084..ed63079 100644
--- a/runtime/vm/timeline.cc
+++ b/runtime/vm/timeline.cc
@@ -232,10 +232,6 @@
   }
 }
 
-TimelineEventRecorder* Timeline::recorder() {
-  return recorder_;
-}
-
 void Timeline::ReclaimCachedBlocksFromThreads() {
   RecorderLockScope rl;
   TimelineEventRecorder* recorder = Timeline::recorder();
@@ -389,6 +385,7 @@
 
 TimelineEventRecorder* Timeline::recorder_ = NULL;
 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);
@@ -739,7 +736,7 @@
 int64_t TimelineEvent::TimeDuration() const {
   if (timestamp1_ == 0) {
     // This duration is still open, use current time as end.
-    return OS::GetCurrentMonotonicMicros() - timestamp0_;
+    return OS::GetCurrentMonotonicMicrosForTimeline() - timestamp0_;
   }
   return timestamp1_ - timestamp0_;
 }
@@ -1681,7 +1678,7 @@
   ASSERT((phase[0] == 'n') || (phase[0] == 'b') || (phase[0] == 'e') ||
          (phase[0] == 'B') || (phase[0] == 'E'));
   ASSERT(phase[1] == '\0');
-  const int64_t start = OS::GetCurrentMonotonicMicros();
+  const int64_t start = OS::GetCurrentMonotonicMicrosForTimeline();
   const int64_t start_cpu = OS::GetCurrentThreadCPUMicrosForTimeline();
   switch (phase[0]) {
     case 'n':
@@ -1713,7 +1710,7 @@
                                                int64_t type,
                                                int64_t flow_id,
                                                char* args) {
-  const int64_t start = OS::GetCurrentMonotonicMicros();
+  const int64_t start = OS::GetCurrentMonotonicMicrosForTimeline();
   TimelineEvent::EventType event_type =
       static_cast<TimelineEvent::EventType>(type);
   switch (event_type) {
@@ -1739,7 +1736,7 @@
                                                   const char* category,
                                                   char* name,
                                                   char* args) {
-  const int64_t start = OS::GetCurrentMonotonicMicros();
+  const int64_t start = OS::GetCurrentMonotonicMicrosForTimeline();
   event->Instant(name, start);
   event->set_owns_label(true);
   event->CompleteWithPreSerializedArgs(args);
diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h
index 8f1df56..7456aab 100644
--- a/runtime/vm/timeline.h
+++ b/runtime/vm/timeline.h
@@ -174,7 +174,14 @@
   static void Cleanup();
 
   // Access the global recorder. Not thread safe.
-  static TimelineEventRecorder* recorder();
+  static TimelineEventRecorder* recorder() { return recorder_; }
+
+  static bool recorder_discards_clock_values() {
+    return recorder_discards_clock_values_;
+  }
+  static void set_recorder_discards_clock_values(bool value) {
+    recorder_discards_clock_values_ = value;
+  }
 
   // Reclaim all |TimelineEventBlocks|s that are cached by threads.
   static void ReclaimCachedBlocksFromThreads();
@@ -204,6 +211,7 @@
  private:
   static TimelineEventRecorder* recorder_;
   static MallocGrowableArray<char*>* enabled_streams_;
+  static bool recorder_discards_clock_values_;
 
 #define TIMELINE_STREAM_DECLARE(name, fuchsia_name)                            \
   static TimelineStream stream_##name##_;
@@ -293,26 +301,27 @@
   // Marks the beginning of an asynchronous operation with |async_id|.
   void AsyncBegin(const char* label,
                   int64_t async_id,
-                  int64_t micros = OS::GetCurrentMonotonicMicros());
+                  int64_t micros = OS::GetCurrentMonotonicMicrosForTimeline());
   // Marks an instantaneous event associated with |async_id|.
-  void AsyncInstant(const char* label,
-                    int64_t async_id,
-                    int64_t micros = OS::GetCurrentMonotonicMicros());
+  void AsyncInstant(
+      const char* label,
+      int64_t async_id,
+      int64_t micros = OS::GetCurrentMonotonicMicrosForTimeline());
   // Marks the end of an asynchronous operation associated with |async_id|.
   void AsyncEnd(const char* label,
                 int64_t async_id,
-                int64_t micros = OS::GetCurrentMonotonicMicros());
+                int64_t micros = OS::GetCurrentMonotonicMicrosForTimeline());
 
   void DurationBegin(
       const char* label,
-      int64_t micros = OS::GetCurrentMonotonicMicros(),
+      int64_t micros = OS::GetCurrentMonotonicMicrosForTimeline(),
       int64_t thread_micros = OS::GetCurrentThreadCPUMicrosForTimeline());
   void DurationEnd(
-      int64_t micros = OS::GetCurrentMonotonicMicros(),
+      int64_t micros = OS::GetCurrentMonotonicMicrosForTimeline(),
       int64_t thread_micros = OS::GetCurrentThreadCPUMicrosForTimeline());
 
   void Instant(const char* label,
-               int64_t micros = OS::GetCurrentMonotonicMicros());
+               int64_t micros = OS::GetCurrentMonotonicMicrosForTimeline());
 
   void Duration(const char* label,
                 int64_t start_micros,
@@ -322,28 +331,28 @@
 
   void Begin(
       const char* label,
-      int64_t micros = OS::GetCurrentMonotonicMicros(),
+      int64_t micros = OS::GetCurrentMonotonicMicrosForTimeline(),
       int64_t thread_micros = OS::GetCurrentThreadCPUMicrosForTimeline());
 
   void End(const char* label,
-           int64_t micros = OS::GetCurrentMonotonicMicros(),
+           int64_t micros = OS::GetCurrentMonotonicMicrosForTimeline(),
            int64_t thread_micros = OS::GetCurrentThreadCPUMicrosForTimeline());
 
   void Counter(const char* label,
-               int64_t micros = OS::GetCurrentMonotonicMicros());
+               int64_t micros = OS::GetCurrentMonotonicMicrosForTimeline());
 
   void FlowBegin(const char* label,
                  int64_t async_id,
-                 int64_t micros = OS::GetCurrentMonotonicMicros());
+                 int64_t micros = OS::GetCurrentMonotonicMicrosForTimeline());
   void FlowStep(const char* label,
                 int64_t async_id,
-                int64_t micros = OS::GetCurrentMonotonicMicros());
+                int64_t micros = OS::GetCurrentMonotonicMicrosForTimeline());
   void FlowEnd(const char* label,
                int64_t async_id,
-               int64_t micros = OS::GetCurrentMonotonicMicros());
+               int64_t micros = OS::GetCurrentMonotonicMicrosForTimeline());
 
   void Metadata(const char* label,
-                int64_t micros = OS::GetCurrentMonotonicMicros());
+                int64_t micros = OS::GetCurrentMonotonicMicrosForTimeline());
 
   void CompleteWithPreSerializedArgs(char* args_json);
 
diff --git a/runtime/vm/timeline_android.cc b/runtime/vm/timeline_android.cc
index 93e2faa..f91ee42 100644
--- a/runtime/vm/timeline_android.cc
+++ b/runtime/vm/timeline_android.cc
@@ -41,7 +41,9 @@
 }
 
 TimelineEventSystraceRecorder::TimelineEventSystraceRecorder()
-    : TimelineEventPlatformRecorder(), systrace_fd_(OpenTraceFD()) {}
+    : TimelineEventPlatformRecorder(), systrace_fd_(OpenTraceFD()) {
+  Timeline::set_recorder_discards_clock_values(true);
+}
 
 TimelineEventSystraceRecorder::~TimelineEventSystraceRecorder() {
   if (systrace_fd_ >= 0) {
diff --git a/runtime/vm/timeline_linux.cc b/runtime/vm/timeline_linux.cc
index f685df2..a85f9e5 100644
--- a/runtime/vm/timeline_linux.cc
+++ b/runtime/vm/timeline_linux.cc
@@ -41,7 +41,9 @@
 }
 
 TimelineEventSystraceRecorder::TimelineEventSystraceRecorder()
-    : TimelineEventPlatformRecorder(), systrace_fd_(OpenTraceFD()) {}
+    : TimelineEventPlatformRecorder(), systrace_fd_(OpenTraceFD()) {
+  Timeline::set_recorder_discards_clock_values(true);
+}
 
 TimelineEventSystraceRecorder::~TimelineEventSystraceRecorder() {
   if (systrace_fd_ >= 0) {
diff --git a/runtime/vm/timeline_macos.cc b/runtime/vm/timeline_macos.cc
index 1bda7e5..cbb2efa 100644
--- a/runtime/vm/timeline_macos.cc
+++ b/runtime/vm/timeline_macos.cc
@@ -12,7 +12,9 @@
 
 // Only available on iOS 12.0, macOS 10.14 or above
 TimelineEventMacosRecorder::TimelineEventMacosRecorder()
-    : TimelineEventPlatformRecorder() {}
+    : TimelineEventPlatformRecorder() {
+  Timeline::set_recorder_discards_clock_values(true);
+}
 
 TimelineEventMacosRecorder::~TimelineEventMacosRecorder() {}
 
diff --git a/runtime/vm/visitor.h b/runtime/vm/visitor.h
index fd2a78c..2ed6547 100644
--- a/runtime/vm/visitor.h
+++ b/runtime/vm/visitor.h
@@ -64,6 +64,15 @@
     return shared_class_table_;
   }
 
+  // Returns true if pointers of the given SuspendState object can be visited.
+  // Compactor overrides this method in order to postpone visiting SuspendState
+  // objects with evacuated frames, as visiting them may touch other Dart
+  // objects (array of InstructionsTables) which have inconsistent state
+  // until compaction is finished.
+  virtual bool CanVisitSuspendStatePointers(SuspendStatePtr suspend_state) {
+    return true;
+  }
+
  private:
   IsolateGroup* isolate_group_;
   const char* gc_root_type_;
diff --git a/sdk/lib/_internal/vm/lib/async_patch.dart b/sdk/lib/_internal/vm/lib/async_patch.dart
index 3d4b20b..27eb7e6 100644
--- a/sdk/lib/_internal/vm/lib/async_patch.dart
+++ b/sdk/lib/_internal/vm/lib/async_patch.dart
@@ -7,7 +7,7 @@
 /// by patches of that library. We plan to change this when we have a shared
 /// front end and simply use parts.
 
-import "dart:_internal" show VMLibraryHooks, patch;
+import "dart:_internal" show VMLibraryHooks, patch, unsafeCast;
 
 /// These are the additional parts of this patch library:
 // part "deferred_load_patch.dart";
@@ -70,8 +70,8 @@
 ///
 /// Returns the result of registering with `.then`.
 Future _awaitHelper(var object, dynamic Function(dynamic) thenCallback,
-    dynamic Function(dynamic, StackTrace) errorCallback) {
-  late _Future future;
+    dynamic Function(Object, StackTrace) errorCallback) {
+  _Future future;
   if (object is _Future) {
     future = object;
   } else if (object is! Future) {
@@ -318,3 +318,154 @@
 
 @pragma("vm:external-name", "AsyncStarMoveNext_debuggerStepCheck")
 external void _moveNextDebuggerStepCheck(Function async_op);
+
+@pragma("vm:entry-point")
+class _SuspendState {
+  static const bool _trace = false;
+
+  @pragma("vm:entry-point", "call")
+  @pragma("vm:invisible")
+  static Object? _initAsync<T>() {
+    if (_trace) print('_initAsync<$T>');
+    return new _Future<T>();
+  }
+
+  @pragma("vm:invisible")
+  @pragma("vm:recognized", "other")
+  void _createAsyncCallbacks() {
+    if (_trace) print('_createAsyncCallbacks');
+
+    @pragma("vm:invisible")
+    thenCallback(value) {
+      if (_trace) print('thenCallback (this=$this, value=$value)');
+      _resume(value, null, null);
+    }
+
+    @pragma("vm:invisible")
+    errorCallback(exception, stackTrace) {
+      if (_trace) {
+        print('errorCallback (this=$this, '
+            'exception=$exception, stackTrace=$stackTrace)');
+      }
+      _resume(null, exception, stackTrace);
+    }
+
+    final currentZone = Zone._current;
+    if (identical(currentZone, _rootZone) ||
+        identical(currentZone._registerUnaryCallback,
+            _rootZone._registerUnaryCallback)) {
+      _thenCallback = thenCallback;
+    } else {
+      _thenCallback =
+          currentZone.registerUnaryCallback<dynamic, dynamic>(thenCallback);
+    }
+    if (identical(currentZone, _rootZone) ||
+        identical(currentZone._registerBinaryCallback,
+            _rootZone._registerBinaryCallback)) {
+      _errorCallback = errorCallback;
+    } else {
+      _errorCallback = currentZone
+          .registerBinaryCallback<dynamic, Object, StackTrace>(errorCallback);
+    }
+  }
+
+  @pragma("vm:entry-point", "call")
+  @pragma("vm:invisible")
+  Object? _awaitAsync(Object? object) {
+    if (_trace) print('_awaitAsync (object=$object)');
+    if (_thenCallback == null) {
+      _createAsyncCallbacks();
+    }
+    _awaitHelper(object, unsafeCast<dynamic Function(dynamic)>(_thenCallback),
+        unsafeCast<dynamic Function(Object, StackTrace)>(_errorCallback));
+    return _future;
+  }
+
+  @pragma("vm:entry-point", "call")
+  @pragma("vm:invisible")
+  static Future _returnAsync(Object suspendState, Object? returnValue) {
+    if (_trace) {
+      print('_returnAsync (suspendState=$suspendState, '
+          'returnValue=$returnValue)');
+    }
+    _Future future;
+    bool isSync = true;
+    if (suspendState is _SuspendState) {
+      future = suspendState._future;
+    } else {
+      future = unsafeCast<_Future>(suspendState);
+      isSync = false;
+    }
+    _completeOnAsyncReturn(future, returnValue, isSync);
+    return future;
+  }
+
+  @pragma("vm:entry-point", "call")
+  @pragma("vm:invisible")
+  static Future _returnAsyncNotFuture(
+      Object suspendState, Object? returnValue) {
+    if (_trace) {
+      print('_returnAsyncNotFuture (suspendState=$suspendState, '
+          'returnValue=$returnValue)');
+    }
+    _Future future;
+    bool isSync = true;
+    if (suspendState is _SuspendState) {
+      future = suspendState._future;
+    } else {
+      future = unsafeCast<_Future>(suspendState);
+      isSync = false;
+    }
+    _completeWithNoFutureOnAsyncReturn(future, returnValue, isSync);
+    return future;
+  }
+
+  @pragma("vm:entry-point", "call")
+  @pragma("vm:invisible")
+  static Future _handleException(
+      Object suspendState, Object exception, StackTrace stackTrace) {
+    if (_trace) {
+      print('_handleException (suspendState=$suspendState, '
+          'exception=$exception, stackTrace=$stackTrace)');
+    }
+    _Future future;
+    bool isSync = true;
+    if (suspendState is _SuspendState) {
+      future = suspendState._future;
+    } else {
+      future = unsafeCast<_Future>(suspendState);
+      isSync = false;
+    }
+    _completeOnAsyncError(future, exception, stackTrace, isSync);
+    return future;
+  }
+
+  @pragma("vm:recognized", "other")
+  @pragma("vm:prefer-inline")
+  external set _future(_Future value);
+
+  @pragma("vm:recognized", "other")
+  @pragma("vm:prefer-inline")
+  external _Future get _future;
+
+  @pragma("vm:recognized", "other")
+  @pragma("vm:prefer-inline")
+  external set _thenCallback(Function? value);
+
+  @pragma("vm:recognized", "other")
+  @pragma("vm:prefer-inline")
+  external Function? get _thenCallback;
+
+  @pragma("vm:recognized", "other")
+  @pragma("vm:prefer-inline")
+  external set _errorCallback(Function value);
+
+  @pragma("vm:recognized", "other")
+  @pragma("vm:prefer-inline")
+  external Function get _errorCallback;
+
+  @pragma("vm:recognized", "other")
+  @pragma("vm:never-inline")
+  external void _resume(
+      dynamic value, Object? exception, StackTrace? stackTrace);
+}
diff --git a/sdk/lib/js_util/js_util.dart b/sdk/lib/js_util/js_util.dart
index 081bcb8..ce77e95 100644
--- a/sdk/lib/js_util/js_util.dart
+++ b/sdk/lib/js_util/js_util.dart
@@ -285,6 +285,90 @@
       'Object', 'new #(#, #, #, #)', constr, arg1, arg2, arg3, arg4);
 }
 
+/// Perform JavaScript addition (`+`) on two values.
+@pragma('dart2js:tryInline')
+T add<T>(Object? first, Object? second) {
+  return JS<dynamic>('Object', '# + #', first, second);
+}
+
+/// Perform JavaScript subtraction (`-`) on two values.
+@pragma('dart2js:tryInline')
+T subtract<T>(Object? first, Object? second) {
+  return JS<dynamic>('Object', '# - #', first, second);
+}
+
+/// Perform JavaScript multiplication (`*`) on two values.
+@pragma('dart2js:tryInline')
+T multiply<T>(Object? first, Object? second) {
+  return JS<dynamic>('Object', '# * #', first, second);
+}
+
+/// Perform JavaScript division (`/`) on two values.
+@pragma('dart2js:tryInline')
+T divide<T>(Object? first, Object? second) {
+  return JS<dynamic>('Object', '# / #', first, second);
+}
+
+/// Perform JavaScript exponentiation (`**`) on two values.
+@pragma('dart2js:tryInline')
+T exponentiate<T>(Object? first, Object? second) {
+  return JS<dynamic>('Object', '# ** #', first, second);
+}
+
+/// Perform JavaScript remainder (`%`) on two values.
+@pragma('dart2js:tryInline')
+T modulo<T>(Object? first, Object? second) {
+  return JS<dynamic>('Object', '# % #', first, second);
+}
+
+/// Perform JavaScript equality comparison (`==`) on two values.
+@pragma('dart2js:tryInline')
+bool equal<T>(Object? first, Object? second) {
+  return JS<bool>('bool', '# == #', first, second);
+}
+
+/// Perform JavaScript strict equality comparison (`===`) on two values.
+@pragma('dart2js:tryInline')
+bool strictEqual<T>(Object? first, Object? second) {
+  return JS<bool>('bool', '# === #', first, second);
+}
+
+/// Perform JavaScript inequality comparison (`!=`) on two values.
+@pragma('dart2js:tryInline')
+bool notEqual<T>(Object? first, Object? second) {
+  return JS<bool>('bool', '# != #', first, second);
+}
+
+/// Perform JavaScript strict inequality comparison (`!==`) on two values.
+@pragma('dart2js:tryInline')
+bool strictNotEqual<T>(Object? first, Object? second) {
+  return JS<bool>('bool', '# !== #', first, second);
+}
+
+/// Perform JavaScript greater than comparison (`>`) of two values.
+@pragma('dart2js:tryInline')
+bool greaterThan<T>(Object? first, Object? second) {
+  return JS<bool>('bool', '# > #', first, second);
+}
+
+/// Perform JavaScript greater than or equal comparison (`>=`) of two values.
+@pragma('dart2js:tryInline')
+bool greaterThanOrEqual<T>(Object? first, Object? second) {
+  return JS<bool>('bool', '# >= #', first, second);
+}
+
+/// Perform JavaScript less than comparison (`<`) of two values.
+@pragma('dart2js:tryInline')
+bool lessThan<T>(Object? first, Object? second) {
+  return JS<bool>('bool', '# < #', first, second);
+}
+
+/// Perform JavaScript less than or equal comparison (`<=`) of two values.
+@pragma('dart2js:tryInline')
+bool lessThanOrEqual<T>(Object? first, Object? second) {
+  return JS<bool>('bool', '# <= #', first, second);
+}
+
 /// Exception for when the promise is rejected with a `null` or `undefined`
 /// value.
 ///
diff --git a/tests/language/async/and_or_test.dart b/tests/language/async/and_or_test.dart
index be24bb1..e636211 100644
--- a/tests/language/async/and_or_test.dart
+++ b/tests/language/async/and_or_test.dart
@@ -1,6 +1,10 @@
 // Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=
+// VMOptions=--stress_write_barrier_elimination
+
 import "dart:async";
 import "package:expect/expect.dart";
 import "package:async_helper/async_helper.dart";
diff --git a/tests/language/async/async_test.dart b/tests/language/async/async_test.dart
index 9d1c01d..69638f0 100644
--- a/tests/language/async/async_test.dart
+++ b/tests/language/async/async_test.dart
@@ -2,6 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// VMOptions=
+// VMOptions=--stress_write_barrier_elimination
+
 import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
 
diff --git a/tests/language/await/for_test.dart b/tests/language/await/for_test.dart
index 0c72a4d..7026e8b 100644
--- a/tests/language/await/for_test.dart
+++ b/tests/language/await/for_test.dart
@@ -2,6 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// VMOptions=
+// VMOptions=--stress_write_barrier_elimination
+
 import "dart:async";
 import "package:expect/expect.dart";
 import "package:async_helper/async_helper.dart";
diff --git a/tests/language_2/async/and_or_test.dart b/tests/language_2/async/and_or_test.dart
index 086e8e6..8a45868 100644
--- a/tests/language_2/async/and_or_test.dart
+++ b/tests/language_2/async/and_or_test.dart
@@ -2,6 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// VMOptions=
+// VMOptions=--stress_write_barrier_elimination
+
 // @dart = 2.9
 import "dart:async";
 import "package:expect/expect.dart";
diff --git a/tests/language_2/async/async_test.dart b/tests/language_2/async/async_test.dart
index db5c44a..27fcecf 100644
--- a/tests/language_2/async/async_test.dart
+++ b/tests/language_2/async/async_test.dart
@@ -2,6 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// VMOptions=
+// VMOptions=--stress_write_barrier_elimination
+
 // @dart = 2.9
 
 import 'package:async_helper/async_helper.dart';
diff --git a/tests/language_2/await/for_test.dart b/tests/language_2/await/for_test.dart
index 214a61f..da1c7e2 100644
--- a/tests/language_2/await/for_test.dart
+++ b/tests/language_2/await/for_test.dart
@@ -2,6 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// VMOptions=
+// VMOptions=--stress_write_barrier_elimination
+
 // @dart = 2.9
 
 import "dart:async";
diff --git a/tests/lib/js/js_util/bigint_test.dart b/tests/lib/js/js_util/bigint_test.dart
new file mode 100644
index 0000000..47462e5
--- /dev/null
+++ b/tests/lib/js/js_util/bigint_test.dart
@@ -0,0 +1,110 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests invoking JS BigInt functionality through js_util. This interop
+// requires usage of the operator functions exposed through js_util.
+
+@JS()
+library js_util_bigint_test;
+
+import 'package:js/js.dart';
+import 'package:js/js_util.dart' as js_util;
+import 'package:expect/minitest.dart';
+
+@JS('BigInt')
+external Object BigInt(Object value);
+
+main() {
+  group('bigint', () {
+    test('addition', () {
+      final one = BigInt('1');
+      final two = BigInt('2');
+      final three = BigInt('3');
+      expect(js_util.strictEqual(js_util.add(one, two), three), isTrue);
+      expect(js_util.strictEqual(js_util.add(one, one), three), isFalse);
+    });
+
+    test('subtraction', () {
+      final one = BigInt('1');
+      final two = BigInt('2');
+      final three = BigInt('3');
+      expect(js_util.strictEqual(js_util.subtract(three, one), two), isTrue);
+      expect(js_util.strictEqual(js_util.subtract(three, two), two), isFalse);
+    });
+
+    test('multiplication', () {
+      final two = BigInt('2');
+      final four = BigInt('4');
+      expect(js_util.strictEqual(js_util.multiply(two, two), four), isTrue);
+      expect(js_util.strictEqual(js_util.multiply(two, four), four), isFalse);
+    });
+
+    test('division', () {
+      final two = BigInt('2');
+      final four = BigInt('4');
+      expect(js_util.strictEqual(js_util.divide(four, two), two), isTrue);
+      expect(js_util.strictEqual(js_util.divide(four, four), two), isFalse);
+    });
+
+    test('exponentiation', () {
+      final two = BigInt('2');
+      final three = BigInt('3');
+      final nine = BigInt('9');
+      expect(
+          js_util.strictEqual(js_util.exponentiate(three, two), nine), isTrue);
+      expect(js_util.strictEqual(js_util.exponentiate(three, three), nine),
+          isFalse);
+    });
+
+    test('exponentiation2', () {
+      final two = BigInt('2');
+      final three = BigInt('3');
+      final five = BigInt('5');
+      expect(
+          js_util.add(
+              '', js_util.exponentiate(js_util.exponentiate(five, three), two)),
+          '15625');
+      expect(
+          js_util.add(
+              '', js_util.exponentiate(five, js_util.exponentiate(three, two))),
+          '1953125');
+    });
+
+    test('modulo', () {
+      final zero = BigInt('0');
+      final three = BigInt('3');
+      final nine = BigInt('9');
+      expect(js_util.strictEqual(js_util.modulo(nine, three), zero), isTrue);
+      expect(js_util.strictEqual(js_util.modulo(nine, three), nine), isFalse);
+    });
+
+    test('equality', () {
+      final one = BigInt('1');
+      expect(js_util.equal(one, 1), isTrue);
+      expect(js_util.strictEqual(one, 1), isFalse);
+      expect(js_util.notEqual(one, 1), isFalse);
+      expect(js_util.strictNotEqual(one, 1), isTrue);
+    });
+
+    test('comparisons', () {
+      final zero = BigInt('0');
+      final one = BigInt('1');
+      final otherOne = BigInt('1');
+      expect(js_util.greaterThan(one, zero), isTrue);
+      expect(js_util.greaterThan(one, 0), isTrue);
+      expect(js_util.greaterThan(2, one), isTrue);
+      expect(js_util.greaterThanOrEqual(one, otherOne), isTrue);
+      expect(js_util.greaterThanOrEqual(one, 1), isTrue);
+      expect(js_util.greaterThanOrEqual(one, 2), isFalse);
+
+      expect(js_util.lessThan(one, zero), isFalse);
+      expect(js_util.lessThan(zero, one), isTrue);
+      expect(js_util.lessThan(one, 2), isTrue);
+      expect(js_util.lessThan(one, 0), isFalse);
+      expect(js_util.lessThanOrEqual(one, otherOne), isTrue);
+      expect(js_util.lessThanOrEqual(one, 1), isTrue);
+      expect(js_util.lessThanOrEqual(2, one), isFalse);
+    });
+  });
+}
diff --git a/tests/lib_2/js/js_util/bigint_test.dart b/tests/lib_2/js/js_util/bigint_test.dart
new file mode 100644
index 0000000..47462e5
--- /dev/null
+++ b/tests/lib_2/js/js_util/bigint_test.dart
@@ -0,0 +1,110 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests invoking JS BigInt functionality through js_util. This interop
+// requires usage of the operator functions exposed through js_util.
+
+@JS()
+library js_util_bigint_test;
+
+import 'package:js/js.dart';
+import 'package:js/js_util.dart' as js_util;
+import 'package:expect/minitest.dart';
+
+@JS('BigInt')
+external Object BigInt(Object value);
+
+main() {
+  group('bigint', () {
+    test('addition', () {
+      final one = BigInt('1');
+      final two = BigInt('2');
+      final three = BigInt('3');
+      expect(js_util.strictEqual(js_util.add(one, two), three), isTrue);
+      expect(js_util.strictEqual(js_util.add(one, one), three), isFalse);
+    });
+
+    test('subtraction', () {
+      final one = BigInt('1');
+      final two = BigInt('2');
+      final three = BigInt('3');
+      expect(js_util.strictEqual(js_util.subtract(three, one), two), isTrue);
+      expect(js_util.strictEqual(js_util.subtract(three, two), two), isFalse);
+    });
+
+    test('multiplication', () {
+      final two = BigInt('2');
+      final four = BigInt('4');
+      expect(js_util.strictEqual(js_util.multiply(two, two), four), isTrue);
+      expect(js_util.strictEqual(js_util.multiply(two, four), four), isFalse);
+    });
+
+    test('division', () {
+      final two = BigInt('2');
+      final four = BigInt('4');
+      expect(js_util.strictEqual(js_util.divide(four, two), two), isTrue);
+      expect(js_util.strictEqual(js_util.divide(four, four), two), isFalse);
+    });
+
+    test('exponentiation', () {
+      final two = BigInt('2');
+      final three = BigInt('3');
+      final nine = BigInt('9');
+      expect(
+          js_util.strictEqual(js_util.exponentiate(three, two), nine), isTrue);
+      expect(js_util.strictEqual(js_util.exponentiate(three, three), nine),
+          isFalse);
+    });
+
+    test('exponentiation2', () {
+      final two = BigInt('2');
+      final three = BigInt('3');
+      final five = BigInt('5');
+      expect(
+          js_util.add(
+              '', js_util.exponentiate(js_util.exponentiate(five, three), two)),
+          '15625');
+      expect(
+          js_util.add(
+              '', js_util.exponentiate(five, js_util.exponentiate(three, two))),
+          '1953125');
+    });
+
+    test('modulo', () {
+      final zero = BigInt('0');
+      final three = BigInt('3');
+      final nine = BigInt('9');
+      expect(js_util.strictEqual(js_util.modulo(nine, three), zero), isTrue);
+      expect(js_util.strictEqual(js_util.modulo(nine, three), nine), isFalse);
+    });
+
+    test('equality', () {
+      final one = BigInt('1');
+      expect(js_util.equal(one, 1), isTrue);
+      expect(js_util.strictEqual(one, 1), isFalse);
+      expect(js_util.notEqual(one, 1), isFalse);
+      expect(js_util.strictNotEqual(one, 1), isTrue);
+    });
+
+    test('comparisons', () {
+      final zero = BigInt('0');
+      final one = BigInt('1');
+      final otherOne = BigInt('1');
+      expect(js_util.greaterThan(one, zero), isTrue);
+      expect(js_util.greaterThan(one, 0), isTrue);
+      expect(js_util.greaterThan(2, one), isTrue);
+      expect(js_util.greaterThanOrEqual(one, otherOne), isTrue);
+      expect(js_util.greaterThanOrEqual(one, 1), isTrue);
+      expect(js_util.greaterThanOrEqual(one, 2), isFalse);
+
+      expect(js_util.lessThan(one, zero), isFalse);
+      expect(js_util.lessThan(zero, one), isTrue);
+      expect(js_util.lessThan(one, 2), isTrue);
+      expect(js_util.lessThan(one, 0), isFalse);
+      expect(js_util.lessThanOrEqual(one, otherOne), isTrue);
+      expect(js_util.lessThanOrEqual(one, 1), isTrue);
+      expect(js_util.lessThanOrEqual(2, one), isFalse);
+    });
+  });
+}
diff --git a/tests/standalone/io/regress_36030.dart b/tests/standalone/io/regress_36030.dart
new file mode 100644
index 0000000..ed1792d
--- /dev/null
+++ b/tests/standalone/io/regress_36030.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:io";
+
+import "package:expect/expect.dart";
+
+void main() async {
+  // Test that renaming a file doesn't change the modified time.
+  final temp = await Directory.systemTemp.createTemp('regress_36030');
+  final file = await File('${temp.path}/before').create();
+  final modifiedTime = await file.lastModified();
+  await Future.delayed(Duration(seconds: 1));
+  final renamed = await file.rename('${temp.path}/after');
+  final renamedTime = await renamed.lastModified();
+  Expect.equals(renamedTime, modifiedTime);
+}
diff --git a/tests/standalone_2/io/regress_36030.dart b/tests/standalone_2/io/regress_36030.dart
new file mode 100644
index 0000000..ed1792d
--- /dev/null
+++ b/tests/standalone_2/io/regress_36030.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:io";
+
+import "package:expect/expect.dart";
+
+void main() async {
+  // Test that renaming a file doesn't change the modified time.
+  final temp = await Directory.systemTemp.createTemp('regress_36030');
+  final file = await File('${temp.path}/before').create();
+  final modifiedTime = await file.lastModified();
+  await Future.delayed(Duration(seconds: 1));
+  final renamed = await file.rename('${temp.path}/after');
+  final renamedTime = await renamed.lastModified();
+  Expect.equals(renamedTime, modifiedTime);
+}
diff --git a/tools/VERSION b/tools/VERSION
index 08f5c3e..3e99c74 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 18
 PATCH 0
-PRERELEASE 68
+PRERELEASE 69
 PRERELEASE_PATCH 0
\ No newline at end of file