Version 2.15.0-237.0.dev

Merge commit '6dd4ff6a3b3bd55019622fa00d62c2f385f1a9b6' into 'dev'
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_missing_enum_case_clauses.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_missing_enum_case_clauses.dart
index 16a7d03..61fbebc 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_missing_enum_case_clauses.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_missing_enum_case_clauses.dart
@@ -12,6 +12,16 @@
 
 class AddMissingEnumCaseClauses extends CorrectionProducer {
   @override
+  // Adding the missing case is not a sufficient fix (user logic needs adding
+  // too).
+  bool get canBeAppliedInBulk => false;
+
+  @override
+  // Adding the missing case is not a sufficient fix (user logic needs adding
+  // too).
+  bool get canBeAppliedToFile => false;
+
+  @override
   FixKind get fixKind => DartFixKind.ADD_MISSING_ENUM_CASE_CLAUSES;
 
   @override
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_dead_if_null.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_dead_if_null.dart
index 4424d19..96e641f 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_dead_if_null.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_dead_if_null.dart
@@ -14,6 +14,16 @@
 
 class RemoveDeadIfNull extends CorrectionProducer {
   @override
+  // This fix removes the right operand of an if-null which is not predictably
+  // the right thing to do.
+  bool get canBeAppliedInBulk => false;
+
+  @override
+  // This fix removes the right operand of an if-null which is not predictably
+  // the right thing to do.
+  bool get canBeAppliedToFile => false;
+
+  @override
   FixKind get fixKind => DartFixKind.REMOVE_IF_NULL_OPERATOR;
 
   @override
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_clause.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_clause.dart
index b3a9af7..09a3c41 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_clause.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_clause.dart
@@ -11,9 +11,18 @@
 
 class RemoveUnusedCatchClause extends CorrectionProducer {
   @override
+  bool get canBeAppliedInBulk => true;
+
+  @override
+  bool get canBeAppliedToFile => true;
+
+  @override
   FixKind get fixKind => DartFixKind.REMOVE_UNUSED_CATCH_CLAUSE;
 
   @override
+  FixKind get multiFixKind => DartFixKind.REMOVE_UNUSED_CATCH_CLAUSE_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var catchClause = node.parent;
     if (catchClause is! CatchClause) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_stack.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_stack.dart
index 7cdc1ac..1ee1908 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_stack.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_stack.dart
@@ -11,9 +11,18 @@
 
 class RemoveUnusedCatchStack extends CorrectionProducer {
   @override
+  bool get canBeAppliedInBulk => true;
+
+  @override
+  bool get canBeAppliedToFile => true;
+
+  @override
   FixKind get fixKind => DartFixKind.REMOVE_UNUSED_CATCH_STACK;
 
   @override
+  FixKind get multiFixKind => DartFixKind.REMOVE_UNUSED_CATCH_STACK_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var catchClause = node.parent;
     if (catchClause is! CatchClause) {
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index c0f4fbb..e344b12 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -1084,11 +1084,21 @@
     DartFixKindPriority.DEFAULT,
     "Remove unused 'catch' clause",
   );
+  static const REMOVE_UNUSED_CATCH_CLAUSE_MULTI = FixKind(
+    'dart.fix.remove.unusedCatchClause.multi',
+    DartFixKindPriority.IN_FILE,
+    "Remove unused 'catch' clauses in file",
+  );
   static const REMOVE_UNUSED_CATCH_STACK = FixKind(
     'dart.fix.remove.unusedCatchStack',
     DartFixKindPriority.DEFAULT,
     'Remove unused stack trace variable',
   );
+  static const REMOVE_UNUSED_CATCH_STACK_MULTI = FixKind(
+    'dart.fix.remove.unusedCatchStack.multi',
+    DartFixKindPriority.IN_FILE,
+    'Remove unused stack trace variables in file',
+  );
   static const REMOVE_UNUSED_ELEMENT = FixKind(
     'dart.fix.remove.unusedElement',
     DartFixKindPriority.DEFAULT,
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_catch_clause_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_catch_clause_test.dart
index d18763d..171e2e1 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_catch_clause_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_catch_clause_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -11,10 +12,38 @@
 void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(RemoveUnusedCatchClauseTest);
+    defineReflectiveTests(RemoveUnusedCatchClauseMultiTest);
   });
 }
 
 @reflectiveTest
+class RemoveUnusedCatchClauseMultiTest extends FixProcessorTest {
+  @override
+  FixKind get kind => DartFixKind.REMOVE_UNUSED_CATCH_CLAUSE_MULTI;
+
+  Future<void> test_singleFile() async {
+    await resolveTestCode('''
+main() {
+  try {
+    throw 42;
+  } on int catch (i) {
+  } on Error catch (e) {
+  }
+}
+''');
+    await assertHasFixAllFix(HintCode.UNUSED_CATCH_CLAUSE, '''
+main() {
+  try {
+    throw 42;
+  } on int {
+  } on Error {
+  }
+}
+''');
+  }
+}
+
+@reflectiveTest
 class RemoveUnusedCatchClauseTest extends FixProcessorTest {
   @override
   FixKind get kind => DartFixKind.REMOVE_UNUSED_CATCH_CLAUSE;
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_catch_stack_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_catch_stack_test.dart
index 730f44e..f72b354 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_catch_stack_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_catch_stack_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -11,10 +12,38 @@
 void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(RemoveUnusedCatchStackTest);
+    defineReflectiveTests(RemoveUnusedCatchStackMultiTest);
   });
 }
 
 @reflectiveTest
+class RemoveUnusedCatchStackMultiTest extends FixProcessorTest {
+  @override
+  FixKind get kind => DartFixKind.REMOVE_UNUSED_CATCH_STACK_MULTI;
+
+  Future<void> test_singleFile() async {
+    await resolveTestCode('''
+main() {
+  try {
+    throw 42;
+  } on int catch (i, stack) {
+  } catch (e, stack) {
+  }
+}
+''');
+    await assertHasFixAllFix(HintCode.UNUSED_CATCH_STACK, '''
+main() {
+  try {
+    throw 42;
+  } on int catch (i) {
+  } catch (e) {
+  }
+}
+''');
+  }
+}
+
+@reflectiveTest
 class RemoveUnusedCatchStackTest extends FixProcessorTest {
   @override
   FixKind get kind => DartFixKind.REMOVE_UNUSED_CATCH_STACK;
diff --git a/pkg/analysis_server/tool/bulk_fix/supported_hints.dart b/pkg/analysis_server/tool/bulk_fix/supported_nonlints.dart
similarity index 90%
rename from pkg/analysis_server/tool/bulk_fix/supported_hints.dart
rename to pkg/analysis_server/tool/bulk_fix/supported_nonlints.dart
index ccc3938..e9dcbbc 100644
--- a/pkg/analysis_server/tool/bulk_fix/supported_hints.dart
+++ b/pkg/analysis_server/tool/bulk_fix/supported_nonlints.dart
@@ -13,8 +13,8 @@
 
   print('hints w/ correction producers:\n');
 
-  var hintEntries = FixProcessor.nonLintProducerMap.entries
-      .where((e) => e.key.type == ErrorType.HINT);
+  var hintEntries = FixProcessor.nonLintProducerMap.entries.where((e) =>
+      e.key.type == ErrorType.HINT || e.key.type == ErrorType.STATIC_WARNING);
   for (var hint in hintEntries) {
     var canBeAppliedInBulk = false;
     var missingExplanations = <String>[];
diff --git a/pkg/analyzer/lib/src/summary2/link.dart b/pkg/analyzer/lib/src/summary2/link.dart
index 5665fb5..d605919 100644
--- a/pkg/analyzer/lib/src/summary2/link.dart
+++ b/pkg/analyzer/lib/src/summary2/link.dart
@@ -27,9 +27,8 @@
 /// Note that AST units and tokens of [inputLibraries] will be damaged.
 LinkResult link(
   LinkedElementFactory elementFactory,
-  List<LinkInputLibrary> inputLibraries, [
-  @Deprecated('Not used anymore') bool? withInformative,
-]) {
+  List<LinkInputLibrary> inputLibraries,
+) {
   var linker = Linker(elementFactory);
   linker.link(inputLibraries);
   return LinkResult(
diff --git a/pkg/analyzer/tool/messages/error_code_info.dart b/pkg/analyzer/tool/messages/error_code_info.dart
index 6ad0667..907a564 100644
--- a/pkg/analyzer/tool/messages/error_code_info.dart
+++ b/pkg/analyzer/tool/messages/error_code_info.dart
@@ -111,14 +111,42 @@
 /// two-level map of [ErrorCodeInfo], indexed first by class name and then by
 /// error name.
 Map<String, Map<String, ErrorCodeInfo>> decodeAnalyzerMessagesYaml(
-    Map<Object?, Object?> yaml) {
+    Object? yaml) {
+  Never problem(String message) {
+    throw 'Problem in pkg/analyzer/messages.yaml: $message';
+  }
+
   var result = <String, Map<String, ErrorCodeInfo>>{};
+  if (yaml is! Map<Object?, Object?>) {
+    problem('root node is not a map');
+  }
   for (var classEntry in yaml.entries) {
-    var className = classEntry.key as String;
-    for (var errorEntry
-        in (classEntry.value as Map<Object?, Object?>).entries) {
-      (result[className] ??= {})[errorEntry.key as String] =
-          ErrorCodeInfo.fromYaml(errorEntry.value as Map<Object?, Object?>);
+    var className = classEntry.key;
+    if (className is! String) {
+      problem('non-string class key ${json.encode(className)}');
+    }
+    var classValue = classEntry.value;
+    if (classValue is! Map<Object?, Object?>) {
+      problem('value associated with class key $className is not a map');
+    }
+    for (var errorEntry in classValue.entries) {
+      var errorName = errorEntry.key;
+      if (errorName is! String) {
+        problem('in class $className, non-string error key '
+            '${json.encode(errorName)}');
+      }
+      var errorValue = errorEntry.value;
+      if (errorValue is! Map<Object?, Object?>) {
+        problem('value associated with error $className.$errorName is not a '
+            'map');
+      }
+      try {
+        (result[className] ??= {})[errorName] =
+            ErrorCodeInfo.fromYaml(errorValue);
+      } catch (e) {
+        problem('while processing '
+            '$className.$errorName, $e');
+      }
     }
   }
   return result;
@@ -126,25 +154,39 @@
 
 /// Decodes a YAML object (obtained from `pkg/front_end/messages.yaml`) into a
 /// map from error name to [ErrorCodeInfo].
-Map<String, ErrorCodeInfo> decodeCfeMessagesYaml(Map<Object?, Object?> yaml) {
+Map<String, ErrorCodeInfo> decodeCfeMessagesYaml(Object? yaml) {
+  Never problem(String message) {
+    throw 'Problem in pkg/front_end/messages.yaml: $message';
+  }
+
   var result = <String, ErrorCodeInfo>{};
+  if (yaml is! Map<Object?, Object?>) {
+    problem('root node is not a map');
+  }
   for (var entry in yaml.entries) {
-    result[entry.key as String] =
-        ErrorCodeInfo.fromYaml(entry.value as Map<Object?, Object?>);
+    var errorName = entry.key;
+    if (errorName is! String) {
+      problem('non-string error key ${json.encode(errorName)}');
+    }
+    var errorValue = entry.value;
+    if (errorValue is! Map<Object?, Object?>) {
+      problem('value associated with error $errorName is not a map');
+    }
+    result[errorName] = ErrorCodeInfo.fromYaml(errorValue);
   }
   return result;
 }
 
 /// Loads analyzer messages from the analyzer's `messages.yaml` file.
 Map<String, Map<String, ErrorCodeInfo>> _loadAnalyzerMessages() {
-  Map<dynamic, dynamic> messagesYaml =
+  Object? messagesYaml =
       loadYaml(File(join(analyzerPkgPath, 'messages.yaml')).readAsStringSync());
   return decodeAnalyzerMessagesYaml(messagesYaml);
 }
 
 /// Loads front end messages from the front end's `messages.yaml` file.
 Map<String, ErrorCodeInfo> _loadFrontEndMessages() {
-  Map<dynamic, dynamic> messagesYaml =
+  Object? messagesYaml =
       loadYaml(File(join(frontEndPkgPath, 'messages.yaml')).readAsStringSync());
   return decodeCfeMessagesYaml(messagesYaml);
 }
diff --git a/pkg/dartdev/lib/src/analysis_server.dart b/pkg/dartdev/lib/src/analysis_server.dart
index 0954378..580619b 100644
--- a/pkg/dartdev/lib/src/analysis_server.dart
+++ b/pkg/dartdev/lib/src/analysis_server.dart
@@ -95,7 +95,6 @@
 
     _process = await startDartProcess(sdk, command);
     // This callback hookup can't throw.
-    // ignore: unawaited_futures
     _process.exitCode.whenComplete(() => _process = null);
 
     final Stream<String> errorStream = _process.stderr
@@ -110,7 +109,6 @@
 
     _streamController('server.error').stream.listen(_handleServerError);
 
-    // ignore: unawaited_futures
     _sendCommand('server.setSubscriptions', params: <String, dynamic>{
       'subscriptions': <String>['STATUS'],
     });
@@ -136,7 +134,6 @@
       }
     });
 
-    // ignore: unawaited_futures
     _sendCommand('analysis.setAnalysisRoots', params: <String, dynamic>{
       'included': analysisRootPaths,
       'excluded': <String>[]
diff --git a/pkg/dartdev/lib/src/commands/analyze.dart b/pkg/dartdev/lib/src/commands/analyze.dart
index 96f0fbe..2c8837b 100644
--- a/pkg/dartdev/lib/src/commands/analyze.dart
+++ b/pkg/dartdev/lib/src/commands/analyze.dart
@@ -128,7 +128,6 @@
 
     bool analysisFinished = false;
 
-    // ignore: unawaited_futures
     server.onExit.then((int exitCode) {
       if (!analysisFinished) {
         io.exitCode = exitCode;
diff --git a/pkg/dartdev/lib/src/commands/fix.dart b/pkg/dartdev/lib/src/commands/fix.dart
index b19b433..c81e467 100644
--- a/pkg/dartdev/lib/src/commands/fix.dart
+++ b/pkg/dartdev/lib/src/commands/fix.dart
@@ -100,7 +100,6 @@
     await server.start();
 
     EditBulkFixesResult fixes;
-    //ignore: unawaited_futures
     server.onExit.then((int exitCode) {
       if (fixes == null && exitCode != 0) {
         progress?.cancel();
diff --git a/runtime/vm/app_snapshot.cc b/runtime/vm/app_snapshot.cc
index a27d27c..e25f0bc 100644
--- a/runtime/vm/app_snapshot.cc
+++ b/runtime/vm/app_snapshot.cc
@@ -3844,14 +3844,9 @@
 
     PushFromTo(type);
 
-    if (type->untag()->type_class_id()->IsHeapObject()) {
-      // Type class is still an unresolved class.
-      UNREACHABLE();
-    }
-
-    SmiPtr raw_type_class_id = Smi::RawCast(type->untag()->type_class_id());
+    ASSERT(type->untag()->type_class_id_ != kIllegalCid);
     ClassPtr type_class =
-        s->isolate_group()->class_table()->At(Smi::Value(raw_type_class_id));
+        s->isolate_group()->class_table()->At(type->untag()->type_class_id_);
     s->Push(type_class);
   }
 
@@ -3883,9 +3878,8 @@
   // inserted into the canonical_types set.
   // Keep in sync with Type::Canonicalize.
   virtual bool IsInCanonicalSet(Serializer* s, TypePtr type) {
-    SmiPtr raw_type_class_id = Smi::RawCast(type->untag()->type_class_id());
     ClassPtr type_class =
-        s->isolate_group()->class_table()->At(Smi::Value(raw_type_class_id));
+        s->isolate_group()->class_table()->At(type->untag()->type_class_id_);
     if (type_class->untag()->declaration_type() != type) {
       return true;
     }
@@ -3898,6 +3892,9 @@
   void WriteType(Serializer* s, TypePtr type) {
     AutoTraceObject(type);
     WriteFromTo(type);
+    COMPILE_ASSERT(
+        std::is_unsigned<decltype(UntaggedType::type_class_id_)>::value);
+    s->WriteUnsigned(type->untag()->type_class_id_);
     ASSERT(type->untag()->type_state_ < (1 << UntaggedType::kTypeStateBitSize));
     ASSERT(type->untag()->nullability_ < (1 << kNullabilityBitSize));
     static_assert(UntaggedType::kTypeStateBitSize + kNullabilityBitSize <=
@@ -3934,6 +3931,9 @@
       Deserializer::InitializeHeader(type, kTypeCid, Type::InstanceSize(),
                                      primary && is_canonical());
       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_state_ = combined >> kNullabilityBitSize;
       type->untag()->nullability_ = combined & kNullabilityBitMask;
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index fd3faae..2d58396 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -1498,11 +1498,7 @@
           Map(param->untag()->parameterized_class_id_);
     } else if (obj->IsType()) {
       TypePtr type = Type::RawCast(obj);
-      ObjectPtr id = type->untag()->type_class_id();
-      if (!id->IsHeapObject()) {
-        type->untag()->set_type_class_id(
-            Smi::New(Map(Smi::Value(Smi::RawCast(id)))));
-      }
+      type->untag()->type_class_id_ = Map(type->untag()->type_class_id_);
     } else {
       intptr_t old_cid = obj->GetClassId();
       intptr_t new_cid = Map(old_cid);
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm.cc b/runtime/vm/compiler/asm_intrinsifier_arm.cc
index 8a97dd4..b61046d 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm.cc
@@ -1360,10 +1360,8 @@
   __ b(normal_ir_body, NE);
 
   // Check if types are syntactically equal.
-  __ ldr(R3, FieldAddress(R1, target::Type::type_class_id_offset()));
-  __ SmiUntag(R3);
-  __ ldr(R4, FieldAddress(R2, target::Type::type_class_id_offset()));
-  __ SmiUntag(R4);
+  __ LoadTypeClassId(R3, R1);
+  __ LoadTypeClassId(R4, R2);
   // We are not testing instance cids, but type class cids of Type instances.
   EquivalentClassIds(assembler, normal_ir_body, &equiv_cids_may_be_generic,
                      &equiv_cids, &not_equal, R3, R4, R0,
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm64.cc b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
index 1b2a819..b6796b5 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
@@ -1509,12 +1509,8 @@
   __ b(normal_ir_body, NE);
 
   // Check if types are syntactically equal.
-  __ LoadCompressedSmi(R3,
-                       FieldAddress(R1, target::Type::type_class_id_offset()));
-  __ SmiUntag(R3);
-  __ LoadCompressedSmi(R4,
-                       FieldAddress(R2, target::Type::type_class_id_offset()));
-  __ SmiUntag(R4);
+  __ LoadTypeClassId(R3, R1);
+  __ LoadTypeClassId(R4, R2);
   // We are not testing instance cids, but type class cids of Type instances.
   EquivalentClassIds(assembler, normal_ir_body, &equiv_cids_may_be_generic,
                      &equiv_cids, &not_equal, R3, R4, R0,
diff --git a/runtime/vm/compiler/asm_intrinsifier_ia32.cc b/runtime/vm/compiler/asm_intrinsifier_ia32.cc
index 91a1794..0c58ca7 100644
--- a/runtime/vm/compiler/asm_intrinsifier_ia32.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_ia32.cc
@@ -1475,10 +1475,8 @@
   __ j(NOT_EQUAL, normal_ir_body);
 
   // Check if types are syntactically equal.
-  __ movl(ECX, FieldAddress(EDI, target::Type::type_class_id_offset()));
-  __ SmiUntag(ECX);
-  __ movl(EDX, FieldAddress(EBX, target::Type::type_class_id_offset()));
-  __ SmiUntag(EDX);
+  __ LoadTypeClassId(ECX, EDI);
+  __ LoadTypeClassId(EDX, EBX);
   // We are not testing instance cids, but type class cids of Type instances.
   EquivalentClassIds(assembler, normal_ir_body, &equiv_cids_may_be_generic,
                      &equiv_cids, &not_equal, ECX, EDX, EAX,
diff --git a/runtime/vm/compiler/asm_intrinsifier_x64.cc b/runtime/vm/compiler/asm_intrinsifier_x64.cc
index 0b84166..c4e02a9 100644
--- a/runtime/vm/compiler/asm_intrinsifier_x64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_x64.cc
@@ -1380,12 +1380,8 @@
   __ j(NOT_EQUAL, normal_ir_body);
 
   // Check if types are syntactically equal.
-  __ LoadCompressedSmi(RDI,
-                       FieldAddress(RCX, target::Type::type_class_id_offset()));
-  __ SmiUntag(RDI);
-  __ LoadCompressedSmi(RSI,
-                       FieldAddress(RDX, target::Type::type_class_id_offset()));
-  __ SmiUntag(RSI);
+  __ LoadTypeClassId(RDI, RCX);
+  __ LoadTypeClassId(RSI, RDX);
   // We are not testing instance cids, but type class cids of Type instances.
   EquivalentClassIds(assembler, normal_ir_body, &equiv_cids_may_be_generic,
                      &equiv_cids, &not_equal, RDI, RSI, RAX,
diff --git a/runtime/vm/compiler/assembler/assembler_base.h b/runtime/vm/compiler/assembler/assembler_base.h
index ad8aa79..c3410b4 100644
--- a/runtime/vm/compiler/assembler/assembler_base.h
+++ b/runtime/vm/compiler/assembler/assembler_base.h
@@ -732,6 +732,18 @@
   // can be accessed without checking the class id first.
   virtual void CompareTypeNullabilityWith(Register type, int8_t value) = 0;
 
+  void LoadTypeClassId(Register dst, Register src) {
+#if !defined(TARGET_ARCH_IA32)
+    EnsureHasClassIdInDEBUG(kTypeCid, src, TMP);
+#endif
+    ASSERT(!compiler::target::UntaggedType::kTypeClassIdIsSigned);
+    ASSERT_EQUAL(compiler::target::UntaggedType::kTypeClassIdBitSize,
+                 kBitsPerInt16);
+    LoadFieldFromOffset(dst, src,
+                        compiler::target::Type::type_class_id_offset(),
+                        kUnsignedTwoBytes);
+  }
+
   virtual void EnsureHasClassIdInDEBUG(intptr_t cid,
                                        Register src,
                                        Register scratch,
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index 20f828f..a421fe8 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -2520,8 +2520,15 @@
     const AbstractType& type,
     compiler::Label* is_instance_lbl,
     compiler::Label* is_not_instance_lbl) {
+  ASSERT(!type.IsTopTypeForInstanceOf());
   __ Comment("InlineInstanceof");
-
+  if (type.IsObjectType()) {  // Must be non-nullable.
+    __ CompareObject(TypeTestABI::kInstanceReg, Object::null_object());
+    // All non-null objects are instances of non-nullable Object.
+    __ BranchIf(NOT_EQUAL, is_instance_lbl);
+    __ Jump(is_not_instance_lbl);
+    return SubtypeTestCache::null();  // No need for an STC.
+  }
   if (type.IsFunctionType()) {
     return GenerateFunctionTypeTest(source, type, is_instance_lbl,
                                     is_not_instance_lbl);
@@ -2577,6 +2584,11 @@
     const Class& type_class,
     compiler::Label* is_instance_lbl,
     compiler::Label* is_not_instance_lbl) {
+  // If the type being tested is non-nullable Object, we are in NNBD strong
+  // mode, since top types do not reach here. In this case, testing the
+  // superclass of a null instance yields a wrong result (as the Null class
+  // extends Object).
+  ASSERT(!type_class.IsObjectClass());
   __ Comment("Subtype1TestCacheLookup");
 #if defined(DEBUG)
   compiler::Label ok;
@@ -2584,43 +2596,40 @@
   __ Breakpoint();
   __ Bind(&ok);
 #endif
-  // Check immediate superclass equality. If type_class is Object, then testing
-  // supertype may yield a wrong result for Null in NNBD strong mode (because
-  // Null also extends Object).
-  if (!type_class.IsObjectClass() ||
-      !IsolateGroup::Current()->use_strict_null_safety_checks()) {
-    // We don't use TypeTestABI::kScratchReg for the first scratch register as
-    // it is not defined on IA32. Instead, we use the subtype test cache
-    // register, as it is clobbered by the subtype test cache stub call anyway.
-    const Register kScratch1Reg = TypeTestABI::kSubtypeTestCacheReg;
+  // We don't use TypeTestABI::kScratchReg for the first scratch register as
+  // it is not defined on IA32. Instead, we use the subtype test cache
+  // register, as it is clobbered by the subtype test cache stub call anyway.
+  const Register kScratch1Reg = TypeTestABI::kSubtypeTestCacheReg;
 #if defined(TARGET_ARCH_IA32)
-    // We don't use TypeTestABI::kScratchReg as it is not defined on IA32.
-    // Instead, we pick another TypeTestABI register and push/pop it around
-    // the uses of the second scratch register.
-    const Register kScratch2Reg = TypeTestABI::kDstTypeReg;
-    __ PushRegister(kScratch2Reg);
+  // We don't use TypeTestABI::kScratchReg as it is not defined on IA32.
+  // Instead, we pick another TypeTestABI register and push/pop it around
+  // the uses of the second scratch register.
+  const Register kScratch2Reg = TypeTestABI::kDstTypeReg;
+  __ PushRegister(kScratch2Reg);
 #else
-    // We can use TypeTestABI::kScratchReg for the second scratch register, as
-    // IA32 is handled separately.
-    const Register kScratch2Reg = TypeTestABI::kScratchReg;
+  // We can use TypeTestABI::kScratchReg for the second scratch register, as
+  // IA32 is handled separately.
+  const Register kScratch2Reg = TypeTestABI::kScratchReg;
 #endif
-    static_assert(kScratch1Reg != kScratch2Reg,
-                  "Scratch registers must be distinct");
-    __ LoadClassId(kScratch2Reg, TypeTestABI::kInstanceReg);
-    __ LoadClassById(kScratch1Reg, kScratch2Reg);
+  static_assert(kScratch1Reg != kScratch2Reg,
+                "Scratch registers must be distinct");
+  // Check immediate superclass equality.
+  __ LoadClassId(kScratch2Reg, TypeTestABI::kInstanceReg);
+  __ LoadClassById(kScratch1Reg, kScratch2Reg);
 #if defined(TARGET_ARCH_IA32)
-    // kScratch2 is no longer used, so restore it.
-    __ PopRegister(kScratch2Reg);
+  // kScratch2 is no longer used, so restore it.
+  __ PopRegister(kScratch2Reg);
 #endif
-    __ LoadCompressedFieldFromOffset(
-        kScratch1Reg, kScratch1Reg,
-        compiler::target::Class::super_type_offset());
-    __ LoadCompressedFieldFromOffset(
-        kScratch1Reg, kScratch1Reg,
-        compiler::target::Type::type_class_id_offset());
-    __ CompareImmediate(kScratch1Reg, Smi::RawValue(type_class.id()));
-    __ BranchIf(EQUAL, is_instance_lbl);
-  }
+  __ LoadCompressedFieldFromOffset(
+      kScratch1Reg, kScratch1Reg, compiler::target::Class::super_type_offset());
+  // Check for a null super type. Instances whose class has a null super type
+  // can only be an instance of top types or of non-nullable Object, but this
+  // method is not called for those types, so the object cannot be an instance.
+  __ CompareObject(kScratch1Reg, Object::null_object());
+  __ BranchIf(EQUAL, is_not_instance_lbl);
+  __ LoadTypeClassId(kScratch1Reg, kScratch1Reg);
+  __ CompareImmediate(kScratch1Reg, type_class.id());
+  __ BranchIf(EQUAL, is_instance_lbl);
 
   return GenerateCallSubtypeTestStub(kTestTypeOneArg, is_instance_lbl,
                                      is_not_instance_lbl);
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc
index 5bc2fff..3210c35 100644
--- a/runtime/vm/compiler/runtime_api.cc
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -369,6 +369,12 @@
 const word UntaggedAbstractType::kTypeStateFinalizedInstantiated =
     dart::UntaggedAbstractType::kFinalizedInstantiated;
 
+const bool UntaggedType::kTypeClassIdIsSigned =
+    std::is_signed<decltype(dart::UntaggedType::type_class_id_)>::value;
+
+const word UntaggedType::kTypeClassIdBitSize =
+    sizeof(dart::UntaggedType::type_class_id_) * kBitsPerByte;
+
 const word UntaggedObject::kBarrierOverlapShift =
     dart::UntaggedObject::kBarrierOverlapShift;
 
diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h
index 85c8181..5ce613d 100644
--- a/runtime/vm/compiler/runtime_api.h
+++ b/runtime/vm/compiler/runtime_api.h
@@ -451,6 +451,12 @@
   static const word kTypeStateFinalizedInstantiated;
 };
 
+class UntaggedType : public AllStatic {
+ public:
+  static const bool kTypeClassIdIsSigned;
+  static const word kTypeClassIdBitSize;
+};
+
 class Object : public AllStatic {
  public:
   // Offset of the tags word.
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index 8a16d29..494a811 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -419,11 +419,11 @@
     Thread_callback_stack_return_offset = 780;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
-static constexpr dart::compiler::target::word Type_arguments_offset = 16;
-static constexpr dart::compiler::target::word Type_hash_offset = 20;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 12;
-static constexpr dart::compiler::target::word Type_type_state_offset = 24;
-static constexpr dart::compiler::target::word Type_nullability_offset = 25;
+static constexpr dart::compiler::target::word Type_arguments_offset = 12;
+static constexpr dart::compiler::target::word Type_hash_offset = 16;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 20;
+static constexpr dart::compiler::target::word Type_type_state_offset = 22;
+static constexpr dart::compiler::target::word Type_nullability_offset = 23;
 static constexpr dart::compiler::target::word FunctionType_hash_offset = 28;
 static constexpr dart::compiler::target::word
     FunctionType_named_parameter_names_offset = 24;
@@ -549,7 +549,7 @@
 static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 20;
 static constexpr dart::compiler::target::word
     TransferableTypedData_InstanceSize = 4;
-static constexpr dart::compiler::target::word Type_InstanceSize = 28;
+static constexpr dart::compiler::target::word Type_InstanceSize = 24;
 static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 28;
 static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 20;
 static constexpr dart::compiler::target::word TypeRef_InstanceSize = 16;
@@ -977,11 +977,11 @@
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
-static constexpr dart::compiler::target::word Type_arguments_offset = 32;
-static constexpr dart::compiler::target::word Type_hash_offset = 40;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 24;
-static constexpr dart::compiler::target::word Type_type_state_offset = 48;
-static constexpr dart::compiler::target::word Type_nullability_offset = 49;
+static constexpr dart::compiler::target::word Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word Type_hash_offset = 32;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 40;
+static constexpr dart::compiler::target::word Type_type_state_offset = 42;
+static constexpr dart::compiler::target::word Type_nullability_offset = 43;
 static constexpr dart::compiler::target::word FunctionType_hash_offset = 56;
 static constexpr dart::compiler::target::word
     FunctionType_named_parameter_names_offset = 48;
@@ -1109,7 +1109,7 @@
 static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 32;
 static constexpr dart::compiler::target::word
     TransferableTypedData_InstanceSize = 8;
-static constexpr dart::compiler::target::word Type_InstanceSize = 56;
+static constexpr dart::compiler::target::word Type_InstanceSize = 48;
 static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 48;
 static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 40;
 static constexpr dart::compiler::target::word TypeRef_InstanceSize = 32;
@@ -1528,11 +1528,11 @@
     Thread_callback_stack_return_offset = 748;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
-static constexpr dart::compiler::target::word Type_arguments_offset = 16;
-static constexpr dart::compiler::target::word Type_hash_offset = 20;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 12;
-static constexpr dart::compiler::target::word Type_type_state_offset = 24;
-static constexpr dart::compiler::target::word Type_nullability_offset = 25;
+static constexpr dart::compiler::target::word Type_arguments_offset = 12;
+static constexpr dart::compiler::target::word Type_hash_offset = 16;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 20;
+static constexpr dart::compiler::target::word Type_type_state_offset = 22;
+static constexpr dart::compiler::target::word Type_nullability_offset = 23;
 static constexpr dart::compiler::target::word FunctionType_hash_offset = 28;
 static constexpr dart::compiler::target::word
     FunctionType_named_parameter_names_offset = 24;
@@ -1655,7 +1655,7 @@
 static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 20;
 static constexpr dart::compiler::target::word
     TransferableTypedData_InstanceSize = 4;
-static constexpr dart::compiler::target::word Type_InstanceSize = 28;
+static constexpr dart::compiler::target::word Type_InstanceSize = 24;
 static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 28;
 static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 20;
 static constexpr dart::compiler::target::word TypeRef_InstanceSize = 16;
@@ -2083,11 +2083,11 @@
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
-static constexpr dart::compiler::target::word Type_arguments_offset = 32;
-static constexpr dart::compiler::target::word Type_hash_offset = 40;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 24;
-static constexpr dart::compiler::target::word Type_type_state_offset = 48;
-static constexpr dart::compiler::target::word Type_nullability_offset = 49;
+static constexpr dart::compiler::target::word Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word Type_hash_offset = 32;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 40;
+static constexpr dart::compiler::target::word Type_type_state_offset = 42;
+static constexpr dart::compiler::target::word Type_nullability_offset = 43;
 static constexpr dart::compiler::target::word FunctionType_hash_offset = 56;
 static constexpr dart::compiler::target::word
     FunctionType_named_parameter_names_offset = 48;
@@ -2216,7 +2216,7 @@
 static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 32;
 static constexpr dart::compiler::target::word
     TransferableTypedData_InstanceSize = 8;
-static constexpr dart::compiler::target::word Type_InstanceSize = 56;
+static constexpr dart::compiler::target::word Type_InstanceSize = 48;
 static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 48;
 static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 40;
 static constexpr dart::compiler::target::word TypeRef_InstanceSize = 32;
@@ -2641,11 +2641,11 @@
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
-static constexpr dart::compiler::target::word Type_arguments_offset = 28;
-static constexpr dart::compiler::target::word Type_hash_offset = 32;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 24;
-static constexpr dart::compiler::target::word Type_type_state_offset = 36;
-static constexpr dart::compiler::target::word Type_nullability_offset = 37;
+static constexpr dart::compiler::target::word Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word Type_hash_offset = 28;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 32;
+static constexpr dart::compiler::target::word Type_type_state_offset = 34;
+static constexpr dart::compiler::target::word Type_nullability_offset = 35;
 static constexpr dart::compiler::target::word FunctionType_hash_offset = 40;
 static constexpr dart::compiler::target::word
     FunctionType_named_parameter_names_offset = 36;
@@ -3198,11 +3198,11 @@
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
-static constexpr dart::compiler::target::word Type_arguments_offset = 28;
-static constexpr dart::compiler::target::word Type_hash_offset = 32;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 24;
-static constexpr dart::compiler::target::word Type_type_state_offset = 36;
-static constexpr dart::compiler::target::word Type_nullability_offset = 37;
+static constexpr dart::compiler::target::word Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word Type_hash_offset = 28;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 32;
+static constexpr dart::compiler::target::word Type_type_state_offset = 34;
+static constexpr dart::compiler::target::word Type_nullability_offset = 35;
 static constexpr dart::compiler::target::word FunctionType_hash_offset = 40;
 static constexpr dart::compiler::target::word
     FunctionType_named_parameter_names_offset = 36;
@@ -3746,11 +3746,11 @@
     Thread_callback_stack_return_offset = 780;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
-static constexpr dart::compiler::target::word Type_arguments_offset = 16;
-static constexpr dart::compiler::target::word Type_hash_offset = 20;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 12;
-static constexpr dart::compiler::target::word Type_type_state_offset = 24;
-static constexpr dart::compiler::target::word Type_nullability_offset = 25;
+static constexpr dart::compiler::target::word Type_arguments_offset = 12;
+static constexpr dart::compiler::target::word Type_hash_offset = 16;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 20;
+static constexpr dart::compiler::target::word Type_type_state_offset = 22;
+static constexpr dart::compiler::target::word Type_nullability_offset = 23;
 static constexpr dart::compiler::target::word FunctionType_hash_offset = 28;
 static constexpr dart::compiler::target::word
     FunctionType_named_parameter_names_offset = 24;
@@ -3876,7 +3876,7 @@
 static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 20;
 static constexpr dart::compiler::target::word
     TransferableTypedData_InstanceSize = 4;
-static constexpr dart::compiler::target::word Type_InstanceSize = 28;
+static constexpr dart::compiler::target::word Type_InstanceSize = 24;
 static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 28;
 static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 20;
 static constexpr dart::compiler::target::word TypeRef_InstanceSize = 16;
@@ -4298,11 +4298,11 @@
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
-static constexpr dart::compiler::target::word Type_arguments_offset = 32;
-static constexpr dart::compiler::target::word Type_hash_offset = 40;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 24;
-static constexpr dart::compiler::target::word Type_type_state_offset = 48;
-static constexpr dart::compiler::target::word Type_nullability_offset = 49;
+static constexpr dart::compiler::target::word Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word Type_hash_offset = 32;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 40;
+static constexpr dart::compiler::target::word Type_type_state_offset = 42;
+static constexpr dart::compiler::target::word Type_nullability_offset = 43;
 static constexpr dart::compiler::target::word FunctionType_hash_offset = 56;
 static constexpr dart::compiler::target::word
     FunctionType_named_parameter_names_offset = 48;
@@ -4430,7 +4430,7 @@
 static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 32;
 static constexpr dart::compiler::target::word
     TransferableTypedData_InstanceSize = 8;
-static constexpr dart::compiler::target::word Type_InstanceSize = 56;
+static constexpr dart::compiler::target::word Type_InstanceSize = 48;
 static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 48;
 static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 40;
 static constexpr dart::compiler::target::word TypeRef_InstanceSize = 32;
@@ -4843,11 +4843,11 @@
     Thread_callback_stack_return_offset = 748;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
-static constexpr dart::compiler::target::word Type_arguments_offset = 16;
-static constexpr dart::compiler::target::word Type_hash_offset = 20;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 12;
-static constexpr dart::compiler::target::word Type_type_state_offset = 24;
-static constexpr dart::compiler::target::word Type_nullability_offset = 25;
+static constexpr dart::compiler::target::word Type_arguments_offset = 12;
+static constexpr dart::compiler::target::word Type_hash_offset = 16;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 20;
+static constexpr dart::compiler::target::word Type_type_state_offset = 22;
+static constexpr dart::compiler::target::word Type_nullability_offset = 23;
 static constexpr dart::compiler::target::word FunctionType_hash_offset = 28;
 static constexpr dart::compiler::target::word
     FunctionType_named_parameter_names_offset = 24;
@@ -4970,7 +4970,7 @@
 static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 20;
 static constexpr dart::compiler::target::word
     TransferableTypedData_InstanceSize = 4;
-static constexpr dart::compiler::target::word Type_InstanceSize = 28;
+static constexpr dart::compiler::target::word Type_InstanceSize = 24;
 static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 28;
 static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 20;
 static constexpr dart::compiler::target::word TypeRef_InstanceSize = 16;
@@ -5392,11 +5392,11 @@
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
-static constexpr dart::compiler::target::word Type_arguments_offset = 32;
-static constexpr dart::compiler::target::word Type_hash_offset = 40;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 24;
-static constexpr dart::compiler::target::word Type_type_state_offset = 48;
-static constexpr dart::compiler::target::word Type_nullability_offset = 49;
+static constexpr dart::compiler::target::word Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word Type_hash_offset = 32;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 40;
+static constexpr dart::compiler::target::word Type_type_state_offset = 42;
+static constexpr dart::compiler::target::word Type_nullability_offset = 43;
 static constexpr dart::compiler::target::word FunctionType_hash_offset = 56;
 static constexpr dart::compiler::target::word
     FunctionType_named_parameter_names_offset = 48;
@@ -5525,7 +5525,7 @@
 static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 32;
 static constexpr dart::compiler::target::word
     TransferableTypedData_InstanceSize = 8;
-static constexpr dart::compiler::target::word Type_InstanceSize = 56;
+static constexpr dart::compiler::target::word Type_InstanceSize = 48;
 static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 48;
 static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 40;
 static constexpr dart::compiler::target::word TypeRef_InstanceSize = 32;
@@ -5944,11 +5944,11 @@
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
-static constexpr dart::compiler::target::word Type_arguments_offset = 28;
-static constexpr dart::compiler::target::word Type_hash_offset = 32;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 24;
-static constexpr dart::compiler::target::word Type_type_state_offset = 36;
-static constexpr dart::compiler::target::word Type_nullability_offset = 37;
+static constexpr dart::compiler::target::word Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word Type_hash_offset = 28;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 32;
+static constexpr dart::compiler::target::word Type_type_state_offset = 34;
+static constexpr dart::compiler::target::word Type_nullability_offset = 35;
 static constexpr dart::compiler::target::word FunctionType_hash_offset = 40;
 static constexpr dart::compiler::target::word
     FunctionType_named_parameter_names_offset = 36;
@@ -6495,11 +6495,11 @@
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
-static constexpr dart::compiler::target::word Type_arguments_offset = 28;
-static constexpr dart::compiler::target::word Type_hash_offset = 32;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 24;
-static constexpr dart::compiler::target::word Type_type_state_offset = 36;
-static constexpr dart::compiler::target::word Type_nullability_offset = 37;
+static constexpr dart::compiler::target::word Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word Type_hash_offset = 28;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 32;
+static constexpr dart::compiler::target::word Type_type_state_offset = 34;
+static constexpr dart::compiler::target::word Type_nullability_offset = 35;
 static constexpr dart::compiler::target::word FunctionType_hash_offset = 40;
 static constexpr dart::compiler::target::word
     FunctionType_named_parameter_names_offset = 36;
@@ -7092,12 +7092,12 @@
     AOT_TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
     12;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 16;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 20;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 12;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 16;
 static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
-    12;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 24;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 25;
+    20;
+static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 22;
+static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 23;
 static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 28;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_named_parameter_names_offset = 24;
@@ -7242,7 +7242,7 @@
 static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 20;
 static constexpr dart::compiler::target::word
     AOT_TransferableTypedData_InstanceSize = 4;
-static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 28;
+static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
     28;
 static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
@@ -7710,12 +7710,12 @@
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
     16;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 32;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 40;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 32;
 static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
-    24;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 48;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 49;
+    40;
+static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 42;
+static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 43;
 static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 56;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_named_parameter_names_offset = 48;
@@ -7862,7 +7862,7 @@
 static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 32;
 static constexpr dart::compiler::target::word
     AOT_TransferableTypedData_InstanceSize = 8;
-static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 56;
+static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 48;
 static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
     48;
 static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
@@ -8333,12 +8333,12 @@
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
     16;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 32;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 40;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 32;
 static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
-    24;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 48;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 49;
+    40;
+static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 42;
+static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 43;
 static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 56;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_named_parameter_names_offset = 48;
@@ -8486,7 +8486,7 @@
 static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 32;
 static constexpr dart::compiler::target::word
     AOT_TransferableTypedData_InstanceSize = 8;
-static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 56;
+static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 48;
 static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
     48;
 static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
@@ -8953,12 +8953,12 @@
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
     16;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 28;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 32;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 28;
 static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
-    24;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 36;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 37;
+    32;
+static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 34;
+static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 35;
 static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_named_parameter_names_offset = 36;
@@ -9572,12 +9572,12 @@
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
     16;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 28;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 32;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 28;
 static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
-    24;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 36;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 37;
+    32;
+static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 34;
+static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 35;
 static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_named_parameter_names_offset = 36;
@@ -10186,12 +10186,12 @@
     AOT_TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
     12;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 16;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 20;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 12;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 16;
 static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
-    12;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 24;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 25;
+    20;
+static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 22;
+static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 23;
 static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 28;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_named_parameter_names_offset = 24;
@@ -10336,7 +10336,7 @@
 static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 20;
 static constexpr dart::compiler::target::word
     AOT_TransferableTypedData_InstanceSize = 4;
-static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 28;
+static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
     28;
 static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
@@ -10797,12 +10797,12 @@
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
     16;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 32;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 40;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 32;
 static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
-    24;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 48;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 49;
+    40;
+static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 42;
+static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 43;
 static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 56;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_named_parameter_names_offset = 48;
@@ -10949,7 +10949,7 @@
 static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 32;
 static constexpr dart::compiler::target::word
     AOT_TransferableTypedData_InstanceSize = 8;
-static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 56;
+static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 48;
 static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
     48;
 static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
@@ -11413,12 +11413,12 @@
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
     16;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 32;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 40;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 32;
 static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
-    24;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 48;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 49;
+    40;
+static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 42;
+static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 43;
 static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 56;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_named_parameter_names_offset = 48;
@@ -11566,7 +11566,7 @@
 static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 32;
 static constexpr dart::compiler::target::word
     AOT_TransferableTypedData_InstanceSize = 8;
-static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 56;
+static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 48;
 static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
     48;
 static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
@@ -12026,12 +12026,12 @@
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
     16;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 28;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 32;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 28;
 static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
-    24;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 36;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 37;
+    32;
+static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 34;
+static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 35;
 static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_named_parameter_names_offset = 36;
@@ -12638,12 +12638,12 @@
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
     16;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 28;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 32;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 28;
 static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
-    24;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 36;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 37;
+    32;
+static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 34;
+static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 35;
 static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_named_parameter_names_offset = 36;
diff --git a/runtime/vm/compiler/stub_code_compiler.cc b/runtime/vm/compiler/stub_code_compiler.cc
index c340571..210001c 100644
--- a/runtime/vm/compiler/stub_code_compiler.cc
+++ b/runtime/vm/compiler/stub_code_compiler.cc
@@ -322,11 +322,7 @@
   // instantiation may result in a top type.
   // Function types cannot be top types.
   __ BranchIf(NOT_EQUAL, &done);
-  __ LoadCompressedField(
-      scratch2_reg,
-      compiler::FieldAddress(scratch1_reg,
-                             compiler::target::Type::type_class_id_offset()));
-  __ SmiUntag(scratch2_reg);
+  __ LoadTypeClassId(scratch2_reg, scratch1_reg);
   __ CompareImmediate(scratch2_reg, kDynamicCid);
   __ BranchIf(EQUAL, &is_top_type, compiler::Assembler::kNearJump);
   __ CompareImmediate(scratch2_reg, kVoidCid);
@@ -443,11 +439,7 @@
     // FutureOr is a special case because it may have the non-nullable bit set,
     // but FutureOr<T> functions as the union of T and Future<T>, so it must be
     // unwrapped to see if T is nullable.
-    __ LoadCompressedField(
-        kScratchReg,
-        compiler::FieldAddress(kCurrentTypeReg,
-                               compiler::target::Type::type_class_id_offset()));
-    __ SmiUntag(kScratchReg);
+    __ LoadTypeClassId(kScratchReg, kCurrentTypeReg);
     __ CompareImmediate(kScratchReg, kFutureOrCid);
     __ BranchIf(NOT_EQUAL, &done);
     __ LoadCompressedField(
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index aeca374..cf8f107 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -20690,7 +20690,7 @@
 }
 
 classid_t Type::type_class_id() const {
-  return Smi::Value(untag()->type_class_id());
+  return untag()->type_class_id_;
 }
 
 ClassPtr Type::type_class() const {
@@ -21261,16 +21261,7 @@
 
 void Type::set_type_class(const Class& value) const {
   ASSERT(!value.IsNull());
-  const intptr_t id = value.id();
-  // We should never need a Type object for a top-level class.
-  ASSERT(!ClassTable::IsTopLevelCid(id));
-  ASSERT(id == kIllegalCid || !IsInternalOnlyClassId(id));
-  // We must allow Types with kIllegalCid type class ids, because the class
-  // used for evaluating expressions inside a instance method call context
-  // from the debugger is not registered (and thus has kIllegalCid as an id).
-  // Thus, we check id != kIllegalCid only if IsType(), not if and only if.
-  ASSERT(id == kIllegalCid || IsType());
-  untag()->set_type_class_id(Smi::New(id));
+  set_type_class_id(value.id());
 }
 
 void Type::set_arguments(const TypeArguments& value) const {
@@ -21302,6 +21293,19 @@
   return result.ptr();
 }
 
+void Type::set_type_class_id(intptr_t id) const {
+  COMPILE_ASSERT(
+      std::is_unsigned<decltype(UntaggedType::type_class_id_)>::value);
+  ASSERT(Utils::IsUint(sizeof(untag()->type_class_id_) * kBitsPerByte, id));
+  // We should never need a Type object for a top-level class.
+  ASSERT(!ClassTable::IsTopLevelCid(id));
+  // We must allow Types with kIllegalCid type class ids, because the class
+  // used for evaluating expressions inside a instance method call context
+  // from the debugger is not registered (and thus has kIllegalCid as an id).
+  ASSERT(id == kIllegalCid || !IsInternalOnlyClassId(id));
+  StoreNonPointer(&untag()->type_class_id_, id);
+}
+
 void Type::set_type_state(uint8_t state) const {
   ASSERT(state <= UntaggedType::kFinalizedUninstantiated);
   StoreNonPointer(&untag()->type_state_, state);
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 2ef9d1d..ad0d7cd 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -8417,6 +8417,10 @@
  private:
   void SetHash(intptr_t value) const;
 
+  // Takes an intptr_t since the cids of some classes are larger than will fit
+  // in ClassIdTagType. This allows us to guard against that case, instead of
+  // silently truncating the cid.
+  void set_type_class_id(intptr_t id) const;
   void set_type_state(uint8_t state) const;
   void set_nullability(Nullability value) const {
     ASSERT(!IsCanonical());
diff --git a/runtime/vm/os_thread.h b/runtime/vm/os_thread.h
index b1019e8..1f6a0e3 100644
--- a/runtime/vm/os_thread.h
+++ b/runtime/vm/os_thread.h
@@ -305,8 +305,9 @@
 
   friend class IsolateGroup;  // to access set_thread(Thread*).
   friend class OSThreadIterator;
-  friend class ThreadInterrupterWin;
   friend class ThreadInterrupterFuchsia;
+  friend class ThreadInterrupterMacOS;
+  friend class ThreadInterrupterWin;
   friend class ThreadPool;  // to access owning_thread_pool_worker_
 };
 
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index ae7d7a9..986cb2d 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -2520,15 +2520,16 @@
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(Type);
 
-  COMPRESSED_POINTER_FIELD(SmiPtr, type_class_id)
   COMPRESSED_POINTER_FIELD(TypeArgumentsPtr, arguments)
   COMPRESSED_POINTER_FIELD(SmiPtr, hash)
   VISIT_TO(hash)
+  ClassIdTagType type_class_id_;
   uint8_t type_state_;
   uint8_t nullability_;
 
   CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 
+  friend class compiler::target::UntaggedType;
   friend class CidRewriteVisitor;
   friend class UntaggedTypeArguments;
 };
diff --git a/runtime/vm/signal_handler_macos.cc b/runtime/vm/signal_handler_macos.cc
index 70e5319..0e0c591 100644
--- a/runtime/vm/signal_handler_macos.cc
+++ b/runtime/vm/signal_handler_macos.cc
@@ -91,24 +91,11 @@
 }
 
 void SignalHandler::Install(SignalAction action) {
-  struct sigaction act = {};
-  act.sa_handler = NULL;
-  act.sa_sigaction = action;
-  sigemptyset(&act.sa_mask);
-  act.sa_flags = SA_RESTART | SA_SIGINFO;
-  int r = sigaction(SIGPROF, &act, NULL);
-  ASSERT(r == 0);
+  // Nothing to do on MacOS.
 }
 
 void SignalHandler::Remove() {
-  // Ignore future SIGPROF signals because by default SIGPROF will terminate
-  // the process and we may have some signals in flight.
-  struct sigaction act = {};
-  act.sa_handler = SIG_IGN;
-  sigemptyset(&act.sa_mask);
-  act.sa_flags = 0;
-  int r = sigaction(SIGPROF, &act, NULL);
-  ASSERT(r == 0);
+  // Nothing to do on MacOS.
 }
 
 }  // namespace dart
diff --git a/runtime/vm/thread_interrupter.cc b/runtime/vm/thread_interrupter.cc
index be990ab..978b428 100644
--- a/runtime/vm/thread_interrupter.cc
+++ b/runtime/vm/thread_interrupter.cc
@@ -66,15 +66,6 @@
 
 void ThreadInterrupter::Startup() {
   ASSERT(initialized_);
-  if (IsDebuggerAttached()) {
-    MonitorLocker shutdown_ml(monitor_);
-    shutdown_ = true;
-    if (FLAG_trace_thread_interrupter) {
-      OS::PrintErr(
-          "ThreadInterrupter disabled because a debugger is attached.\n");
-    }
-    return;
-  }
   if (FLAG_trace_thread_interrupter) {
     OS::PrintErr("ThreadInterrupter starting up.\n");
   }
diff --git a/runtime/vm/thread_interrupter.h b/runtime/vm/thread_interrupter.h
index c5d770e..8921ebe 100644
--- a/runtime/vm/thread_interrupter.h
+++ b/runtime/vm/thread_interrupter.h
@@ -102,8 +102,6 @@
   static std::atomic<intptr_t> sample_buffer_lock_;
   static std::atomic<intptr_t> sample_buffer_waiters_;
 
-  static bool IsDebuggerAttached();
-
   static bool InDeepSleep() {
     return current_wait_time_ == Monitor::kNoTimeout;
   }
diff --git a/runtime/vm/thread_interrupter_android.cc b/runtime/vm/thread_interrupter_android.cc
index dbdd331..2f8ed98 100644
--- a/runtime/vm/thread_interrupter_android.cc
+++ b/runtime/vm/thread_interrupter_android.cc
@@ -61,10 +61,6 @@
 #endif
 }  // namespace
 
-bool ThreadInterrupter::IsDebuggerAttached() {
-  return false;
-}
-
 void ThreadInterrupter::InterruptThread(OSThread* thread) {
   if (FLAG_trace_thread_interrupter) {
     OS::PrintErr("ThreadInterrupter interrupting %p\n",
diff --git a/runtime/vm/thread_interrupter_fuchsia.cc b/runtime/vm/thread_interrupter_fuchsia.cc
index b295569..235bbed 100644
--- a/runtime/vm/thread_interrupter_fuchsia.cc
+++ b/runtime/vm/thread_interrupter_fuchsia.cc
@@ -227,10 +227,6 @@
   }
 };
 
-bool ThreadInterrupter::IsDebuggerAttached() {
-  return false;
-}
-
 void ThreadInterrupter::InterruptThread(OSThread* thread) {
   if (FLAG_trace_thread_interrupter) {
     OS::PrintErr("ThreadInterrupter suspending %p\n",
diff --git a/runtime/vm/thread_interrupter_linux.cc b/runtime/vm/thread_interrupter_linux.cc
index ee623db..5d7661d 100644
--- a/runtime/vm/thread_interrupter_linux.cc
+++ b/runtime/vm/thread_interrupter_linux.cc
@@ -48,10 +48,6 @@
   }
 };
 
-bool ThreadInterrupter::IsDebuggerAttached() {
-  return false;
-}
-
 void ThreadInterrupter::InterruptThread(OSThread* thread) {
   if (FLAG_trace_thread_interrupter) {
     OS::PrintErr("ThreadInterrupter interrupting %p\n",
diff --git a/runtime/vm/thread_interrupter_macos.cc b/runtime/vm/thread_interrupter_macos.cc
index ba9ce5a..9676b53 100644
--- a/runtime/vm/thread_interrupter_macos.cc
+++ b/runtime/vm/thread_interrupter_macos.cc
@@ -5,12 +5,15 @@
 #include "platform/globals.h"
 #if defined(DART_HOST_OS_MACOS)
 
-#include <assert.h>      // NOLINT
-#include <errno.h>       // NOLINT
-#include <stdbool.h>     // NOLINT
-#include <sys/sysctl.h>  // NOLINT
-#include <sys/types.h>   // NOLINT
-#include <unistd.h>      // NOLINT
+#include <assert.h>            // NOLINT
+#include <errno.h>             // NOLINT
+#include <mach/kern_return.h>  // NOLINT
+#include <mach/mach.h>         // NOLINT
+#include <mach/thread_act.h>   // NOLINT
+#include <stdbool.h>           // NOLINT
+#include <sys/sysctl.h>        // NOLINT
+#include <sys/types.h>         // NOLINT
+#include <unistd.h>            // NOLINT
 
 #include "vm/flags.h"
 #include "vm/os.h"
@@ -24,70 +27,110 @@
 
 DECLARE_FLAG(bool, trace_thread_interrupter);
 
-// Returns true if the current process is being debugged (either
-// running under the debugger or has a debugger attached post facto).
-// Code from https://developer.apple.com/library/content/qa/qa1361/_index.html
-bool ThreadInterrupter::IsDebuggerAttached() {
-  struct kinfo_proc info;
-  // Initialize the flags so that, if sysctl fails for some bizarre
-  // reason, we get a predictable result.
-  info.kp_proc.p_flag = 0;
-  // Initialize mib, which tells sysctl the info we want, in this case
-  // we're looking for information about a specific process ID.
-  int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()};
-  size_t size = sizeof(info);
+#if defined(HOST_ARCH_X64)
+#define THREAD_STATE_FLAVOR x86_THREAD_STATE64
+#define THREAD_STATE_FLAVOR_SIZE x86_THREAD_STATE64_COUNT
+typedef x86_thread_state64_t thread_state_flavor_t;
+#elif defined(HOST_ARCH_ARM64)
+#define THREAD_STATE_FLAVOR ARM_THREAD_STATE64
+#define THREAD_STATE_FLAVOR_SIZE ARM_THREAD_STATE64_COUNT
+typedef arm_thread_state64_t thread_state_flavor_t;
+#elif defined(HOST_ARCH_ARM)
+#define THREAD_STATE_FLAVOR ARM_THREAD_STATE32
+#define THREAD_STATE_FLAVOR_SIZE ARM_THREAD_STATE32_COUNT
+typedef arm_thread_state32_t thread_state_flavor_t;
+#else
+#error "Unsupported architecture."
+#endif  // HOST_ARCH_...
 
-  // Call sysctl.
-  size = sizeof(info);
-  int junk = sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0);
-  ASSERT(junk == 0);
-  // We're being debugged if the P_TRACED flag is set.
-  return ((info.kp_proc.p_flag & P_TRACED) != 0);
-}
-
-class ThreadInterrupterMacOS : public AllStatic {
+class ThreadInterrupterMacOS {
  public:
-  static void ThreadInterruptSignalHandler(int signal,
-                                           siginfo_t* info,
-                                           void* context_) {
-    if (signal != SIGPROF) {
-      return;
-    }
-    Thread* thread = Thread::Current();
-    if (thread == NULL) {
-      return;
-    }
-    ThreadInterrupter::SampleBufferWriterScope scope;
-    if (!scope.CanSample()) {
-      return;
-    }
-    // Extract thread state.
-    ucontext_t* context = reinterpret_cast<ucontext_t*>(context_);
-    mcontext_t mcontext = context->uc_mcontext;
-    InterruptedThreadState its;
-    its.pc = SignalHandler::GetProgramCounter(mcontext);
-    its.fp = SignalHandler::GetFramePointer(mcontext);
-    its.csp = SignalHandler::GetCStackPointer(mcontext);
-    its.dsp = SignalHandler::GetDartStackPointer(mcontext);
-    its.lr = SignalHandler::GetLinkRegister(mcontext);
-    Profiler::SampleThread(thread, its);
+  explicit ThreadInterrupterMacOS(OSThread* os_thread) : os_thread_(os_thread) {
+    ASSERT(os_thread != nullptr);
+    mach_thread_ = pthread_mach_thread_np(os_thread->id());
+    ASSERT(reinterpret_cast<void*>(mach_thread_) != nullptr);
+    res = thread_suspend(mach_thread_);
   }
+
+  void CollectSample() {
+    if (res != KERN_SUCCESS) {
+      return;
+    }
+    auto count = static_cast<mach_msg_type_number_t>(THREAD_STATE_FLAVOR_SIZE);
+    thread_state_flavor_t state;
+    kern_return_t res =
+        thread_get_state(mach_thread_, THREAD_STATE_FLAVOR,
+                         reinterpret_cast<thread_state_t>(&state), &count);
+    ASSERT(res == KERN_SUCCESS);
+    Thread* thread = static_cast<Thread*>(os_thread_->thread());
+    if (thread == nullptr) {
+      return;
+    }
+    Profiler::SampleThread(thread, ProcessState(state));
+  }
+
+  ~ThreadInterrupterMacOS() {
+    if (res != KERN_SUCCESS) {
+      return;
+    }
+    res = thread_resume(mach_thread_);
+    ASSERT(res == KERN_SUCCESS);
+  }
+
+ private:
+  static InterruptedThreadState ProcessState(thread_state_flavor_t state) {
+    InterruptedThreadState its;
+#if defined(HOST_ARCH_X64)
+    its.pc = state.__rip;
+    its.fp = state.__rbp;
+    its.csp = state.__rsp;
+    its.dsp = state.__rsp;
+    its.lr = 0;
+#elif defined(HOST_ARCH_ARM64)
+    its.pc = state.__pc;
+    its.fp = state.__fp;
+    its.csp = state.__sp;
+    its.dsp = state.__sp;
+    its.lr = state.__lr;
+#elif defined(HOST_ARCH_ARM)
+    its.pc = state.__pc;
+    its.fp = state.__r[7];
+    its.csp = state.__sp;
+    its.dsp = state.__sp;
+    its.lr = state.__lr;
+#endif  // HOST_ARCH_...
+
+#if defined(TARGET_ARCH_ARM64) && !defined(USING_SIMULATOR)
+    its.dsp = state.__x[SPREG];
+#endif
+    return its;
+  }
+
+  kern_return_t res;
+  OSThread* os_thread_;
+  mach_port_t mach_thread_;
 };
 
-void ThreadInterrupter::InterruptThread(OSThread* thread) {
+void ThreadInterrupter::InterruptThread(OSThread* os_thread) {
+  ASSERT(!OSThread::Compare(OSThread::GetCurrentThreadId(), os_thread->id()));
   if (FLAG_trace_thread_interrupter) {
-    OS::PrintErr("ThreadInterrupter interrupting %p\n", thread->id());
+    OS::PrintErr("ThreadInterrupter interrupting %p\n", os_thread->id());
   }
-  int result = pthread_kill(thread->id(), SIGPROF);
-  ASSERT((result == 0) || (result == ESRCH));
+
+  ThreadInterrupter::SampleBufferWriterScope scope;
+  if (!scope.CanSample()) {
+    return;
+  }
+  ThreadInterrupterMacOS interrupter(os_thread);
+  interrupter.CollectSample();
 }
 
 void ThreadInterrupter::InstallSignalHandler() {
-  SignalHandler::Install(&ThreadInterrupterMacOS::ThreadInterruptSignalHandler);
+  // Nothing to do on MacOS.
 }
 
 void ThreadInterrupter::RemoveSignalHandler() {
-  SignalHandler::Remove();
+  // Nothing to do on MacOS.
 }
 
 #endif  // !PRODUCT
diff --git a/runtime/vm/thread_interrupter_win.cc b/runtime/vm/thread_interrupter_win.cc
index bfbf5d1..3db5023 100644
--- a/runtime/vm/thread_interrupter_win.cc
+++ b/runtime/vm/thread_interrupter_win.cc
@@ -90,10 +90,6 @@
   }
 };
 
-bool ThreadInterrupter::IsDebuggerAttached() {
-  return false;
-}
-
 void ThreadInterrupter::InterruptThread(OSThread* thread) {
   if (FLAG_trace_thread_interrupter) {
     OS::PrintErr("ThreadInterrupter suspending %p\n",
diff --git a/runtime/vm/type_testing_stubs.cc b/runtime/vm/type_testing_stubs.cc
index 5742615..6b1780f 100644
--- a/runtime/vm/type_testing_stubs.cc
+++ b/runtime/vm/type_testing_stubs.cc
@@ -996,18 +996,6 @@
   }
 }
 
-// src must contain a TypePtr. Assumes dst != src. May affect flags.
-static void LoadTypeClassId(compiler::Assembler* assembler,
-                            Register dst,
-                            Register src) {
-  ASSERT(src != dst);
-  __ EnsureHasClassIdInDEBUG(kTypeCid, src, dst);
-  __ LoadCompressedSmi(
-      dst, compiler::FieldAddress(
-               src, compiler::target::Type::type_class_id_offset()));
-  __ SmiUntag(dst);
-}
-
 void TypeTestingStubGenerator::BuildOptimizedTypeParameterArgumentValueCheck(
     compiler::Assembler* assembler,
     HierarchyInfo* hi,
@@ -1052,8 +1040,8 @@
   UnwrapAbstractType(assembler, TTSInternalRegs::kSuperTypeArgumentReg,
                      TTSInternalRegs::kScratchReg, /*is_type=*/nullptr,
                      &check_subtype_type_class_ids);
-  LoadTypeClassId(assembler, TTSInternalRegs::kScratchReg,
-                  TTSInternalRegs::kSuperTypeArgumentReg);
+  __ LoadTypeClassId(TTSInternalRegs::kScratchReg,
+                     TTSInternalRegs::kSuperTypeArgumentReg);
   __ CompareImmediate(TTSInternalRegs::kScratchReg, kDynamicCid);
   __ BranchIf(EQUAL, &is_subtype);
   __ CompareImmediate(TTSInternalRegs::kScratchReg, kVoidCid);
@@ -1090,8 +1078,8 @@
   UnwrapAbstractType(assembler, TTSInternalRegs::kSubTypeArgumentReg,
                      TTSInternalRegs::kScratchReg, /*is_type=*/nullptr,
                      check_failed);
-  LoadTypeClassId(assembler, TTSInternalRegs::kScratchReg,
-                  TTSInternalRegs::kSubTypeArgumentReg);
+  __ LoadTypeClassId(TTSInternalRegs::kScratchReg,
+                     TTSInternalRegs::kSubTypeArgumentReg);
   __ CompareImmediate(TTSInternalRegs::kScratchReg, kNeverCid);
   __ BranchIf(EQUAL, &is_subtype);
   __ CompareImmediate(TTSInternalRegs::kScratchReg, kNullCid);
@@ -1186,8 +1174,8 @@
 
   // No further checks needed for non-nullable object.
   if (!type.IsObjectType()) {
-    LoadTypeClassId(assembler, TTSInternalRegs::kScratchReg,
-                    TTSInternalRegs::kSubTypeArgumentReg);
+    __ LoadTypeClassId(TTSInternalRegs::kScratchReg,
+                       TTSInternalRegs::kSubTypeArgumentReg);
 
     const bool null_is_assignable = Instance::NullIsAssignableTo(type);
     // Check bottom types.
diff --git a/sdk/lib/_internal/vm/bin/builtin.dart b/sdk/lib/_internal/vm/bin/builtin.dart
index b5263e0..e39fa7f 100644
--- a/sdk/lib/_internal/vm/bin/builtin.dart
+++ b/sdk/lib/_internal/vm/bin/builtin.dart
@@ -4,7 +4,6 @@
 
 library builtin;
 
-// NOTE: Do not import 'dart:io' in builtin.
 import 'dart:async';
 import 'dart:collection' hide LinkedList, LinkedListEntry;
 import 'dart:_internal' hide Symbol;
diff --git a/tools/VERSION b/tools/VERSION
index 3c5112c..05b635f 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 15
 PATCH 0
-PRERELEASE 236
+PRERELEASE 237
 PRERELEASE_PATCH 0
\ No newline at end of file