[vm] Reorder SubtypeTestCache inputs to improve non-dynamic cases.

In particular, avoid storing/comparing the destination type unless the
SubtypeTestCache was created for a dynamic AssertAssignable instruction.

TEST=vm/cc/STC_{Linear,Hash}Lookup, vm/cc/TTS

Bug: https://github.com/dart-lang/sdk/issues/48345
Change-Id: I279c69a668ce19785785cf71707acf951f2b2133
Cq-Include-Trybots: luci.dart.try:vm-aot-linux-debug-simriscv64-try,vm-aot-linux-debug-x64-try,vm-aot-linux-release-x64-try,vm-aot-linux-product-x64-try,vm-aot-linux-release-simarm64-try,vm-aot-linux-release-simarm_x64-try,vm-aot-linux-debug-x64c-try,vm-aot-tsan-linux-release-x64-try,vm-aot-mac-release-arm64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-aot-dwarf-linux-product-x64-try,vm-linux-release-ia32-try,vm-linux-debug-x64c-try,vm-linux-debug-x64-try,vm-linux-debug-simriscv64-try,vm-linux-release-simarm64-try,vm-linux-release-simarm-try,vm-mac-release-arm64-try,vm-mac-release-x64-try,vm-tsan-linux-release-x64-try,vm-reload-rollback-linux-release-x64-try,vm-reload-linux-release-x64-try,vm-ffi-qemu-linux-release-arm-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/310340
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
diff --git a/runtime/vm/app_snapshot.cc b/runtime/vm/app_snapshot.cc
index 335e3df..111fadd 100644
--- a/runtime/vm/app_snapshot.cc
+++ b/runtime/vm/app_snapshot.cc
@@ -3560,6 +3560,7 @@
       AutoTraceObject(cache);
       WriteField(cache, cache_);
       s->Write<uint32_t>(cache->untag()->num_inputs_);
+      s->Write<uint32_t>(cache->untag()->num_occupied_);
     }
   }
 
@@ -3588,6 +3589,7 @@
                                      SubtypeTestCache::InstanceSize());
       cache->untag()->cache_ = static_cast<ArrayPtr>(d.ReadRef());
       cache->untag()->num_inputs_ = d.Read<uint32_t>();
+      cache->untag()->num_occupied_ = d.Read<uint32_t>();
     }
   }
 };
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index eb777bd..080f034 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -2329,12 +2329,9 @@
   __ Comment("FunctionTypeTest");
 
   __ BranchIfSmi(TypeTestABI::kInstanceReg, is_not_instance_lbl);
-  // Load the type into the right register for the subtype test cache check.
-  __ LoadUniqueObject(TypeTestABI::kDstTypeReg, type);
   // Uninstantiated type class is known at compile time, but the type
   // arguments are determined at runtime by the instantiator(s).
-
-  return GenerateCallSubtypeTestStub(TypeTestStubKind::kTestTypeSevenArgs,
+  return GenerateCallSubtypeTestStub(TypeTestStubKind::kTestTypeSixArgs,
                                      is_instance_lbl, is_not_instance_lbl);
 }
 
@@ -2407,14 +2404,14 @@
 FlowGraphCompiler::GetTypeTestStubKindForTypeParameter(
     const TypeParameter& type_param) {
   // If it's guaranteed, by type-parameter bound, that the type parameter will
-  // never have a value of a function type, then we can safely do a 5-type
-  // test instead of a 7-type test.
+  // never have a value of a function type, then we can safely do a 4-type
+  // test instead of a 6-type test.
   AbstractType& bound = AbstractType::Handle(zone(), type_param.bound());
   bound = bound.UnwrapFutureOr();
   return !bound.IsTopTypeForSubtyping() && !bound.IsObjectType() &&
                  !bound.IsDartFunctionType() && bound.IsType()
-             ? TypeTestStubKind::kTestTypeFiveArgs
-             : TypeTestStubKind::kTestTypeSevenArgs;
+             ? TypeTestStubKind::kTestTypeFourArgs
+             : TypeTestStubKind::kTestTypeSixArgs;
 }
 
 // Generates quick and subtype cache tests when only the instance need be
@@ -2533,10 +2530,8 @@
     }
   }
 
-  // Load the type into the right register for the subtype test cache check.
-  __ LoadUniqueObject(TypeTestABI::kDstTypeReg, type);
   // Regular subtype test cache involving instance's type arguments.
-  return GenerateCallSubtypeTestStub(TypeTestStubKind::kTestTypeThreeArgs,
+  return GenerateCallSubtypeTestStub(TypeTestStubKind::kTestTypeTwoArgs,
                                      is_instance_lbl, is_not_instance_lbl);
 }
 
@@ -2664,8 +2659,6 @@
     // Smi can be handled by type test cache.
     __ Bind(&not_smi);
 
-    // Load the type into the right register for the subtype test cache check.
-    __ LoadUniqueObject(TypeTestABI::kDstTypeReg, type);
     const auto test_kind = GetTypeTestStubKindForTypeParameter(type_param);
     return GenerateCallSubtypeTestStub(test_kind, is_instance_lbl,
                                        is_not_instance_lbl);
@@ -2676,11 +2669,9 @@
     if (!type.IsFutureOrType()) {
       __ BranchIfSmi(TypeTestABI::kInstanceReg, is_not_instance_lbl);
     }
-    // Load the type into the right register for the subtype test cache check.
-    __ LoadUniqueObject(TypeTestABI::kDstTypeReg, type);
     // Uninstantiated type class is known at compile time, but the type
     // arguments are determined at runtime by the instantiator(s).
-    return GenerateCallSubtypeTestStub(TypeTestStubKind::kTestTypeFiveArgs,
+    return GenerateCallSubtypeTestStub(TypeTestStubKind::kTestTypeFourArgs,
                                        is_instance_lbl, is_not_instance_lbl);
   }
   return SubtypeTestCache::null();
@@ -2752,11 +2743,10 @@
 #if !defined(TARGET_ARCH_IA32)
 // Expected inputs (from TypeTestABI):
 // - kInstanceReg: instance (preserved).
-// - kDstTypeReg: destination type (for test_kind != kTestTypeOneArg).
 // - kInstantiatorTypeArgumentsReg: instantiator type arguments
-//   (for test_kind == kTestTypeFiveArg or test_kind == kTestTypeSevenArg).
+//   (for test_kind == kTestTypeFourArg or test_kind == kTestTypeSixArg).
 // - kFunctionTypeArgumentsReg: function type arguments
-//   (for test_kind == kTestTypeFiveArg or test_kind == kTestTypeSevenArg).
+//   (for test_kind == kTestTypeFourArg or test_kind == kTestTypeSixArg).
 //
 // See the arch-specific GenerateSubtypeNTestCacheStub method to see which
 // registers may need saving across this call.
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.h b/runtime/vm/compiler/backend/flow_graph_compiler.h
index f52116f..c04c8a2 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.h
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.h
@@ -1024,8 +1024,9 @@
 
   enum class TypeTestStubKind {
     kTestTypeOneArg = 1,
-    kTestTypeThreeArgs = 3,
-    kTestTypeFiveArgs = 5,
+    kTestTypeTwoArgs = 2,
+    kTestTypeFourArgs = 4,
+    kTestTypeSixArgs = 6,
     kTestTypeSevenArgs = 7,
   };
 
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
index 8bdde80..2d2d22c 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
@@ -188,11 +188,11 @@
 
 // Input registers (from TypeTestABI):
 // - kInstanceReg: instance.
-// - kDstTypeReg: destination type (for test_kind != kTestTypeOneArg).
+// - kDstTypeReg: destination type (for test_kind == kTestTypeSevenArg).
 // - kInstantiatorTypeArgumentsReg: instantiator type arguments
-//   (for test_kind == kTestTypeFiveArg or test_kind == kTestTypeSevenArg).
+//   (for test_kind == kTestTypeFourArg, kTestTypeSixArg, or kTestTypeSevenArg).
 // - kFunctionTypeArgumentsReg: function type arguments
-//   (for test_kind == kTestTypeFiveArg or test_kind == kTestTypeSevenArg).
+//   (for test_kind == kTestTypeFourArg, kTestTypeSixArg, or kTestTypeSevenArg).
 //
 // Only preserves kInstanceReg from TypeTestABI, all other TypeTestABI
 // registers may be used and thus must be saved by the caller.
@@ -200,15 +200,6 @@
     TypeTestStubKind test_kind,
     compiler::Label* is_instance_lbl,
     compiler::Label* is_not_instance_lbl) {
-  // Used for registers that may not have GC-safe values to push. Pushes
-  // the null object if the condition is not met.
-  auto conditional_push = [&](Register reg, bool condition) {
-    if (condition) {
-      __ pushl(reg);
-    } else {
-      __ PushObject(Object::null_object());
-    }
-  };
   const intptr_t num_inputs = UsedInputsForTTSKind(test_kind);
   const SubtypeTestCache& type_test_cache =
       SubtypeTestCache::ZoneHandle(zone(), SubtypeTestCache::New(num_inputs));
@@ -217,9 +208,23 @@
   __ LoadObject(TypeTestABI::kSubtypeTestCacheReg, type_test_cache);
   __ pushl(TypeTestABI::kSubtypeTestCacheReg);
   __ pushl(TypeTestABI::kInstanceReg);
-  conditional_push(TypeTestABI::kDstTypeReg, num_inputs >= 3);
-  conditional_push(TypeTestABI::kInstantiatorTypeArgumentsReg, num_inputs >= 4);
-  conditional_push(TypeTestABI::kFunctionTypeArgumentsReg, num_inputs >= 5);
+  // Registers for unused inputs may not have GC-safe values to push, so push
+  // the null object if the input is unused instead.
+  if (num_inputs >= 7) {
+    __ pushl(TypeTestABI::kDstTypeReg);
+  } else {
+    __ PushObject(Object::null_object());
+  }
+  if (num_inputs >= 3) {
+    __ pushl(TypeTestABI::kInstantiatorTypeArgumentsReg);
+  } else {
+    __ PushObject(Object::null_object());
+  }
+  if (num_inputs >= 4) {
+    __ pushl(TypeTestABI::kFunctionTypeArgumentsReg);
+  } else {
+    __ PushObject(Object::null_object());
+  }
   __ Call(stub_entry);
   // Restore all but kSubtypeTestCacheReg (since it is the same as
   // kSubtypeTestCacheResultReg). Since the generated code is documented as
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc
index c3ac863..966035a 100644
--- a/runtime/vm/compiler/runtime_api.cc
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -293,12 +293,16 @@
   return dart::StubCode::AllocateArray();
 }
 
-const Code& StubCodeSubtype3TestCache() {
-  return dart::StubCode::Subtype3TestCache();
+const Code& StubCodeSubtype2TestCache() {
+  return dart::StubCode::Subtype2TestCache();
 }
 
-const Code& StubCodeSubtype5TestCache() {
-  return dart::StubCode::Subtype5TestCache();
+const Code& StubCodeSubtype4TestCache() {
+  return dart::StubCode::Subtype4TestCache();
+}
+
+const Code& StubCodeSubtype6TestCache() {
+  return dart::StubCode::Subtype6TestCache();
 }
 
 const Code& StubCodeSubtype7TestCache() {
diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h
index f721041..09ccdfb 100644
--- a/runtime/vm/compiler/runtime_api.h
+++ b/runtime/vm/compiler/runtime_api.h
@@ -215,8 +215,9 @@
 #endif
 
 const Code& StubCodeAllocateArray();
-const Code& StubCodeSubtype3TestCache();
-const Code& StubCodeSubtype5TestCache();
+const Code& StubCodeSubtype2TestCache();
+const Code& StubCodeSubtype4TestCache();
+const Code& StubCodeSubtype6TestCache();
 const Code& StubCodeSubtype7TestCache();
 
 class RuntimeEntry : public ValueObject {
@@ -1433,7 +1434,6 @@
   static word cache_offset();
   static word num_inputs_offset();
 
-  static const word kHeaderSize;
   static const word kMaxInputs;
   static const word kTestEntryLength;
   static const word kInstanceCidOrSignature;
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index 73a212d..be7d4c9 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -96,22 +96,20 @@
     OneByteString_kMaxNewSpaceElements = 0x3fff4;
 static constexpr dart::compiler::target::word
     TwoByteString_kMaxNewSpaceElements = 0x1fffa;
-static constexpr dart::compiler::target::word SubtypeTestCache_kHeaderSize =
-    0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kFunctionTypeArguments = 0x4;
+    SubtypeTestCache_kFunctionTypeArguments = 0x3;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kInstanceCidOrSignature = 0x0;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kDestinationType = 0x1;
+    SubtypeTestCache_kDestinationType = 0x6;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x6;
+    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x5;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x5;
+    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x4;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceTypeArguments = 0x2;
+    SubtypeTestCache_kInstanceTypeArguments = 0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstantiatorTypeArguments = 0x3;
+    SubtypeTestCache_kInstantiatorTypeArguments = 0x2;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kTestEntryLength = 0x8;
 static constexpr dart::compiler::target::word SubtypeTestCache_kMaxInputs = 0x7;
@@ -703,7 +701,7 @@
 static constexpr dart::compiler::target::word SuspendState_HeaderSize = 0x1c;
 static constexpr dart::compiler::target::word String_InstanceSize = 0xc;
 static constexpr dart::compiler::target::word SubtypeTestCache_InstanceSize =
-    0xc;
+    0x10;
 static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 0x14;
 static constexpr dart::compiler::target::word
     TransferableTypedData_InstanceSize = 0x4;
@@ -808,22 +806,20 @@
     OneByteString_kMaxNewSpaceElements = 0x3fff0;
 static constexpr dart::compiler::target::word
     TwoByteString_kMaxNewSpaceElements = 0x1fff8;
-static constexpr dart::compiler::target::word SubtypeTestCache_kHeaderSize =
-    0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kFunctionTypeArguments = 0x4;
+    SubtypeTestCache_kFunctionTypeArguments = 0x3;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kInstanceCidOrSignature = 0x0;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kDestinationType = 0x1;
+    SubtypeTestCache_kDestinationType = 0x6;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x6;
+    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x5;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x5;
+    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x4;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceTypeArguments = 0x2;
+    SubtypeTestCache_kInstanceTypeArguments = 0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstantiatorTypeArguments = 0x3;
+    SubtypeTestCache_kInstantiatorTypeArguments = 0x2;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kTestEntryLength = 0x8;
 static constexpr dart::compiler::target::word SubtypeTestCache_kMaxInputs = 0x7;
@@ -1522,22 +1518,20 @@
     OneByteString_kMaxNewSpaceElements = 0x3fff4;
 static constexpr dart::compiler::target::word
     TwoByteString_kMaxNewSpaceElements = 0x1fffa;
-static constexpr dart::compiler::target::word SubtypeTestCache_kHeaderSize =
-    0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kFunctionTypeArguments = 0x4;
+    SubtypeTestCache_kFunctionTypeArguments = 0x3;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kInstanceCidOrSignature = 0x0;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kDestinationType = 0x1;
+    SubtypeTestCache_kDestinationType = 0x6;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x6;
+    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x5;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x5;
+    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x4;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceTypeArguments = 0x2;
+    SubtypeTestCache_kInstanceTypeArguments = 0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstantiatorTypeArguments = 0x3;
+    SubtypeTestCache_kInstantiatorTypeArguments = 0x2;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kTestEntryLength = 0x8;
 static constexpr dart::compiler::target::word SubtypeTestCache_kMaxInputs = 0x7;
@@ -2128,7 +2122,7 @@
 static constexpr dart::compiler::target::word SuspendState_HeaderSize = 0x1c;
 static constexpr dart::compiler::target::word String_InstanceSize = 0xc;
 static constexpr dart::compiler::target::word SubtypeTestCache_InstanceSize =
-    0xc;
+    0x10;
 static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 0x14;
 static constexpr dart::compiler::target::word
     TransferableTypedData_InstanceSize = 0x4;
@@ -2233,22 +2227,20 @@
     OneByteString_kMaxNewSpaceElements = 0x3fff0;
 static constexpr dart::compiler::target::word
     TwoByteString_kMaxNewSpaceElements = 0x1fff8;
-static constexpr dart::compiler::target::word SubtypeTestCache_kHeaderSize =
-    0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kFunctionTypeArguments = 0x4;
+    SubtypeTestCache_kFunctionTypeArguments = 0x3;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kInstanceCidOrSignature = 0x0;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kDestinationType = 0x1;
+    SubtypeTestCache_kDestinationType = 0x6;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x6;
+    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x5;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x5;
+    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x4;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceTypeArguments = 0x2;
+    SubtypeTestCache_kInstanceTypeArguments = 0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstantiatorTypeArguments = 0x3;
+    SubtypeTestCache_kInstantiatorTypeArguments = 0x2;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kTestEntryLength = 0x8;
 static constexpr dart::compiler::target::word SubtypeTestCache_kMaxInputs = 0x7;
@@ -2950,22 +2942,20 @@
     OneByteString_kMaxNewSpaceElements = 0x3fff0;
 static constexpr dart::compiler::target::word
     TwoByteString_kMaxNewSpaceElements = 0x1fff8;
-static constexpr dart::compiler::target::word SubtypeTestCache_kHeaderSize =
-    0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kFunctionTypeArguments = 0x4;
+    SubtypeTestCache_kFunctionTypeArguments = 0x3;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kInstanceCidOrSignature = 0x0;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kDestinationType = 0x1;
+    SubtypeTestCache_kDestinationType = 0x6;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x6;
+    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x5;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x5;
+    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x4;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceTypeArguments = 0x2;
+    SubtypeTestCache_kInstanceTypeArguments = 0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstantiatorTypeArguments = 0x3;
+    SubtypeTestCache_kInstantiatorTypeArguments = 0x2;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kTestEntryLength = 0x8;
 static constexpr dart::compiler::target::word SubtypeTestCache_kMaxInputs = 0x7;
@@ -3664,22 +3654,20 @@
     OneByteString_kMaxNewSpaceElements = 0x3fff0;
 static constexpr dart::compiler::target::word
     TwoByteString_kMaxNewSpaceElements = 0x1fff8;
-static constexpr dart::compiler::target::word SubtypeTestCache_kHeaderSize =
-    0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kFunctionTypeArguments = 0x4;
+    SubtypeTestCache_kFunctionTypeArguments = 0x3;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kInstanceCidOrSignature = 0x0;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kDestinationType = 0x1;
+    SubtypeTestCache_kDestinationType = 0x6;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x6;
+    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x5;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x5;
+    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x4;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceTypeArguments = 0x2;
+    SubtypeTestCache_kInstanceTypeArguments = 0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstantiatorTypeArguments = 0x3;
+    SubtypeTestCache_kInstantiatorTypeArguments = 0x2;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kTestEntryLength = 0x8;
 static constexpr dart::compiler::target::word SubtypeTestCache_kMaxInputs = 0x7;
@@ -4379,22 +4367,20 @@
     OneByteString_kMaxNewSpaceElements = 0x3fff4;
 static constexpr dart::compiler::target::word
     TwoByteString_kMaxNewSpaceElements = 0x1fffa;
-static constexpr dart::compiler::target::word SubtypeTestCache_kHeaderSize =
-    0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kFunctionTypeArguments = 0x4;
+    SubtypeTestCache_kFunctionTypeArguments = 0x3;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kInstanceCidOrSignature = 0x0;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kDestinationType = 0x1;
+    SubtypeTestCache_kDestinationType = 0x6;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x6;
+    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x5;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x5;
+    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x4;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceTypeArguments = 0x2;
+    SubtypeTestCache_kInstanceTypeArguments = 0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstantiatorTypeArguments = 0x3;
+    SubtypeTestCache_kInstantiatorTypeArguments = 0x2;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kTestEntryLength = 0x8;
 static constexpr dart::compiler::target::word SubtypeTestCache_kMaxInputs = 0x7;
@@ -4987,7 +4973,7 @@
 static constexpr dart::compiler::target::word SuspendState_HeaderSize = 0x1c;
 static constexpr dart::compiler::target::word String_InstanceSize = 0xc;
 static constexpr dart::compiler::target::word SubtypeTestCache_InstanceSize =
-    0xc;
+    0x10;
 static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 0x14;
 static constexpr dart::compiler::target::word
     TransferableTypedData_InstanceSize = 0x4;
@@ -5092,22 +5078,20 @@
     OneByteString_kMaxNewSpaceElements = 0x3fff0;
 static constexpr dart::compiler::target::word
     TwoByteString_kMaxNewSpaceElements = 0x1fff8;
-static constexpr dart::compiler::target::word SubtypeTestCache_kHeaderSize =
-    0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kFunctionTypeArguments = 0x4;
+    SubtypeTestCache_kFunctionTypeArguments = 0x3;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kInstanceCidOrSignature = 0x0;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kDestinationType = 0x1;
+    SubtypeTestCache_kDestinationType = 0x6;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x6;
+    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x5;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x5;
+    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x4;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceTypeArguments = 0x2;
+    SubtypeTestCache_kInstanceTypeArguments = 0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstantiatorTypeArguments = 0x3;
+    SubtypeTestCache_kInstantiatorTypeArguments = 0x2;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kTestEntryLength = 0x8;
 static constexpr dart::compiler::target::word SubtypeTestCache_kMaxInputs = 0x7;
@@ -5806,22 +5790,20 @@
     OneByteString_kMaxNewSpaceElements = 0x3fff4;
 static constexpr dart::compiler::target::word
     TwoByteString_kMaxNewSpaceElements = 0x1fffa;
-static constexpr dart::compiler::target::word SubtypeTestCache_kHeaderSize =
-    0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kFunctionTypeArguments = 0x4;
+    SubtypeTestCache_kFunctionTypeArguments = 0x3;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kInstanceCidOrSignature = 0x0;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kDestinationType = 0x1;
+    SubtypeTestCache_kDestinationType = 0x6;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x6;
+    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x5;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x5;
+    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x4;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceTypeArguments = 0x2;
+    SubtypeTestCache_kInstanceTypeArguments = 0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstantiatorTypeArguments = 0x3;
+    SubtypeTestCache_kInstantiatorTypeArguments = 0x2;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kTestEntryLength = 0x8;
 static constexpr dart::compiler::target::word SubtypeTestCache_kMaxInputs = 0x7;
@@ -6408,7 +6390,7 @@
 static constexpr dart::compiler::target::word SuspendState_HeaderSize = 0x1c;
 static constexpr dart::compiler::target::word String_InstanceSize = 0xc;
 static constexpr dart::compiler::target::word SubtypeTestCache_InstanceSize =
-    0xc;
+    0x10;
 static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 0x14;
 static constexpr dart::compiler::target::word
     TransferableTypedData_InstanceSize = 0x4;
@@ -6510,22 +6492,20 @@
     OneByteString_kMaxNewSpaceElements = 0x3fff0;
 static constexpr dart::compiler::target::word
     TwoByteString_kMaxNewSpaceElements = 0x1fff8;
-static constexpr dart::compiler::target::word SubtypeTestCache_kHeaderSize =
-    0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kFunctionTypeArguments = 0x4;
+    SubtypeTestCache_kFunctionTypeArguments = 0x3;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kInstanceCidOrSignature = 0x0;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kDestinationType = 0x1;
+    SubtypeTestCache_kDestinationType = 0x6;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x6;
+    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x5;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x5;
+    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x4;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceTypeArguments = 0x2;
+    SubtypeTestCache_kInstanceTypeArguments = 0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstantiatorTypeArguments = 0x3;
+    SubtypeTestCache_kInstantiatorTypeArguments = 0x2;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kTestEntryLength = 0x8;
 static constexpr dart::compiler::target::word SubtypeTestCache_kMaxInputs = 0x7;
@@ -7216,22 +7196,20 @@
     OneByteString_kMaxNewSpaceElements = 0x3fff4;
 static constexpr dart::compiler::target::word
     TwoByteString_kMaxNewSpaceElements = 0x1fffa;
-static constexpr dart::compiler::target::word SubtypeTestCache_kHeaderSize =
-    0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kFunctionTypeArguments = 0x4;
+    SubtypeTestCache_kFunctionTypeArguments = 0x3;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kInstanceCidOrSignature = 0x0;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kDestinationType = 0x1;
+    SubtypeTestCache_kDestinationType = 0x6;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x6;
+    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x5;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x5;
+    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x4;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceTypeArguments = 0x2;
+    SubtypeTestCache_kInstanceTypeArguments = 0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstantiatorTypeArguments = 0x3;
+    SubtypeTestCache_kInstantiatorTypeArguments = 0x2;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kTestEntryLength = 0x8;
 static constexpr dart::compiler::target::word SubtypeTestCache_kMaxInputs = 0x7;
@@ -7817,7 +7795,7 @@
 static constexpr dart::compiler::target::word SuspendState_HeaderSize = 0x1c;
 static constexpr dart::compiler::target::word String_InstanceSize = 0xc;
 static constexpr dart::compiler::target::word SubtypeTestCache_InstanceSize =
-    0xc;
+    0x10;
 static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 0x14;
 static constexpr dart::compiler::target::word
     TransferableTypedData_InstanceSize = 0x4;
@@ -7919,22 +7897,20 @@
     OneByteString_kMaxNewSpaceElements = 0x3fff0;
 static constexpr dart::compiler::target::word
     TwoByteString_kMaxNewSpaceElements = 0x1fff8;
-static constexpr dart::compiler::target::word SubtypeTestCache_kHeaderSize =
-    0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kFunctionTypeArguments = 0x4;
+    SubtypeTestCache_kFunctionTypeArguments = 0x3;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kInstanceCidOrSignature = 0x0;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kDestinationType = 0x1;
+    SubtypeTestCache_kDestinationType = 0x6;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x6;
+    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x5;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x5;
+    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x4;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceTypeArguments = 0x2;
+    SubtypeTestCache_kInstanceTypeArguments = 0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstantiatorTypeArguments = 0x3;
+    SubtypeTestCache_kInstantiatorTypeArguments = 0x2;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kTestEntryLength = 0x8;
 static constexpr dart::compiler::target::word SubtypeTestCache_kMaxInputs = 0x7;
@@ -8628,22 +8604,20 @@
     OneByteString_kMaxNewSpaceElements = 0x3fff0;
 static constexpr dart::compiler::target::word
     TwoByteString_kMaxNewSpaceElements = 0x1fff8;
-static constexpr dart::compiler::target::word SubtypeTestCache_kHeaderSize =
-    0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kFunctionTypeArguments = 0x4;
+    SubtypeTestCache_kFunctionTypeArguments = 0x3;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kInstanceCidOrSignature = 0x0;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kDestinationType = 0x1;
+    SubtypeTestCache_kDestinationType = 0x6;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x6;
+    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x5;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x5;
+    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x4;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceTypeArguments = 0x2;
+    SubtypeTestCache_kInstanceTypeArguments = 0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstantiatorTypeArguments = 0x3;
+    SubtypeTestCache_kInstantiatorTypeArguments = 0x2;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kTestEntryLength = 0x8;
 static constexpr dart::compiler::target::word SubtypeTestCache_kMaxInputs = 0x7;
@@ -9334,22 +9308,20 @@
     OneByteString_kMaxNewSpaceElements = 0x3fff0;
 static constexpr dart::compiler::target::word
     TwoByteString_kMaxNewSpaceElements = 0x1fff8;
-static constexpr dart::compiler::target::word SubtypeTestCache_kHeaderSize =
-    0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kFunctionTypeArguments = 0x4;
+    SubtypeTestCache_kFunctionTypeArguments = 0x3;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kInstanceCidOrSignature = 0x0;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kDestinationType = 0x1;
+    SubtypeTestCache_kDestinationType = 0x6;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x6;
+    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x5;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x5;
+    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x4;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceTypeArguments = 0x2;
+    SubtypeTestCache_kInstanceTypeArguments = 0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstantiatorTypeArguments = 0x3;
+    SubtypeTestCache_kInstantiatorTypeArguments = 0x2;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kTestEntryLength = 0x8;
 static constexpr dart::compiler::target::word SubtypeTestCache_kMaxInputs = 0x7;
@@ -10041,22 +10013,20 @@
     OneByteString_kMaxNewSpaceElements = 0x3fff4;
 static constexpr dart::compiler::target::word
     TwoByteString_kMaxNewSpaceElements = 0x1fffa;
-static constexpr dart::compiler::target::word SubtypeTestCache_kHeaderSize =
-    0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kFunctionTypeArguments = 0x4;
+    SubtypeTestCache_kFunctionTypeArguments = 0x3;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kInstanceCidOrSignature = 0x0;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kDestinationType = 0x1;
+    SubtypeTestCache_kDestinationType = 0x6;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x6;
+    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x5;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x5;
+    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x4;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceTypeArguments = 0x2;
+    SubtypeTestCache_kInstanceTypeArguments = 0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstantiatorTypeArguments = 0x3;
+    SubtypeTestCache_kInstantiatorTypeArguments = 0x2;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kTestEntryLength = 0x8;
 static constexpr dart::compiler::target::word SubtypeTestCache_kMaxInputs = 0x7;
@@ -10644,7 +10614,7 @@
 static constexpr dart::compiler::target::word SuspendState_HeaderSize = 0x1c;
 static constexpr dart::compiler::target::word String_InstanceSize = 0xc;
 static constexpr dart::compiler::target::word SubtypeTestCache_InstanceSize =
-    0xc;
+    0x10;
 static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 0x14;
 static constexpr dart::compiler::target::word
     TransferableTypedData_InstanceSize = 0x4;
@@ -10746,22 +10716,20 @@
     OneByteString_kMaxNewSpaceElements = 0x3fff0;
 static constexpr dart::compiler::target::word
     TwoByteString_kMaxNewSpaceElements = 0x1fff8;
-static constexpr dart::compiler::target::word SubtypeTestCache_kHeaderSize =
-    0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kFunctionTypeArguments = 0x4;
+    SubtypeTestCache_kFunctionTypeArguments = 0x3;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kInstanceCidOrSignature = 0x0;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kDestinationType = 0x1;
+    SubtypeTestCache_kDestinationType = 0x6;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x6;
+    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x5;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x5;
+    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x4;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstanceTypeArguments = 0x2;
+    SubtypeTestCache_kInstanceTypeArguments = 0x1;
 static constexpr dart::compiler::target::word
-    SubtypeTestCache_kInstantiatorTypeArguments = 0x3;
+    SubtypeTestCache_kInstantiatorTypeArguments = 0x2;
 static constexpr dart::compiler::target::word
     SubtypeTestCache_kTestEntryLength = 0x8;
 static constexpr dart::compiler::target::word SubtypeTestCache_kMaxInputs = 0x7;
@@ -11463,22 +11431,20 @@
     AOT_OneByteString_kMaxNewSpaceElements = 0x3fff4;
 static constexpr dart::compiler::target::word
     AOT_TwoByteString_kMaxNewSpaceElements = 0x1fffa;
-static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kHeaderSize =
-    0x1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kFunctionTypeArguments = 0x4;
+    AOT_SubtypeTestCache_kFunctionTypeArguments = 0x3;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kInstanceCidOrSignature = 0x0;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kDestinationType = 0x1;
+    AOT_SubtypeTestCache_kDestinationType = 0x6;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x6;
+    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x5;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x5;
+    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x4;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceTypeArguments = 0x2;
+    AOT_SubtypeTestCache_kInstanceTypeArguments = 0x1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 0x3;
+    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 0x2;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kTestEntryLength = 0x8;
 static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kMaxInputs =
@@ -12140,7 +12106,7 @@
     0x18;
 static constexpr dart::compiler::target::word AOT_String_InstanceSize = 0xc;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_InstanceSize = 0xc;
+    AOT_SubtypeTestCache_InstanceSize = 0x10;
 static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize =
     0x14;
 static constexpr dart::compiler::target::word
@@ -12252,22 +12218,20 @@
     AOT_OneByteString_kMaxNewSpaceElements = 0x3fff0;
 static constexpr dart::compiler::target::word
     AOT_TwoByteString_kMaxNewSpaceElements = 0x1fff8;
-static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kHeaderSize =
-    0x1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kFunctionTypeArguments = 0x4;
+    AOT_SubtypeTestCache_kFunctionTypeArguments = 0x3;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kInstanceCidOrSignature = 0x0;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kDestinationType = 0x1;
+    AOT_SubtypeTestCache_kDestinationType = 0x6;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x6;
+    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x5;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x5;
+    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x4;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceTypeArguments = 0x2;
+    AOT_SubtypeTestCache_kInstanceTypeArguments = 0x1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 0x3;
+    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 0x2;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kTestEntryLength = 0x8;
 static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kMaxInputs =
@@ -13044,22 +13008,20 @@
     AOT_OneByteString_kMaxNewSpaceElements = 0x3fff0;
 static constexpr dart::compiler::target::word
     AOT_TwoByteString_kMaxNewSpaceElements = 0x1fff8;
-static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kHeaderSize =
-    0x1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kFunctionTypeArguments = 0x4;
+    AOT_SubtypeTestCache_kFunctionTypeArguments = 0x3;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kInstanceCidOrSignature = 0x0;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kDestinationType = 0x1;
+    AOT_SubtypeTestCache_kDestinationType = 0x6;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x6;
+    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x5;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x5;
+    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x4;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceTypeArguments = 0x2;
+    AOT_SubtypeTestCache_kInstanceTypeArguments = 0x1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 0x3;
+    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 0x2;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kTestEntryLength = 0x8;
 static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kMaxInputs =
@@ -13835,22 +13797,20 @@
     AOT_OneByteString_kMaxNewSpaceElements = 0x3fff0;
 static constexpr dart::compiler::target::word
     AOT_TwoByteString_kMaxNewSpaceElements = 0x1fff8;
-static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kHeaderSize =
-    0x1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kFunctionTypeArguments = 0x4;
+    AOT_SubtypeTestCache_kFunctionTypeArguments = 0x3;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kInstanceCidOrSignature = 0x0;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kDestinationType = 0x1;
+    AOT_SubtypeTestCache_kDestinationType = 0x6;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x6;
+    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x5;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x5;
+    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x4;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceTypeArguments = 0x2;
+    AOT_SubtypeTestCache_kInstanceTypeArguments = 0x1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 0x3;
+    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 0x2;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kTestEntryLength = 0x8;
 static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kMaxInputs =
@@ -14626,22 +14586,20 @@
     AOT_OneByteString_kMaxNewSpaceElements = 0x3fff0;
 static constexpr dart::compiler::target::word
     AOT_TwoByteString_kMaxNewSpaceElements = 0x1fff8;
-static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kHeaderSize =
-    0x1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kFunctionTypeArguments = 0x4;
+    AOT_SubtypeTestCache_kFunctionTypeArguments = 0x3;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kInstanceCidOrSignature = 0x0;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kDestinationType = 0x1;
+    AOT_SubtypeTestCache_kDestinationType = 0x6;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x6;
+    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x5;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x5;
+    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x4;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceTypeArguments = 0x2;
+    AOT_SubtypeTestCache_kInstanceTypeArguments = 0x1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 0x3;
+    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 0x2;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kTestEntryLength = 0x8;
 static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kMaxInputs =
@@ -15419,22 +15377,20 @@
     AOT_OneByteString_kMaxNewSpaceElements = 0x3fff4;
 static constexpr dart::compiler::target::word
     AOT_TwoByteString_kMaxNewSpaceElements = 0x1fffa;
-static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kHeaderSize =
-    0x1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kFunctionTypeArguments = 0x4;
+    AOT_SubtypeTestCache_kFunctionTypeArguments = 0x3;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kInstanceCidOrSignature = 0x0;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kDestinationType = 0x1;
+    AOT_SubtypeTestCache_kDestinationType = 0x6;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x6;
+    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x5;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x5;
+    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x4;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceTypeArguments = 0x2;
+    AOT_SubtypeTestCache_kInstanceTypeArguments = 0x1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 0x3;
+    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 0x2;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kTestEntryLength = 0x8;
 static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kMaxInputs =
@@ -16097,7 +16053,7 @@
     0x18;
 static constexpr dart::compiler::target::word AOT_String_InstanceSize = 0xc;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_InstanceSize = 0xc;
+    AOT_SubtypeTestCache_InstanceSize = 0x10;
 static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize =
     0x14;
 static constexpr dart::compiler::target::word
@@ -16209,22 +16165,20 @@
     AOT_OneByteString_kMaxNewSpaceElements = 0x3fff0;
 static constexpr dart::compiler::target::word
     AOT_TwoByteString_kMaxNewSpaceElements = 0x1fff8;
-static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kHeaderSize =
-    0x1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kFunctionTypeArguments = 0x4;
+    AOT_SubtypeTestCache_kFunctionTypeArguments = 0x3;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kInstanceCidOrSignature = 0x0;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kDestinationType = 0x1;
+    AOT_SubtypeTestCache_kDestinationType = 0x6;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x6;
+    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x5;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x5;
+    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x4;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceTypeArguments = 0x2;
+    AOT_SubtypeTestCache_kInstanceTypeArguments = 0x1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 0x3;
+    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 0x2;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kTestEntryLength = 0x8;
 static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kMaxInputs =
@@ -16998,22 +16952,20 @@
     AOT_OneByteString_kMaxNewSpaceElements = 0x3fff4;
 static constexpr dart::compiler::target::word
     AOT_TwoByteString_kMaxNewSpaceElements = 0x1fffa;
-static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kHeaderSize =
-    0x1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kFunctionTypeArguments = 0x4;
+    AOT_SubtypeTestCache_kFunctionTypeArguments = 0x3;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kInstanceCidOrSignature = 0x0;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kDestinationType = 0x1;
+    AOT_SubtypeTestCache_kDestinationType = 0x6;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x6;
+    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x5;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x5;
+    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x4;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceTypeArguments = 0x2;
+    AOT_SubtypeTestCache_kInstanceTypeArguments = 0x1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 0x3;
+    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 0x2;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kTestEntryLength = 0x8;
 static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kMaxInputs =
@@ -17669,7 +17621,7 @@
     0x18;
 static constexpr dart::compiler::target::word AOT_String_InstanceSize = 0xc;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_InstanceSize = 0xc;
+    AOT_SubtypeTestCache_InstanceSize = 0x10;
 static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize =
     0x14;
 static constexpr dart::compiler::target::word
@@ -17778,22 +17730,20 @@
     AOT_OneByteString_kMaxNewSpaceElements = 0x3fff0;
 static constexpr dart::compiler::target::word
     AOT_TwoByteString_kMaxNewSpaceElements = 0x1fff8;
-static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kHeaderSize =
-    0x1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kFunctionTypeArguments = 0x4;
+    AOT_SubtypeTestCache_kFunctionTypeArguments = 0x3;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kInstanceCidOrSignature = 0x0;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kDestinationType = 0x1;
+    AOT_SubtypeTestCache_kDestinationType = 0x6;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x6;
+    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x5;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x5;
+    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x4;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceTypeArguments = 0x2;
+    AOT_SubtypeTestCache_kInstanceTypeArguments = 0x1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 0x3;
+    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 0x2;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kTestEntryLength = 0x8;
 static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kMaxInputs =
@@ -18561,22 +18511,20 @@
     AOT_OneByteString_kMaxNewSpaceElements = 0x3fff0;
 static constexpr dart::compiler::target::word
     AOT_TwoByteString_kMaxNewSpaceElements = 0x1fff8;
-static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kHeaderSize =
-    0x1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kFunctionTypeArguments = 0x4;
+    AOT_SubtypeTestCache_kFunctionTypeArguments = 0x3;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kInstanceCidOrSignature = 0x0;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kDestinationType = 0x1;
+    AOT_SubtypeTestCache_kDestinationType = 0x6;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x6;
+    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x5;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x5;
+    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x4;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceTypeArguments = 0x2;
+    AOT_SubtypeTestCache_kInstanceTypeArguments = 0x1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 0x3;
+    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 0x2;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kTestEntryLength = 0x8;
 static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kMaxInputs =
@@ -19343,22 +19291,20 @@
     AOT_OneByteString_kMaxNewSpaceElements = 0x3fff0;
 static constexpr dart::compiler::target::word
     AOT_TwoByteString_kMaxNewSpaceElements = 0x1fff8;
-static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kHeaderSize =
-    0x1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kFunctionTypeArguments = 0x4;
+    AOT_SubtypeTestCache_kFunctionTypeArguments = 0x3;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kInstanceCidOrSignature = 0x0;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kDestinationType = 0x1;
+    AOT_SubtypeTestCache_kDestinationType = 0x6;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x6;
+    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x5;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x5;
+    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x4;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceTypeArguments = 0x2;
+    AOT_SubtypeTestCache_kInstanceTypeArguments = 0x1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 0x3;
+    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 0x2;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kTestEntryLength = 0x8;
 static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kMaxInputs =
@@ -20125,22 +20071,20 @@
     AOT_OneByteString_kMaxNewSpaceElements = 0x3fff0;
 static constexpr dart::compiler::target::word
     AOT_TwoByteString_kMaxNewSpaceElements = 0x1fff8;
-static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kHeaderSize =
-    0x1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kFunctionTypeArguments = 0x4;
+    AOT_SubtypeTestCache_kFunctionTypeArguments = 0x3;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kInstanceCidOrSignature = 0x0;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kDestinationType = 0x1;
+    AOT_SubtypeTestCache_kDestinationType = 0x6;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x6;
+    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x5;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x5;
+    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x4;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceTypeArguments = 0x2;
+    AOT_SubtypeTestCache_kInstanceTypeArguments = 0x1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 0x3;
+    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 0x2;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kTestEntryLength = 0x8;
 static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kMaxInputs =
@@ -20909,22 +20853,20 @@
     AOT_OneByteString_kMaxNewSpaceElements = 0x3fff4;
 static constexpr dart::compiler::target::word
     AOT_TwoByteString_kMaxNewSpaceElements = 0x1fffa;
-static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kHeaderSize =
-    0x1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kFunctionTypeArguments = 0x4;
+    AOT_SubtypeTestCache_kFunctionTypeArguments = 0x3;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kInstanceCidOrSignature = 0x0;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kDestinationType = 0x1;
+    AOT_SubtypeTestCache_kDestinationType = 0x6;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x6;
+    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x5;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x5;
+    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x4;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceTypeArguments = 0x2;
+    AOT_SubtypeTestCache_kInstanceTypeArguments = 0x1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 0x3;
+    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 0x2;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kTestEntryLength = 0x8;
 static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kMaxInputs =
@@ -21581,7 +21523,7 @@
     0x18;
 static constexpr dart::compiler::target::word AOT_String_InstanceSize = 0xc;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_InstanceSize = 0xc;
+    AOT_SubtypeTestCache_InstanceSize = 0x10;
 static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize =
     0x14;
 static constexpr dart::compiler::target::word
@@ -21690,22 +21632,20 @@
     AOT_OneByteString_kMaxNewSpaceElements = 0x3fff0;
 static constexpr dart::compiler::target::word
     AOT_TwoByteString_kMaxNewSpaceElements = 0x1fff8;
-static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kHeaderSize =
-    0x1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kFunctionTypeArguments = 0x4;
+    AOT_SubtypeTestCache_kFunctionTypeArguments = 0x3;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kInstanceCidOrSignature = 0x0;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kDestinationType = 0x1;
+    AOT_SubtypeTestCache_kDestinationType = 0x6;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x6;
+    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 0x5;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x5;
+    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 0x4;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstanceTypeArguments = 0x2;
+    AOT_SubtypeTestCache_kInstanceTypeArguments = 0x1;
 static constexpr dart::compiler::target::word
-    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 0x3;
+    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 0x2;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_kTestEntryLength = 0x8;
 static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kMaxInputs =
diff --git a/runtime/vm/compiler/runtime_offsets_list.h b/runtime/vm/compiler/runtime_offsets_list.h
index b2d58f0..2ac6d96 100644
--- a/runtime/vm/compiler/runtime_offsets_list.h
+++ b/runtime/vm/compiler/runtime_offsets_list.h
@@ -94,7 +94,6 @@
   CONSTANT(String, kMaxElements)                                               \
   CONSTANT(OneByteString, kMaxNewSpaceElements)                                \
   CONSTANT(TwoByteString, kMaxNewSpaceElements)                                \
-  CONSTANT(SubtypeTestCache, kHeaderSize)                                      \
   CONSTANT(SubtypeTestCache, kFunctionTypeArguments)                           \
   CONSTANT(SubtypeTestCache, kInstanceCidOrSignature)                          \
   CONSTANT(SubtypeTestCache, kDestinationType)                                 \
diff --git a/runtime/vm/compiler/stub_code_compiler.cc b/runtime/vm/compiler/stub_code_compiler.cc
index 2b8d1d3..495a676 100644
--- a/runtime/vm/compiler/stub_code_compiler.cc
+++ b/runtime/vm/compiler/stub_code_compiler.cc
@@ -1094,14 +1094,16 @@
   __ BranchIf(EQUAL, &call_runtime, Assembler::kNearJump);
 
   // Use the number of inputs used by the STC to determine which stub to call.
-  Label call_3, call_5;
+  Label call_2, call_4, call_6;
   __ Comment("Check number of STC inputs");
   __ LoadFromSlot(TypeTestABI::kScratchReg, TypeTestABI::kSubtypeTestCacheReg,
                   Slot::SubtypeTestCache_num_inputs());
-  __ CompareImmediate(TypeTestABI::kScratchReg, 3);
-  __ BranchIf(EQUAL, &call_3, Assembler::kNearJump);
-  __ CompareImmediate(TypeTestABI::kScratchReg, 5);
-  __ BranchIf(EQUAL, &call_5, Assembler::kNearJump);
+  __ CompareImmediate(TypeTestABI::kScratchReg, 2);
+  __ BranchIf(EQUAL, &call_2, Assembler::kNearJump);
+  __ CompareImmediate(TypeTestABI::kScratchReg, 4);
+  __ BranchIf(EQUAL, &call_4, Assembler::kNearJump);
+  __ CompareImmediate(TypeTestABI::kScratchReg, 6);
+  __ BranchIf(EQUAL, &call_6, Assembler::kNearJump);
 #if defined(DEBUG)
   // Verify we have the all inputs case.
   Label perform_check;
@@ -1122,20 +1124,30 @@
     __ Jump(&call_runtime, Assembler::kNearJump);
   }
 
-  __ Bind(&call_5);
+  __ Bind(&call_6);
   {
-    __ Comment("Call 5 input STC check");
-    __ Call(StubCodeSubtype5TestCache());
+    __ Comment("Call 6 input STC check");
+    __ Call(StubCodeSubtype6TestCache());
     __ CompareObject(TypeTestABI::kSubtypeTestCacheResultReg,
                      CastHandle<Object>(TrueObject()));
     __ BranchIf(EQUAL, &done);  // Cache said: yes.
     __ Jump(&call_runtime, Assembler::kNearJump);
   }
 
-  __ Bind(&call_3);
+  __ Bind(&call_4);
   {
-    __ Comment("Call 3 input STC check");
-    __ Call(StubCodeSubtype3TestCache());
+    __ Comment("Call 4 input STC check");
+    __ Call(StubCodeSubtype4TestCache());
+    __ CompareObject(TypeTestABI::kSubtypeTestCacheResultReg,
+                     CastHandle<Object>(TrueObject()));
+    __ BranchIf(EQUAL, &done);  // Cache said: yes.
+    __ Jump(&call_runtime, Assembler::kNearJump);
+  }
+
+  __ Bind(&call_2);
+  {
+    __ Comment("Call 2 input STC check");
+    __ Call(StubCodeSubtype2TestCache());
     __ CompareObject(TypeTestABI::kSubtypeTestCacheResultReg,
                      CastHandle<Object>(TrueObject()));
     __ BranchIf(EQUAL, &done);  // Cache said: yes.
@@ -2559,6 +2571,107 @@
 }
 
 #if !defined(TARGET_ARCH_IA32)
+static void GenerateSubtypeTestCacheLoop(Assembler* assembler,
+                                         int n,
+                                         Register null_reg,
+                                         Register cache_entry_reg,
+                                         Register instance_cid_or_sig_reg,
+                                         Register instance_type_args_reg,
+                                         Register parent_fun_type_args_reg,
+                                         Register delayed_type_args_reg,
+                                         Label* found,
+                                         Label* not_found,
+                                         Label* next_iteration) {
+  __ Comment("Loop");
+  // LoadAcquireCompressed assumes the loaded value is a heap object and
+  // extends it with the heap bits if compressed. However, the entry may be
+  // a Smi.
+  //
+  // Instead, just use LoadAcquire to load the lower bits when compressed and
+  // only compare the low bits of the loaded value using CompareObjectRegisters.
+  __ LoadAcquire(TypeTestABI::kScratchReg, cache_entry_reg,
+                 target::kCompressedWordSize *
+                     target::SubtypeTestCache::kInstanceCidOrSignature,
+                 kObjectBytes);
+  __ CompareObjectRegisters(TypeTestABI::kScratchReg, null_reg);
+  __ BranchIf(EQUAL, not_found, Assembler::kNearJump);
+  __ CompareObjectRegisters(TypeTestABI::kScratchReg, instance_cid_or_sig_reg);
+  if (n == 1) {
+    __ BranchIf(EQUAL, found, Assembler::kNearJump);
+    return;
+  }
+
+  __ BranchIf(NOT_EQUAL, next_iteration, Assembler::kNearJump);
+  __ CompareWithMemoryValue(
+      instance_type_args_reg,
+      Address(cache_entry_reg,
+              target::kCompressedWordSize *
+                  target::SubtypeTestCache::kInstanceTypeArguments),
+      kObjectBytes);
+  if (n == 2) {
+    __ BranchIf(EQUAL, found, Assembler::kNearJump);
+    return;
+  }
+
+  __ BranchIf(NOT_EQUAL, next_iteration, Assembler::kNearJump);
+  __ CompareWithMemoryValue(
+      TypeTestABI::kInstantiatorTypeArgumentsReg,
+      Address(cache_entry_reg,
+              target::kCompressedWordSize *
+                  target::SubtypeTestCache::kInstantiatorTypeArguments),
+      kObjectBytes);
+  if (n == 3) {
+    __ BranchIf(EQUAL, found, Assembler::kNearJump);
+    return;
+  }
+
+  __ BranchIf(NOT_EQUAL, next_iteration, Assembler::kNearJump);
+  __ CompareWithMemoryValue(
+      TypeTestABI::kFunctionTypeArgumentsReg,
+      Address(cache_entry_reg,
+              target::kCompressedWordSize *
+                  target::SubtypeTestCache::kFunctionTypeArguments),
+      kObjectBytes);
+  if (n == 4) {
+    __ BranchIf(EQUAL, found, Assembler::kNearJump);
+    return;
+  }
+
+  __ BranchIf(NOT_EQUAL, next_iteration, Assembler::kNearJump);
+  __ CompareWithMemoryValue(
+      parent_fun_type_args_reg,
+      Address(
+          cache_entry_reg,
+          target::kCompressedWordSize *
+              target::SubtypeTestCache::kInstanceParentFunctionTypeArguments),
+      kObjectBytes);
+  if (n == 5) {
+    __ BranchIf(EQUAL, found, Assembler::kNearJump);
+    return;
+  }
+
+  __ BranchIf(NOT_EQUAL, next_iteration, Assembler::kNearJump);
+  __ CompareWithMemoryValue(
+      delayed_type_args_reg,
+      Address(
+          cache_entry_reg,
+          target::kCompressedWordSize *
+              target::SubtypeTestCache::kInstanceDelayedFunctionTypeArguments),
+      kObjectBytes);
+  if (n == 6) {
+    __ BranchIf(EQUAL, found, Assembler::kNearJump);
+    return;
+  }
+
+  __ BranchIf(NOT_EQUAL, next_iteration, Assembler::kNearJump);
+  __ CompareWithMemoryValue(
+      TypeTestABI::kDstTypeReg,
+      Address(cache_entry_reg, target::kCompressedWordSize *
+                                   target::SubtypeTestCache::kDestinationType),
+      kObjectBytes);
+  __ BranchIf(EQUAL, found, Assembler::kNearJump);
+}
+
 void StubCodeCompiler::GenerateSubtypeTestCacheSearch(
     Assembler* assembler,
     int n,
@@ -2579,15 +2692,17 @@
   ASSERT(instance_cid_or_sig_reg != kNoRegister);
   ASSERT(!input_regs.ContainsRegister(instance_cid_or_sig_reg));
   input_regs.AddRegister(instance_cid_or_sig_reg);
-  if (n >= 3) {
+  if (n >= 2) {
     ASSERT(instance_type_args_reg != kNoRegister);
     ASSERT(!input_regs.ContainsRegister(instance_type_args_reg));
     input_regs.AddRegister(instance_type_args_reg);
   }
-  if (n >= 7) {
+  if (n >= 5) {
     ASSERT(parent_fun_type_args_reg != kNoRegister);
     ASSERT(!input_regs.ContainsRegister(parent_fun_type_args_reg));
     input_regs.AddRegister(parent_fun_type_args_reg);
+  }
+  if (n >= 6) {
     ASSERT(!input_regs.ContainsRegister(TypeTestABI::kInstanceReg));
     ASSERT(delayed_type_args_reg != kNoRegister);
     ASSERT(!input_regs.ContainsRegister(delayed_type_args_reg));
@@ -2595,11 +2710,21 @@
   } else {
     ASSERT(!input_regs.ContainsRegister(TypeTestABI::kInstanceReg));
   }
+  // We can allow the use of the registers below only if we're not expecting
+  // them as an inspected input.
+  if (n >= 3) {
+    ASSERT(!input_regs.ContainsRegister(
+        TypeTestABI::kInstantiatorTypeArgumentsReg));
+  }
+  if (n >= 4) {
+    ASSERT(
+        !input_regs.ContainsRegister(TypeTestABI::kFunctionTypeArgumentsReg));
+  }
+  if (n >= 7) {
+    ASSERT(!input_regs.ContainsRegister(TypeTestABI::kDstTypeReg));
+  }
+  // We use this as a scratch, so it has to be distinct from the others.
   ASSERT(!input_regs.ContainsRegister(TypeTestABI::kScratchReg));
-  ASSERT(!input_regs.ContainsRegister(TypeTestABI::kDstTypeReg));
-  ASSERT(
-      !input_regs.ContainsRegister(TypeTestABI::kInstantiatorTypeArgumentsReg));
-  ASSERT(!input_regs.ContainsRegister(TypeTestABI::kFunctionTypeArgumentsReg));
 #endif
   Label loop;
 
@@ -2617,15 +2742,24 @@
   // TODO(sstrickl): Handle hash-based tables in the stub and load the first
   // entry to check here instead of generating a false negative.
   __ BranchIf(GREATER, not_found);
-  __ AddImmediate(
-      cache_entry_reg,
-      target::Array::data_offset() - kHeapObjectTag +
-          target::kCompressedWordSize * target::SubtypeTestCache::kHeaderSize);
+  __ AddImmediate(cache_entry_reg,
+                  target::Array::data_offset() - kHeapObjectTag);
 
   Label not_closure;
-  if (n >= 5) {
+  if (n >= 4) {
     __ LoadClassIdMayBeSmi(instance_cid_or_sig_reg, TypeTestABI::kInstanceReg);
   } else {
+    // If the type is fully instantiated, then it can be determined at compile
+    // time whether Smi is a subtype of the type or not. Thus, this code should
+    // never be called with a Smi instance.
+#if defined(DEBUG)
+    // Double-check this in DEBUG mode, instead of getting a segfault.
+    Label not_smi;
+    __ BranchIfNotSmi(TypeTestABI::kInstanceReg, &not_smi,
+                      Assembler::kNearJump);
+    __ Breakpoint();
+    __ Bind(&not_smi);
+#endif
     __ LoadClassId(instance_cid_or_sig_reg, TypeTestABI::kInstanceReg);
   }
   __ CompareImmediate(instance_cid_or_sig_reg, kClosureCid);
@@ -2640,22 +2774,25 @@
     __ LoadCompressed(instance_cid_or_sig_reg,
                       FieldAddress(instance_cid_or_sig_reg,
                                    target::Function::signature_offset()));
-    if (n >= 3) {
+    if (n >= 2) {
       __ LoadCompressed(
           instance_type_args_reg,
           FieldAddress(TypeTestABI::kInstanceReg,
                        target::Closure::instantiator_type_arguments_offset()));
-      if (n >= 7) {
-        __ LoadCompressed(
-            parent_fun_type_args_reg,
-            FieldAddress(TypeTestABI::kInstanceReg,
-                         target::Closure::function_type_arguments_offset()));
-        __ LoadCompressed(
-            delayed_type_args_reg,
-            FieldAddress(TypeTestABI::kInstanceReg,
-                         target::Closure::delayed_type_arguments_offset()));
-      }
     }
+    if (n >= 5) {
+      __ LoadCompressed(
+          parent_fun_type_args_reg,
+          FieldAddress(TypeTestABI::kInstanceReg,
+                       target::Closure::function_type_arguments_offset()));
+    }
+    if (n >= 6) {
+      __ LoadCompressed(
+          delayed_type_args_reg,
+          FieldAddress(TypeTestABI::kInstanceReg,
+                       target::Closure::delayed_type_arguments_offset()));
+    }
+
     __ Jump(&loop, Assembler::kNearJump);
   }
 
@@ -2663,7 +2800,7 @@
   {
     __ Comment("Non-Closure");
     __ Bind(&not_closure);
-    if (n >= 3) {
+    if (n >= 2) {
       Label has_no_type_arguments;
       __ LoadClassById(TypeTestABI::kScratchReg, instance_cid_or_sig_reg);
       __ MoveRegister(instance_type_args_reg, null_reg);
@@ -2679,92 +2816,22 @@
                                TypeTestABI::kScratchReg);
       __ Bind(&has_no_type_arguments);
       __ Comment("No type arguments");
-
-      if (n >= 7) {
-        __ MoveRegister(parent_fun_type_args_reg, null_reg);
-        __ MoveRegister(delayed_type_args_reg, null_reg);
-      }
     }
     __ SmiTag(instance_cid_or_sig_reg);
+    if (n >= 5) {
+      __ MoveRegister(parent_fun_type_args_reg, null_reg);
+    }
+    if (n >= 6) {
+      __ MoveRegister(delayed_type_args_reg, null_reg);
+    }
   }
 
   Label next_iteration, found;
   __ Bind(&loop);
-  __ Comment("Loop");
-  // LoadAcquireCompressed assumes the loaded value is a heap object and
-  // extends it with the heap bits if compressed. However, the entry may be
-  // a Smi.
-  //
-  // Instead, just use LoadAcquire to load the lower bits when compressed and
-  // only compare the low bits of the loaded value using CompareObjectRegisters.
-  __ LoadAcquire(TypeTestABI::kScratchReg, cache_entry_reg,
-                 target::kCompressedWordSize *
-                     target::SubtypeTestCache::kInstanceCidOrSignature,
-                 kObjectBytes);
-  __ CompareObjectRegisters(TypeTestABI::kScratchReg, null_reg);
-  __ BranchIf(EQUAL, not_found, Assembler::kNearJump);
-  __ CompareObjectRegisters(TypeTestABI::kScratchReg, instance_cid_or_sig_reg);
-  if (n == 1) {
-    __ BranchIf(EQUAL, &found, Assembler::kNearJump);
-  } else {
-    __ BranchIf(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
-    __ CompareWithMemoryValue(
-        TypeTestABI::kDstTypeReg,
-        Address(cache_entry_reg,
-                target::kCompressedWordSize *
-                    target::SubtypeTestCache::kDestinationType),
-        kObjectBytes);
-    __ BranchIf(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
-    __ CompareWithMemoryValue(
-        instance_type_args_reg,
-        Address(cache_entry_reg,
-                target::kCompressedWordSize *
-                    target::SubtypeTestCache::kInstanceTypeArguments),
-        kObjectBytes);
-    if (n == 3) {
-      __ BranchIf(EQUAL, &found, Assembler::kNearJump);
-    } else {
-      __ BranchIf(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
-      __ CompareWithMemoryValue(
-          TypeTestABI::kInstantiatorTypeArgumentsReg,
-          Address(cache_entry_reg,
-                  target::kCompressedWordSize *
-                      target::SubtypeTestCache::kInstantiatorTypeArguments),
-          kObjectBytes);
-      __ BranchIf(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
-      __ CompareWithMemoryValue(
-          TypeTestABI::kFunctionTypeArgumentsReg,
-          Address(cache_entry_reg,
-                  target::kCompressedWordSize *
-                      target::SubtypeTestCache::kFunctionTypeArguments),
-          kObjectBytes);
-
-      if (n == 5) {
-        __ BranchIf(EQUAL, &found, Assembler::kNearJump);
-      } else {
-        ASSERT(n == 7);
-        __ BranchIf(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
-
-        __ CompareWithMemoryValue(
-            parent_fun_type_args_reg,
-            Address(cache_entry_reg,
-                    target::kCompressedWordSize *
-                        target::SubtypeTestCache::
-                            kInstanceParentFunctionTypeArguments),
-            kObjectBytes);
-        __ BranchIf(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
-        __ CompareWithMemoryValue(
-            delayed_type_args_reg,
-            Address(cache_entry_reg,
-                    target::kCompressedWordSize *
-                        target::SubtypeTestCache::
-                            kInstanceDelayedFunctionTypeArguments),
-            kObjectBytes);
-        __ BranchIf(EQUAL, &found, Assembler::kNearJump);
-      }
-    }
-  }
-
+  GenerateSubtypeTestCacheLoop(assembler, n, null_reg, cache_entry_reg,
+                               instance_cid_or_sig_reg, instance_type_args_reg,
+                               parent_fun_type_args_reg, delayed_type_args_reg,
+                               &found, not_found, &next_iteration);
   __ Bind(&next_iteration);
   __ Comment("Next iteration");
   __ AddImmediate(
@@ -2776,6 +2843,31 @@
 }
 #endif
 
+// See comment on [GenerateSubtypeNTestCacheStub].
+void StubCodeCompiler::GenerateSubtype1TestCacheStub() {
+  GenerateSubtypeNTestCacheStub(assembler, 1);
+}
+
+// See comment on [GenerateSubtypeNTestCacheStub].
+void StubCodeCompiler::GenerateSubtype2TestCacheStub() {
+  GenerateSubtypeNTestCacheStub(assembler, 2);
+}
+
+// See comment on [GenerateSubtypeNTestCacheStub].
+void StubCodeCompiler::GenerateSubtype4TestCacheStub() {
+  GenerateSubtypeNTestCacheStub(assembler, 4);
+}
+
+// See comment on [GenerateSubtypeNTestCacheStub].
+void StubCodeCompiler::GenerateSubtype6TestCacheStub() {
+  GenerateSubtypeNTestCacheStub(assembler, 6);
+}
+
+// See comment on [GenerateSubtypeNTestCacheStub].
+void StubCodeCompiler::GenerateSubtype7TestCacheStub() {
+  GenerateSubtypeNTestCacheStub(assembler, 7);
+}
+
 }  // namespace compiler
 
 }  // namespace dart
diff --git a/runtime/vm/compiler/stub_code_compiler.h b/runtime/vm/compiler/stub_code_compiler.h
index 39a853e..c0e369d 100644
--- a/runtime/vm/compiler/stub_code_compiler.h
+++ b/runtime/vm/compiler/stub_code_compiler.h
@@ -119,6 +119,7 @@
   // `StubCode::*<stub-name>Shared{With,Without}FpuRegsStub()`
   static intptr_t WordOffsetFromFpToCpuRegister(Register cpu_register);
 
+ private:
 #if !defined(TARGET_ARCH_IA32)
   // Generates the code for searching a subtype test cache for an entry that
   // matches the contents of the TypeTestABI registers. If no matching
@@ -126,29 +127,31 @@
   // continues immediately after the loop and [cache_entry_reg] points to
   // the start of the matching cache entry.
   //
-  // The following registers must be provided, that is, they cannot be
-  // kNoRegister for any [n]:
-  // - null_reg
-  // - cache_entry_reg
-  // - instance_cid_or_sig_reg
+  // The following registers from TypeTestABI are inputs under the following
+  // conditions:
+  // - kScratchReg: always
+  // - kInstanceReg: always
+  // - kDstTypeReg: [n] >= 3
+  // - kInstantiatorTypeArgumentsReg: [n] >= 4
+  // - kFunctionTypeArgumentsReg: [n] >= 5
   //
-  // The following registers must be provided for [n] >= 3:
-  // - instance_type_args_reg
+  // Has the following input registers in addition to those in TypeTestABI:
+  // - null_reg: contains the ObjectPtr for Object::null()
+  // - cache_entry_reg: contains the ArrayPtr for the backing array of the STC
   //
-  // The following registers must be provided for [n] >= 7:
-  // - parent_fun_type_args_reg
-  // - delayed_type_args_reg
+  // The following registers must be provided for the given conditions and
+  // are clobbered:
+  // - instance_cid_or_sig_reg: always
+  // - instance_type_args_reg: [n] >= 2
+  // - parent_fun_type_args_reg: [n] >= 6
+  // - delayed_type_args_reg: [n] >= 7
   //
-  // All provided registers must be distinct, and in addition, all provided
-  // registers must be distinct from the following TypeTestABI registers:
-  // - kScratchReg
-  // - kDstTypeReg
-  // - kInstantiatorTypeArgumentsReg
-  // - kFunctionTypeArgumentsReg
+  // Note that all input registers must be distinct, except for the case
+  // of kInstanceReg and [delayed_type_args_reg], which are allowed to overlap.
   //
-  // and all but [delayed_type_args_reg] must be distinct from the following
-  // TypeTestABI register:
-  // - kInstanceReg
+  // Also note that if any non-TypeTestABI registers overlap with any
+  // non-scratch TypeTestABI registers, the original value of the TypeTestABI
+  // register must be restored afterwards.
   static void GenerateSubtypeTestCacheSearch(Assembler* assembler,
                                              int n,
                                              Register null_reg,
@@ -160,7 +163,10 @@
                                              Label* not_found);
 #endif
 
- private:
+  // Common function for generating the different SubtypeTestCache search
+  // stubs. Check architecture-specific version for inputs/outputs.
+  static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n);
+
   // Common function for generating InitLateStaticField and
   // InitLateFinalStaticField stubs.
   void GenerateInitLateStaticFieldStub(bool is_final);
diff --git a/runtime/vm/compiler/stub_code_compiler_arm.cc b/runtime/vm/compiler/stub_code_compiler_arm.cc
index def834f..4b752dd 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm.cc
@@ -2689,15 +2689,16 @@
 // Inputs (all preserved, mostly from TypeTestABI struct):
 //   - kSubtypeTestCacheReg: SubtypeTestCacheLayout
 //   - kInstanceReg: instance to test against.
-//   - kDstTypeReg: destination type (for n>=3).
-//   - kInstantiatorTypeArgumentsReg: instantiator type arguments (for n=5).
-//   - kFunctionTypeArgumentsReg: function type arguments (for n=5).
+//   - kDstTypeReg: destination type (for n>=7).
+//   - kInstantiatorTypeArgumentsReg: instantiator type arguments (for n>=3).
+//   - kFunctionTypeArgumentsReg: function type arguments (for n>=4).
 //   - LR: return address.
 //
 // Outputs (from TypeTestABI struct):
 //   - kSubtypeTestCacheResultReg: the cached result, or null if not found.
-static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
-  ASSERT(n == 1 || n == 3 || n == 5 || n == 7);
+void StubCodeCompiler::GenerateSubtypeNTestCacheStub(Assembler* assembler,
+                                                     int n) {
+  ASSERT(n == 1 || n == 2 || n == 4 || n == 6 || n == 7);
   RegisterSet saved_registers;
 
   // Safe as the original value of TypeTestABI::kSubtypeTestCacheReg is only
@@ -2705,28 +2706,28 @@
   const Register kCacheArrayReg = TypeTestABI::kSubtypeTestCacheReg;
   saved_registers.AddRegister(kCacheArrayReg);
 
-  // Registers that are only used for n >= 3 and must be preserved if used.
-  Register kInstanceInstantiatorTypeArgumentsReg = kNoRegister;
-  // Registers that are only used for n >= 7 and must be preserved if used.
-  Register kInstanceParentFunctionTypeArgumentsReg = kNoRegister;
-  Register kInstanceDelayedFunctionTypeArgumentsReg = kNoRegister;
-
   // NOTFP must be preserved for bare payloads, otherwise CODE_REG.
   const bool use_bare_payloads = FLAG_precompiled_mode;
   // For this, we choose the register that need not be preserved of the pair.
   const Register kNullReg = use_bare_payloads ? CODE_REG : NOTFP;
   __ LoadObject(kNullReg, NullObject());
 
-  // Free up registers to be used to store values checked in the loop.
-  if (n >= 3) {
+  // Free up additional registers needed for checks in the loop. Initially
+  // define them as kNoRegister so any unexpected uses are caught.
+  Register kInstanceInstantiatorTypeArgumentsReg = kNoRegister;
+  if (n >= 2) {
     kInstanceInstantiatorTypeArgumentsReg = PP;
     saved_registers.AddRegister(kInstanceInstantiatorTypeArgumentsReg);
   }
-  if (n >= 7) {
+  Register kInstanceParentFunctionTypeArgumentsReg = kNoRegister;
+  if (n >= 5) {
     // For this, we choose the register that must be preserved of the pair.
     kInstanceParentFunctionTypeArgumentsReg =
         use_bare_payloads ? NOTFP : CODE_REG;
     saved_registers.AddRegister(kInstanceParentFunctionTypeArgumentsReg);
+  }
+  Register kInstanceDelayedFunctionTypeArgumentsReg = kNoRegister;
+  if (n >= 6) {
     // We retrieve all the needed fields from the instance during loop
     // initialization and store them in registers, so we don't need the value
     // of kInstanceReg during the loop and just need to save and restore it.
@@ -2738,12 +2739,12 @@
   __ PushRegisters(saved_registers);
 
   Label not_found;
-  StubCodeCompiler::GenerateSubtypeTestCacheSearch(
-      assembler, n, kNullReg, kCacheArrayReg,
-      STCInternalRegs::kInstanceCidOrSignatureReg,
-      kInstanceInstantiatorTypeArgumentsReg,
-      kInstanceParentFunctionTypeArgumentsReg,
-      kInstanceDelayedFunctionTypeArgumentsReg, &not_found);
+  GenerateSubtypeTestCacheSearch(assembler, n, kNullReg, kCacheArrayReg,
+                                 STCInternalRegs::kInstanceCidOrSignatureReg,
+                                 kInstanceInstantiatorTypeArgumentsReg,
+                                 kInstanceParentFunctionTypeArgumentsReg,
+                                 kInstanceDelayedFunctionTypeArgumentsReg,
+                                 &not_found);
 
   __ Comment("Found");
   __ LoadCompressed(
@@ -2760,26 +2761,6 @@
   __ Ret();
 }
 
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype1TestCacheStub() {
-  GenerateSubtypeNTestCacheStub(assembler, 1);
-}
-
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype3TestCacheStub() {
-  GenerateSubtypeNTestCacheStub(assembler, 3);
-}
-
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype5TestCacheStub() {
-  GenerateSubtypeNTestCacheStub(assembler, 5);
-}
-
-// See comment on[GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype7TestCacheStub() {
-  GenerateSubtypeNTestCacheStub(assembler, 7);
-}
-
 // Return the current stack pointer address, used to do stack alignment checks.
 void StubCodeCompiler::GenerateGetCStackPointerStub() {
   __ mov(R0, Operand(SP));
diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc
index 97ba42f..cb559d1 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc
@@ -3006,15 +3006,16 @@
 // Inputs (all preserved, mostly from TypeTestABI struct):
 //   - kSubtypeTestCacheReg: UntaggedSubtypeTestCache
 //   - kInstanceReg: instance to test against.
-//   - kDstTypeReg: destination type (for n>=3).
-//   - kInstantiatorTypeArgumentsReg: instantiator type arguments (for n=5).
-//   - kFunctionTypeArgumentsReg: function type arguments (for n=5).
+//   - kDstTypeReg: destination type (for n>=7).
+//   - kInstantiatorTypeArgumentsReg: instantiator type arguments (for n>=3).
+//   - kFunctionTypeArgumentsReg: function type arguments (for n>=4).
 //   - LR: return address.
 //
 // Outputs (from TypeTestABI struct):
 //   - kSubtypeTestCacheResultReg: the cached result, or null if not found.
-static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
-  ASSERT(n == 1 || n == 3 || n == 5 || n == 7);
+void StubCodeCompiler::GenerateSubtypeNTestCacheStub(Assembler* assembler,
+                                                     int n) {
+  ASSERT(n == 1 || n == 2 || n == 4 || n == 6 || n == 7);
 
   // We could initialize kSubtypeTestCacheResultReg with null and use that as
   // the null register up until exit, which means we'd just need to return
@@ -3030,7 +3031,7 @@
   const Register kCacheArrayReg = TypeTestABI::kSubtypeTestCacheResultReg;
 
   Label not_found;
-  StubCodeCompiler::GenerateSubtypeTestCacheSearch(
+  GenerateSubtypeTestCacheSearch(
       assembler, n, NULL_REG, kCacheArrayReg,
       STCInternalRegs::kInstanceCidOrSignatureReg,
       STCInternalRegs::kInstanceInstantiatorTypeArgumentsReg,
@@ -3050,26 +3051,6 @@
   __ Ret();
 }
 
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype1TestCacheStub() {
-  GenerateSubtypeNTestCacheStub(assembler, 1);
-}
-
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype3TestCacheStub() {
-  GenerateSubtypeNTestCacheStub(assembler, 3);
-}
-
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype5TestCacheStub() {
-  GenerateSubtypeNTestCacheStub(assembler, 5);
-}
-
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype7TestCacheStub() {
-  GenerateSubtypeNTestCacheStub(assembler, 7);
-}
-
 void StubCodeCompiler::GenerateGetCStackPointerStub() {
   __ mov(R0, CSP);
   __ ret();
diff --git a/runtime/vm/compiler/stub_code_compiler_ia32.cc b/runtime/vm/compiler/stub_code_compiler_ia32.cc
index 6523a7d..9fd1a9f 100644
--- a/runtime/vm/compiler/stub_code_compiler_ia32.cc
+++ b/runtime/vm/compiler/stub_code_compiler_ia32.cc
@@ -2310,11 +2310,132 @@
 #endif  // defined(PRODUCT)
 }
 
+// Constants used for generating subtype test cache lookup stubs.
+// We represent the depth of as a depth from the top of the stack at the
+// start of the stub. That is, depths for input values are non-negative and
+// depths for values pushed during the stub are negative.
+
+struct STCInternal : AllStatic {
+  // Used to initialize depths for conditionally-pushed values.
+  static constexpr intptr_t kNoDepth = kIntptrMin;
+
+  // These inputs are always on the stack when the SubtypeNTestCacheStub is
+  // called. These absolute depths will be converted to relative depths within
+  // the stub to compensate for additional pushed values.
+  static constexpr intptr_t kFunctionTypeArgumentsDepth = 1;
+  static constexpr intptr_t kInstantiatorTypeArgumentsDepth = 2;
+  static constexpr intptr_t kDestinationTypeDepth = 3;
+  static constexpr intptr_t kInstanceDepth = 4;
+  static constexpr intptr_t kCacheDepth = 5;
+
+  // Non-stack values are stored in non-kInstanceReg registers from TypeTestABI.
+  static constexpr Register kCacheArrayReg =
+      TypeTestABI::kInstantiatorTypeArgumentsReg;
+  static constexpr Register kScratchReg = TypeTestABI::kSubtypeTestCacheReg;
+  static constexpr Register kInstanceCidOrSignatureReg =
+      TypeTestABI::kFunctionTypeArgumentsReg;
+  static constexpr Register kInstanceInstantiatorTypeArgumentsReg =
+      TypeTestABI::kDstTypeReg;
+};
+
+static void GenerateSubtypeTestCacheLoop(
+    Assembler* assembler,
+    int n,
+    intptr_t original_tos_offset,
+    intptr_t parent_function_type_args_depth,
+    intptr_t delayed_type_args_depth,
+    Label* found,
+    Label* not_found,
+    Label* next_iteration) {
+  const auto& raw_null = Immediate(target::ToRawPointer(NullObject()));
+
+  // Compares a value at the given depth from the stack to the value in src.
+  auto compare_to_stack = [&](Register src, intptr_t depth) {
+    ASSERT(original_tos_offset + depth >= 0);
+    __ CompareToStack(src, original_tos_offset + depth);
+  };
+
+  __ LoadAcquireCompressed(
+      STCInternal::kScratchReg, STCInternal::kCacheArrayReg,
+      target::kCompressedWordSize *
+          target::SubtypeTestCache::kInstanceCidOrSignature);
+  __ cmpl(STCInternal::kScratchReg, raw_null);
+  __ j(EQUAL, not_found, Assembler::kNearJump);
+  __ cmpl(STCInternal::kScratchReg, STCInternal::kInstanceCidOrSignatureReg);
+  if (n == 1) {
+    __ j(EQUAL, found, Assembler::kNearJump);
+    return;
+  }
+  __ j(NOT_EQUAL, next_iteration, Assembler::kNearJump);
+  __ cmpl(STCInternal::kInstanceInstantiatorTypeArgumentsReg,
+          Address(STCInternal::kCacheArrayReg,
+                  target::kWordSize *
+                      target::SubtypeTestCache::kInstanceTypeArguments));
+  if (n == 2) {
+    __ j(EQUAL, found, Assembler::kNearJump);
+    return;
+  }
+  __ j(NOT_EQUAL, next_iteration, Assembler::kNearJump);
+  __ movl(STCInternal::kScratchReg,
+          Address(STCInternal::kCacheArrayReg,
+                  target::kWordSize *
+                      target::SubtypeTestCache::kInstantiatorTypeArguments));
+  compare_to_stack(STCInternal::kScratchReg,
+                   STCInternal::kInstantiatorTypeArgumentsDepth);
+  if (n == 3) {
+    __ j(EQUAL, found, Assembler::kNearJump);
+    return;
+  }
+  __ j(NOT_EQUAL, next_iteration, Assembler::kNearJump);
+  __ movl(STCInternal::kScratchReg,
+          Address(STCInternal::kCacheArrayReg,
+                  target::kWordSize *
+                      target::SubtypeTestCache::kFunctionTypeArguments));
+  compare_to_stack(STCInternal::kScratchReg,
+                   STCInternal::kFunctionTypeArgumentsDepth);
+  if (n == 4) {
+    __ j(EQUAL, found, Assembler::kNearJump);
+    return;
+  }
+  __ j(NOT_EQUAL, next_iteration, Assembler::kNearJump);
+  __ movl(
+      STCInternal::kScratchReg,
+      Address(
+          STCInternal::kCacheArrayReg,
+          target::kWordSize *
+              target::SubtypeTestCache::kInstanceParentFunctionTypeArguments));
+  compare_to_stack(STCInternal::kScratchReg, parent_function_type_args_depth);
+  if (n == 5) {
+    __ j(EQUAL, found, Assembler::kNearJump);
+    return;
+  }
+  __ j(NOT_EQUAL, next_iteration, Assembler::kNearJump);
+  __ movl(
+      STCInternal::kScratchReg,
+      Address(
+          STCInternal::kCacheArrayReg,
+          target::kWordSize *
+              target::SubtypeTestCache::kInstanceDelayedFunctionTypeArguments));
+  compare_to_stack(STCInternal::kScratchReg, delayed_type_args_depth);
+  if (n == 6) {
+    __ j(EQUAL, found, Assembler::kNearJump);
+    return;
+  }
+  __ j(NOT_EQUAL, next_iteration, Assembler::kNearJump);
+  __ movl(
+      STCInternal::kScratchReg,
+      Address(STCInternal::kCacheArrayReg,
+              target::kWordSize * target::SubtypeTestCache::kDestinationType));
+  compare_to_stack(STCInternal::kScratchReg,
+                   STCInternal::kDestinationTypeDepth);
+  __ j(EQUAL, found, Assembler::kNearJump);
+}
+
 // Used to check class and type arguments. Arguments passed on stack:
 // TOS + 0: return address.
-// TOS + 1: function type arguments (only if n == 4, can be raw_null).
-// TOS + 2: instantiator type arguments (only if n == 4, can be raw_null).
-// TOS + 3: destination_type (only used if n >= 3).
+// TOS + 1: function type arguments (only used if n >= 4, can be raw_null).
+// TOS + 2: instantiator type arguments (only used if n >= 3, can be raw_null).
+// TOS + 3: destination_type (only used if n >= 7).
 // TOS + 4: instance.
 // TOS + 5: SubtypeTestCache.
 //
@@ -2322,107 +2443,73 @@
 //
 // Result in SubtypeTestCacheReg::kResultReg: null -> not found, otherwise
 // result (true or false).
-static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
-  ASSERT(n == 1 || n == 3 || n == 5 || n == 7);
-
-  // We represent the depth of as a depth from the top of the stack at the
-  // start of the stub. That is, depths for input values are non-negative and
-  // depths for values pushed during the stub are negative.
-
-  // Used to initialize depths for conditionally-pushed values.
-  const intptr_t kNoDepth = kIntptrMin;
-  // Offset of the original top of the stack from the current top of stack.
-  intptr_t original_tos_offset = 0;
-
-  // Inputs use relative depths.
-  static constexpr intptr_t kFunctionTypeArgumentsDepth = 1;
-  static constexpr intptr_t kInstantiatorTypeArgumentsDepth = 2;
-  static constexpr intptr_t kDestinationTypeDepth = 3;
-  static constexpr intptr_t kInstanceDepth = 4;
-  static constexpr intptr_t kCacheDepth = 5;
-  // Others use absolute depths. We initialize conditionally pushed values to
-  // kNoInput for extra checking.
-  intptr_t kInstanceParentFunctionTypeArgumentsDepth = kNoDepth;
-  intptr_t kInstanceDelayedFunctionTypeArgumentsDepth = kNoDepth;
-
-  // Other values are stored in non-kInstanceReg registers from TypeTestABI.
-  const Register kCacheArrayReg = TypeTestABI::kInstantiatorTypeArgumentsReg;
-  const Register kScratchReg = TypeTestABI::kSubtypeTestCacheReg;
-  const Register kInstanceCidOrSignature =
-      TypeTestABI::kFunctionTypeArgumentsReg;
-  const Register kInstanceInstantiatorTypeArgumentsReg =
-      TypeTestABI::kDstTypeReg;
-
-  // Loads a value at the given depth from the stack into dst.
-  auto load_from_stack = [&](Register dst, intptr_t depth) {
-    ASSERT(depth != kNoDepth);
-    __ LoadFromStack(dst, original_tos_offset + depth);
-  };
-
-  // Compares a value at the given depth from the stack to the value in src.
-  auto compare_to_stack = [&](Register src, intptr_t depth) {
-    ASSERT(depth != kNoDepth);
-    __ CompareToStack(src, original_tos_offset + depth);
-  };
+void StubCodeCompiler::GenerateSubtypeNTestCacheStub(Assembler* assembler,
+                                                     int n) {
+  ASSERT(n == 1 || n == 2 || n == 4 || n == 6 || n == 7);
 
   const auto& raw_null = Immediate(target::ToRawPointer(NullObject()));
 
-  load_from_stack(TypeTestABI::kInstanceReg, kInstanceDepth);
+  __ LoadFromStack(TypeTestABI::kInstanceReg, STCInternal::kInstanceDepth);
 
   // Loop initialization (moved up here to avoid having all dependent loads
   // after each other)
-  load_from_stack(kCacheArrayReg, kCacheDepth);
+  __ LoadFromStack(STCInternal::kCacheArrayReg, STCInternal::kCacheDepth);
   // We avoid a load-acquire barrier here by relying on the fact that all other
   // loads from the array are data-dependent loads.
-  __ movl(
-      kCacheArrayReg,
-      FieldAddress(kCacheArrayReg, target::SubtypeTestCache::cache_offset()));
+  __ movl(STCInternal::kCacheArrayReg,
+          FieldAddress(STCInternal::kCacheArrayReg,
+                       target::SubtypeTestCache::cache_offset()));
 
   // There is a maximum size for linear caches that is smaller than the size
   // of any hash-based cache, so we check the size of the backing array to
   // determine if this is a linear or hash-based cache.
-  __ LoadFromSlot(kScratchReg, kCacheArrayReg, Slot::Array_length());
-  __ CompareImmediate(kScratchReg,
+  __ LoadFromSlot(STCInternal::kScratchReg, STCInternal::kCacheArrayReg,
+                  Slot::Array_length());
+  __ CompareImmediate(STCInternal::kScratchReg,
                       target::ToRawSmi(SubtypeTestCache::kMaxLinearCacheSize));
-  Label not_found_before_push;
   // For IA32, we never handle hash caches in the stub, as there's too much
   // register pressure.
-  __ BranchIf(GREATER, &not_found_before_push);
-  __ AddImmediate(
-      kCacheArrayReg,
-      target::Array::data_offset() - kHeapObjectTag +
-          target::kCompressedWordSize * target::SubtypeTestCache::kHeaderSize);
+  Label is_linear;
+  __ BranchIf(LESS_EQUAL, &is_linear, Assembler::kNearJump);
+  // Return null so that we'll continue to the runtime for hash-based caches.
+  __ movl(TypeTestABI::kSubtypeTestCacheResultReg, raw_null);
+  __ ret();
+  __ Bind(&is_linear);
+  __ AddImmediate(STCInternal::kCacheArrayReg,
+                  target::Array::data_offset() - kHeapObjectTag);
 
   Label loop, not_closure;
-  if (n >= 5) {
-    __ LoadClassIdMayBeSmi(kInstanceCidOrSignature, TypeTestABI::kInstanceReg);
+  if (n >= 4) {
+    __ LoadClassIdMayBeSmi(STCInternal::kInstanceCidOrSignatureReg,
+                           TypeTestABI::kInstanceReg);
   } else {
-    __ LoadClassId(kInstanceCidOrSignature, TypeTestABI::kInstanceReg);
+    __ LoadClassId(STCInternal::kInstanceCidOrSignatureReg,
+                   TypeTestABI::kInstanceReg);
   }
-  __ cmpl(kInstanceCidOrSignature, Immediate(kClosureCid));
+  __ cmpl(STCInternal::kInstanceCidOrSignatureReg, Immediate(kClosureCid));
   __ j(NOT_EQUAL, &not_closure, Assembler::kNearJump);
 
   // Closure handling.
   {
-    __ movl(kInstanceCidOrSignature,
+    __ movl(STCInternal::kInstanceCidOrSignatureReg,
             FieldAddress(TypeTestABI::kInstanceReg,
                          target::Closure::function_offset()));
-    __ movl(kInstanceCidOrSignature,
-            FieldAddress(kInstanceCidOrSignature,
+    __ movl(STCInternal::kInstanceCidOrSignatureReg,
+            FieldAddress(STCInternal::kInstanceCidOrSignatureReg,
                          target::Function::signature_offset()));
-    if (n >= 3) {
+    if (n >= 2) {
       __ movl(
-          kInstanceInstantiatorTypeArgumentsReg,
+          STCInternal::kInstanceInstantiatorTypeArgumentsReg,
           FieldAddress(TypeTestABI::kInstanceReg,
                        target::Closure::instantiator_type_arguments_offset()));
-      if (n >= 7) {
-        __ pushl(
-            FieldAddress(TypeTestABI::kInstanceReg,
-                         target::Closure::delayed_type_arguments_offset()));
-        __ pushl(
-            FieldAddress(TypeTestABI::kInstanceReg,
-                         target::Closure::function_type_arguments_offset()));
-      }
+    }
+    if (n >= 5) {
+      __ pushl(FieldAddress(TypeTestABI::kInstanceReg,
+                            target::Closure::function_type_arguments_offset()));
+    }
+    if (n >= 6) {
+      __ pushl(FieldAddress(TypeTestABI::kInstanceReg,
+                            target::Closure::delayed_type_arguments_offset()));
     }
     __ jmp(&loop, Assembler::kNearJump);
   }
@@ -2430,127 +2517,82 @@
   // Non-Closure handling.
   {
     __ Bind(&not_closure);
-    if (n >= 3) {
+    if (n >= 2) {
       Label has_no_type_arguments;
-      __ LoadClassById(kScratchReg, kInstanceCidOrSignature);
-      __ movl(kInstanceInstantiatorTypeArgumentsReg, raw_null);
+      __ LoadClassById(STCInternal::kScratchReg,
+                       STCInternal::kInstanceCidOrSignatureReg);
+      __ movl(STCInternal::kInstanceInstantiatorTypeArgumentsReg, raw_null);
       __ movl(
-          kScratchReg,
-          FieldAddress(kScratchReg,
+          STCInternal::kScratchReg,
+          FieldAddress(STCInternal::kScratchReg,
                        target::Class::
                            host_type_arguments_field_offset_in_words_offset()));
-      __ cmpl(kScratchReg, Immediate(target::Class::kNoTypeArguments));
+      __ cmpl(STCInternal::kScratchReg,
+              Immediate(target::Class::kNoTypeArguments));
       __ j(EQUAL, &has_no_type_arguments, Assembler::kNearJump);
-      __ movl(kInstanceInstantiatorTypeArgumentsReg,
-              FieldAddress(TypeTestABI::kInstanceReg, kScratchReg, TIMES_4, 0));
+      __ movl(STCInternal::kInstanceInstantiatorTypeArgumentsReg,
+              FieldAddress(TypeTestABI::kInstanceReg, STCInternal::kScratchReg,
+                           TIMES_4, 0));
       __ Bind(&has_no_type_arguments);
-
-      if (n >= 7) {
-        __ pushl(raw_null);  // delayed.
-        __ pushl(raw_null);  // function.
-      }
     }
-    __ SmiTag(kInstanceCidOrSignature);
+    __ SmiTag(STCInternal::kInstanceCidOrSignatureReg);
+    if (n >= 5) {
+      __ pushl(raw_null);  // parent function.
+    }
+    if (n >= 6) {
+      __ pushl(raw_null);  // delayed.
+    }
   }
 
-  if (n >= 7) {
-    // Now that instance handling is done, both the delayed and parent function
-    // type arguments stack slots have been set, so any input uses must be
-    // offset by the new values and the new values can now be accessed in
-    // the following code without issue when n >= 6.
-    original_tos_offset = 2;
-    kInstanceDelayedFunctionTypeArgumentsDepth = -1;
-    kInstanceParentFunctionTypeArgumentsDepth = -2;
+  // Offset of the original top of the stack from the current top of stack.
+  intptr_t original_tos_offset = 0;
+
+  // Additional data conditionally stored on the stack use negative depths
+  // that will be non-negative when adjusted for original_tos_offset. We
+  // initialize conditionally pushed values to kNoInput for extra checking.
+  intptr_t kInstanceParentFunctionTypeArgumentsDepth = STCInternal::kNoDepth;
+  intptr_t kInstanceDelayedFunctionTypeArgumentsDepth = STCInternal::kNoDepth;
+
+  // Now that instance handling is done, both the delayed and parent function
+  // type arguments stack slots have been set, so any input uses must be
+  // offset by the new values and the new values can now be accessed in
+  // the following code without issue when n >= 6.
+  if (n >= 5) {
+    original_tos_offset++;
+    kInstanceParentFunctionTypeArgumentsDepth = -original_tos_offset;
+  }
+  if (n >= 6) {
+    original_tos_offset++;
+    kInstanceDelayedFunctionTypeArgumentsDepth = -original_tos_offset;
   }
 
   Label found, not_found, done, next_iteration;
 
   // Loop header.
   __ Bind(&loop);
-  __ LoadAcquireCompressed(
-      kScratchReg, kCacheArrayReg,
-      target::kCompressedWordSize *
-          target::SubtypeTestCache::kInstanceCidOrSignature);
-  __ cmpl(kScratchReg, raw_null);
-  __ j(EQUAL, &not_found, Assembler::kNearJump);
-  __ cmpl(kScratchReg, kInstanceCidOrSignature);
-  if (n == 1) {
-    __ j(EQUAL, &found, Assembler::kNearJump);
-  } else {
-    __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
-    __ movl(kScratchReg,
-            Address(kCacheArrayReg,
-                    target::kWordSize *
-                        target::SubtypeTestCache::kDestinationType));
-    compare_to_stack(kScratchReg, kDestinationTypeDepth);
-    __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
-    __ cmpl(kInstanceInstantiatorTypeArgumentsReg,
-            Address(kCacheArrayReg,
-                    target::kWordSize *
-                        target::SubtypeTestCache::kInstanceTypeArguments));
-    if (n == 3) {
-      __ j(EQUAL, &found, Assembler::kNearJump);
-    } else {
-      __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
-      __ movl(
-          kScratchReg,
-          Address(kCacheArrayReg,
-                  target::kWordSize *
-                      target::SubtypeTestCache::kInstantiatorTypeArguments));
-      compare_to_stack(kScratchReg, kInstantiatorTypeArgumentsDepth);
-      __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
-      __ movl(kScratchReg,
-              Address(kCacheArrayReg,
-                      target::kWordSize *
-                          target::SubtypeTestCache::kFunctionTypeArguments));
-      compare_to_stack(kScratchReg, kFunctionTypeArgumentsDepth);
-      if (n == 5) {
-        __ j(EQUAL, &found, Assembler::kNearJump);
-      } else {
-        ASSERT(n == 7);
-        __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
-
-        __ movl(kScratchReg,
-                Address(kCacheArrayReg,
-                        target::kWordSize *
-                            target::SubtypeTestCache::
-                                kInstanceParentFunctionTypeArguments));
-        compare_to_stack(kScratchReg,
-                         kInstanceParentFunctionTypeArgumentsDepth);
-        __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
-        __ movl(kScratchReg,
-                Address(kCacheArrayReg,
-                        target::kWordSize *
-                            target::SubtypeTestCache::
-                                kInstanceDelayedFunctionTypeArguments));
-        compare_to_stack(kScratchReg,
-                         kInstanceDelayedFunctionTypeArgumentsDepth);
-        __ j(EQUAL, &found, Assembler::kNearJump);
-      }
-    }
-  }
+  GenerateSubtypeTestCacheLoop(assembler, n, original_tos_offset,
+                               kInstanceParentFunctionTypeArgumentsDepth,
+                               kInstanceDelayedFunctionTypeArgumentsDepth,
+                               &found, &not_found, &next_iteration);
   __ Bind(&next_iteration);
-  __ addl(kCacheArrayReg,
+  __ addl(STCInternal::kCacheArrayReg,
           Immediate(target::kWordSize *
                     target::SubtypeTestCache::kTestEntryLength));
   __ jmp(&loop, Assembler::kNearJump);
 
   __ Bind(&found);
-  if (n >= 7) {
-    __ Drop(2);
-    original_tos_offset = 0;  // In case we add any input uses after this point.
+  if (n >= 5) {
+    __ Drop(original_tos_offset);
   }
   __ movl(TypeTestABI::kSubtypeTestCacheResultReg,
-          Address(kCacheArrayReg,
+          Address(STCInternal::kCacheArrayReg,
                   target::kWordSize * target::SubtypeTestCache::kTestResult));
   __ ret();
 
   __ Bind(&not_found);
-  if (n >= 7) {
-    __ Drop(2);
-    original_tos_offset = 0;  // In case we add any input uses after this point.
+  if (n >= 5) {
+    __ Drop(original_tos_offset);
   }
-  __ Bind(&not_found_before_push);
   // In the not found case, even though the field that determines occupancy was
   // null, another thread might be updating the cache and in the middle of
   // filling in the entry. Thus, we load the null object explicitly instead of
@@ -2559,26 +2601,6 @@
   __ ret();
 }
 
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype1TestCacheStub() {
-  GenerateSubtypeNTestCacheStub(assembler, 1);
-}
-
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype3TestCacheStub() {
-  GenerateSubtypeNTestCacheStub(assembler, 3);
-}
-
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype5TestCacheStub() {
-  GenerateSubtypeNTestCacheStub(assembler, 5);
-}
-
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype7TestCacheStub() {
-  GenerateSubtypeNTestCacheStub(assembler, 7);
-}
-
 // Return the current stack pointer address, used to do stack alignment checks.
 // TOS + 0: return address
 // Result in EAX.
diff --git a/runtime/vm/compiler/stub_code_compiler_riscv.cc b/runtime/vm/compiler/stub_code_compiler_riscv.cc
index 8c79853..1ad795d 100644
--- a/runtime/vm/compiler/stub_code_compiler_riscv.cc
+++ b/runtime/vm/compiler/stub_code_compiler_riscv.cc
@@ -2801,15 +2801,16 @@
 // Inputs (all preserved, mostly from TypeTestABI struct):
 //   - kSubtypeTestCacheReg: UntaggedSubtypeTestCache
 //   - kInstanceReg: instance to test against.
-//   - kDstTypeReg: destination type (for n>=3).
-//   - kInstantiatorTypeArgumentsReg: instantiator type arguments (for n=5).
-//   - kFunctionTypeArgumentsReg: function type arguments (for n=5).
+//   - kDstTypeReg: destination type (for n>=7).
+//   - kInstantiatorTypeArgumentsReg: instantiator type arguments (for n>=3).
+//   - kFunctionTypeArgumentsReg: function type arguments (for n>=4).
 //   - RA: return address.
 //
 // Outputs (from TypeTestABI struct):
 //   - kSubtypeTestCacheResultReg: the cached result, or null if not found.
-static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
-  ASSERT(n == 1 || n == 3 || n == 5 || n == 7);
+void StubCodeCompiler::GenerateSubtypeNTestCacheStub(Assembler* assembler,
+                                                     int n) {
+  ASSERT(n == 1 || n == 2 || n == 4 || n == 6 || n == 7);
 
   // We could initialize kSubtypeTestCacheResultReg with null and use that as
   // the null register up until exit, which means we'd just need to return
@@ -2825,7 +2826,7 @@
   const Register kCacheArrayReg = TypeTestABI::kSubtypeTestCacheResultReg;
 
   Label not_found;
-  StubCodeCompiler::GenerateSubtypeTestCacheSearch(
+  GenerateSubtypeTestCacheSearch(
       assembler, n, NULL_REG, kCacheArrayReg,
       STCInternalRegs::kInstanceCidOrSignatureReg,
       STCInternalRegs::kInstanceInstantiatorTypeArgumentsReg,
@@ -2845,26 +2846,6 @@
   __ Ret();
 }
 
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype1TestCacheStub() {
-  GenerateSubtypeNTestCacheStub(assembler, 1);
-}
-
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype3TestCacheStub() {
-  GenerateSubtypeNTestCacheStub(assembler, 3);
-}
-
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype5TestCacheStub() {
-  GenerateSubtypeNTestCacheStub(assembler, 5);
-}
-
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype7TestCacheStub() {
-  GenerateSubtypeNTestCacheStub(assembler, 7);
-}
-
 void StubCodeCompiler::GenerateGetCStackPointerStub() {
   __ mv(A0, SP);
   __ ret();
diff --git a/runtime/vm/compiler/stub_code_compiler_x64.cc b/runtime/vm/compiler/stub_code_compiler_x64.cc
index de79112..9079c27 100644
--- a/runtime/vm/compiler/stub_code_compiler_x64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_x64.cc
@@ -2964,16 +2964,17 @@
 // Input registers (all preserved, from TypeTestABI struct):
 //   - kSubtypeTestCacheReg: UntaggedSubtypeTestCache
 //   - kInstanceReg: instance to test against (must be preserved).
-//   - kDstTypeReg: destination type (for n>=3).
-//   - kInstantiatorTypeArgumentsReg : instantiator type arguments (for n>=5).
-//   - kFunctionTypeArgumentsReg : function type arguments (for n>=5).
+//   - kDstTypeReg: destination type (for n>=7).
+//   - kInstantiatorTypeArgumentsReg : instantiator type arguments (for n>=3).
+//   - kFunctionTypeArgumentsReg : function type arguments (for n>=4).
 // Inputs from stack:
 //   - TOS + 0: return address.
 //
 // Outputs (from TypeTestABI struct):
 //   - kSubtypeTestCacheResultReg: the cached result, or null if not found.
-static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
-  ASSERT(n == 1 || n == 3 || n == 5 || n == 7);
+void StubCodeCompiler::GenerateSubtypeNTestCacheStub(Assembler* assembler,
+                                                     int n) {
+  ASSERT(n == 1 || n == 2 || n == 4 || n == 6 || n == 7);
   RegisterSet saved_registers;
 
   // Until we have the result, we use the result register to store the null
@@ -2982,21 +2983,22 @@
   const Register kNullReg = TypeTestABI::kSubtypeTestCacheResultReg;
   __ LoadObject(kNullReg, NullObject());
 
-  // Only used for n >= 7, so set conditionally in that case to catch misuse.
+  // Free up additional registers needed for checks in the loop. Initially
+  // define them as kNoRegister so any unexpected uses are caught.
   Register kInstanceParentFunctionTypeArgumentsReg = kNoRegister;
-  Register kInstanceDelayedFunctionTypeArgumentsReg = kNoRegister;
-
-  // Free up these 2 registers to be used for 7-value test.
-  if (n >= 7) {
+  if (n >= 5) {
     kInstanceParentFunctionTypeArgumentsReg = PP;
     saved_registers.AddRegister(kInstanceParentFunctionTypeArgumentsReg);
+  }
+  Register kInstanceDelayedFunctionTypeArgumentsReg = kNoRegister;
+  if (n >= 6) {
     kInstanceDelayedFunctionTypeArgumentsReg = CODE_REG;
     saved_registers.AddRegister(kInstanceDelayedFunctionTypeArgumentsReg);
   }
   __ PushRegisters(saved_registers);
 
   Label done;
-  StubCodeCompiler::GenerateSubtypeTestCacheSearch(
+  GenerateSubtypeTestCacheSearch(
       assembler, n, kNullReg, STCInternalRegs::kCacheEntryReg,
       STCInternalRegs::kInstanceCidOrSignatureReg,
       STCInternalRegs::kInstanceInstantiatorTypeArgumentsReg,
@@ -3018,26 +3020,6 @@
   __ Ret();
 }
 
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype1TestCacheStub() {
-  GenerateSubtypeNTestCacheStub(assembler, 1);
-}
-
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype3TestCacheStub() {
-  GenerateSubtypeNTestCacheStub(assembler, 3);
-}
-
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype5TestCacheStub() {
-  GenerateSubtypeNTestCacheStub(assembler, 5);
-}
-
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCodeCompiler::GenerateSubtype7TestCacheStub() {
-  GenerateSubtypeNTestCacheStub(assembler, 7);
-}
-
 // Return the current stack pointer address, used to stack alignment
 // checks.
 // TOS + 0: return address
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 39f1980..f310b9c 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -19168,11 +19168,9 @@
 
 void SubtypeTestCache::Init() {
   const auto& array =
-      Array::Handle(Array::New(kHeaderSize + kTestEntryLength, Heap::kOld));
-  // Set the number of occupied entries to 0 and mark the first (only) entry
-  // unoccupied before making this array visible.
-  array.SetAt(kNumOccupiedIndex, Object::smi_zero());
-  array.SetAt(kHeaderSize + kInstanceCidOrSignature, Object::null_object());
+      Array::Handle(Array::NewUninitialized(kTestEntryLength, Heap::kOld));
+  // Mark the first (only) entry unoccupied before making this array visible.
+  array.SetAt(kInstanceCidOrSignature, Object::null_object());
   cached_array_ = array.ptr();
 }
 
@@ -19182,10 +19180,8 @@
 
 SubtypeTestCachePtr SubtypeTestCache::New(intptr_t num_inputs) {
   ASSERT(Object::subtypetestcache_class() != Class::null());
-  // While the SubtypeTestCache runtime code is written so that any value in
-  // [1..kMaxInputs] works, we only expect the following values in practice.
-  ASSERT(num_inputs == 1 || num_inputs == 3 || num_inputs == 5 ||
-         num_inputs == 7);
+  ASSERT(num_inputs >= 1);
+  ASSERT(num_inputs <= kMaxInputs);
   SubtypeTestCache& result = SubtypeTestCache::Handle();
   {
     // SubtypeTestCache objects are long living objects, allocate them in the
@@ -19197,6 +19193,7 @@
     result ^= raw;
     result.untag()->num_inputs_ = num_inputs;
   }
+  result.set_num_occupied(0);
   result.set_cache(Array::Handle(cached_array_));
   return result.ptr();
 }
@@ -19212,11 +19209,14 @@
   untag()->set_cache<std::memory_order_release>(value.ptr());
 }
 
+void SubtypeTestCache::set_num_occupied(intptr_t value) const {
+  ASSERT(Utils::IsUint(32, value));
+  untag()->num_occupied_ = value;
+}
+
 intptr_t SubtypeTestCache::NumberOfChecks() const {
   ASSERT(!IsNull());
-  NoSafepointScope no_safepoint;
-  return RawSmiValue(Smi::RawCast(
-      cache()->untag()->element<std::memory_order_acquire>(kNumOccupiedIndex)));
+  return num_occupied();
 }
 
 intptr_t SubtypeTestCache::NumEntries() const {
@@ -19230,7 +19230,7 @@
 
 bool SubtypeTestCache::IsHash() const {
   if (IsNull()) return false;
-  return RawSmiValue(cache()->untag()->length()) > kMaxLinearCacheSize;
+  return Array::LengthOf(cache()) > kMaxLinearCacheSize;
 }
 
 bool SubtypeTestCache::IsHash(const Array& array) {
@@ -19281,24 +19281,24 @@
   entry.Set<kTestResult>(test_result);
   switch (num_inputs()) {
     case 7:
+      entry.Set<kDestinationType>(destination_type);
+      FALL_THROUGH;
+    case 6:
       entry.Set<kInstanceDelayedFunctionTypeArguments>(
           instance_delayed_type_arguments);
       FALL_THROUGH;
-    case 6:
+    case 5:
       entry.Set<kInstanceParentFunctionTypeArguments>(
           instance_parent_function_type_arguments);
       FALL_THROUGH;
-    case 5:
+    case 4:
       entry.Set<kFunctionTypeArguments>(function_type_arguments);
       FALL_THROUGH;
-    case 4:
+    case 3:
       entry.Set<kInstantiatorTypeArguments>(instantiator_type_arguments);
       FALL_THROUGH;
-    case 3:
-      entry.Set<kInstanceTypeArguments>(instance_type_arguments);
-      FALL_THROUGH;
     case 2:
-      entry.Set<kDestinationType>(destination_type);
+      entry.Set<kInstanceTypeArguments>(instance_type_arguments);
       FALL_THROUGH;
     case 1:
       // If this is a new backing array, we don't need store-release barriers,
@@ -19318,16 +19318,9 @@
     default:
       UNREACHABLE();
   }
-  // Similarly, we set the metadata afterwards with a store-release barrier to
-  // ensure that any reader that sees the updated count can depend on at least
-  // that number of entries being occupied, for example, all entries up to that
-  // count being occupied in a linear cache.
-  const Smi& new_count = Smi::Handle(zone, Smi::New(old_num + 1));
+  set_num_occupied(old_num + 1);
   if (was_grown) {
-    data.SetAt(kNumOccupiedIndex, new_count);
     set_cache(data);
-  } else {
-    data.SetAtRelease(kNumOccupiedIndex, new_count);
   }
   return loc.entry;
 }
@@ -19344,41 +19337,41 @@
     const TypeArguments& instance_delayed_type_arguments) {
   switch (num_inputs) {
     case 7:
+      if (t.Get<SubtypeTestCache::kDestinationType>() !=
+          destination_type.ptr()) {
+        return false;
+      }
+      FALL_THROUGH;
+    case 6:
       if (t.Get<SubtypeTestCache::kInstanceDelayedFunctionTypeArguments>() !=
           instance_delayed_type_arguments.ptr()) {
         return false;
       }
       FALL_THROUGH;
-    case 6:
+    case 5:
       if (t.Get<SubtypeTestCache::kInstanceParentFunctionTypeArguments>() !=
           instance_parent_function_type_arguments.ptr()) {
         return false;
       }
       FALL_THROUGH;
-    case 5:
+    case 4:
       if (t.Get<SubtypeTestCache::kFunctionTypeArguments>() !=
           function_type_arguments.ptr()) {
         return false;
       }
       FALL_THROUGH;
-    case 4:
+    case 3:
       if (t.Get<SubtypeTestCache::kInstantiatorTypeArguments>() !=
           instantiator_type_arguments.ptr()) {
         return false;
       }
       FALL_THROUGH;
-    case 3:
+    case 2:
       if (t.Get<SubtypeTestCache::kInstanceTypeArguments>() !=
           instance_type_arguments.ptr()) {
         return false;
       }
       FALL_THROUGH;
-    case 2:
-      if (t.Get<SubtypeTestCache::kDestinationType>() !=
-          destination_type.ptr()) {
-        return false;
-      }
-      FALL_THROUGH;
     case 1:
       // We don't need to perform load-acquire semantics when re-retrieving
       // the kInstanceCidOrSignature field, as this is performed only if the
@@ -19421,23 +19414,23 @@
             : Smi::Cast(instance_class_id_or_signature).Value();
     switch (num_inputs) {
       case 7:
-        hash = CombineHashes(hash, instance_delayed_type_arguments.Hash());
+        hash = CombineHashes(hash, destination_type.Hash());
         FALL_THROUGH;
       case 6:
+        hash = CombineHashes(hash, instance_delayed_type_arguments.Hash());
+        FALL_THROUGH;
+      case 5:
         hash =
             CombineHashes(hash, instance_parent_function_type_arguments.Hash());
         FALL_THROUGH;
-      case 5:
+      case 4:
         hash = CombineHashes(hash, function_type_arguments.Hash());
         FALL_THROUGH;
-      case 4:
+      case 3:
         hash = CombineHashes(hash, instantiator_type_arguments.Hash());
         FALL_THROUGH;
-      case 3:
-        hash = CombineHashes(hash, instance_type_arguments.Hash());
-        FALL_THROUGH;
       case 2:
-        hash = CombineHashes(hash, destination_type.Hash());
+        hash = CombineHashes(hash, instance_type_arguments.Hash());
         FALL_THROUGH;
       case 1:
         break;
@@ -19470,20 +19463,14 @@
       probe_distance++;
     }
   }
-  // We should always get the next slot for a linear cache.
-  ASSERT(is_hash || probe == NumberOfChecks(array));
   return {probe, false};
 }
 
-intptr_t SubtypeTestCache::NumberOfChecks(const Array& array) {
-  return Smi::Value(Smi::RawCast(array.AtAcquire(kNumOccupiedIndex)));
-}
-
 ArrayPtr SubtypeTestCache::EnsureCapacity(Zone* zone,
                                           const Array& array,
                                           intptr_t new_occupied,
                                           bool* was_grown) const {
-  ASSERT(new_occupied > NumberOfChecks(array));
+  ASSERT(new_occupied > NumberOfChecks());
   ASSERT(was_grown != nullptr);
   // How many entries are in the current array (including unoccupied entries).
   const intptr_t current_capacity = NumEntries(array);
@@ -19514,13 +19501,13 @@
         Utils::Minimum(current_capacity + (current_capacity >> 1),
                        kMaxLinearCacheEntries) +
         1;
-    const intptr_t cache_size = kHeaderSize + new_capacity * kTestEntryLength;
+    const intptr_t cache_size = new_capacity * kTestEntryLength;
     ASSERT(cache_size <= kMaxLinearCacheSize);
     const auto& new_data =
         Array::Handle(zone, Array::Grow(array, cache_size, Heap::kOld));
     ASSERT(!new_data.IsNull());
-    // No need to adjust the number of occupied entries or old entries, as they
-    // are copied over by Array::Grow. Just mark any new entries as unoccupied.
+    // No need to adjust old entries, as they are copied over by Array::Grow.
+    // Just mark any new entries as unoccupied.
     SubtypeTestCacheTable table(new_data);
     for (intptr_t i = current_capacity; i < new_capacity; i++) {
       const auto& tuple = table.At(i);
@@ -19541,18 +19528,11 @@
   // appendix, 2nd edition).
   ASSERT(Utils::IsPowerOfTwo(new_capacity));
   ASSERT(LoadFactor(new_occupied, new_capacity) < kMaxLoadFactor);
-  const intptr_t new_size = kHeaderSize + new_capacity * kTestEntryLength;
+  const intptr_t new_size = new_capacity * kTestEntryLength;
   const auto& new_data =
       Array::Handle(zone, Array::NewUninitialized(new_size, Heap::kOld));
   ASSERT(!new_data.IsNull());
-  // First copy over the metadata in new_data using the existing Object handle.
-  for (intptr_t i = 0; i < kHeaderSize; i++) {
-    instance_cid_or_signature = array.At(i);
-    new_data.SetAt(i, instance_cid_or_signature);
-  }
-  // Set the object handle back to null for later use.
-  instance_cid_or_signature = Object::null();
-  // Then mark all the entries in new_data as unoccupied.
+  // Mark all the entries in new_data as unoccupied.
   SubtypeTestCacheTable to_table(new_data);
   for (const auto& tuple : to_table) {
     tuple.Set<kInstanceCidOrSignature>(instance_cid_or_signature);
@@ -19588,24 +19568,24 @@
     to_tuple.Set<kTestResult>(test_result);
     switch (used_inputs) {
       case 7:
+        to_tuple.Set<kDestinationType>(destination_type);
+        FALL_THROUGH;
+      case 6:
         to_tuple.Set<kInstanceDelayedFunctionTypeArguments>(
             instance_delayed_type_arguments);
         FALL_THROUGH;
-      case 6:
+      case 5:
         to_tuple.Set<kInstanceParentFunctionTypeArguments>(
             instance_parent_function_type_arguments);
         FALL_THROUGH;
-      case 5:
+      case 4:
         to_tuple.Set<kFunctionTypeArguments>(function_type_arguments);
         FALL_THROUGH;
-      case 4:
+      case 3:
         to_tuple.Set<kInstantiatorTypeArguments>(instantiator_type_arguments);
         FALL_THROUGH;
-      case 3:
-        to_tuple.Set<kInstanceTypeArguments>(instance_type_arguments);
-        FALL_THROUGH;
       case 2:
-        to_tuple.Set<kDestinationType>(destination_type);
+        to_tuple.Set<kInstanceTypeArguments>(instance_type_arguments);
         FALL_THROUGH;
       case 1:
         to_tuple.Set<kInstanceCidOrSignature>(instance_cid_or_signature);
@@ -19679,24 +19659,24 @@
   ASSERT(!instance_class_id_or_signature->IsNull());
   switch (num_inputs) {
     case 7:
+      *destination_type = entry.Get<kDestinationType>();
+      FALL_THROUGH;
+    case 6:
       *instance_delayed_type_arguments =
           entry.Get<kInstanceDelayedFunctionTypeArguments>();
       FALL_THROUGH;
-    case 6:
+    case 5:
       *instance_parent_function_type_arguments =
           entry.Get<kInstanceParentFunctionTypeArguments>();
       FALL_THROUGH;
-    case 5:
+    case 4:
       *function_type_arguments = entry.Get<kFunctionTypeArguments>();
       FALL_THROUGH;
-    case 4:
+    case 3:
       *instantiator_type_arguments = entry.Get<kInstantiatorTypeArguments>();
       FALL_THROUGH;
-    case 3:
-      *instance_type_arguments = entry.Get<kInstanceTypeArguments>();
-      FALL_THROUGH;
     case 2:
-      *destination_type = entry.Get<kDestinationType>();
+      *instance_type_arguments = entry.Get<kInstanceTypeArguments>();
       FALL_THROUGH;
     case 1:
       break;
@@ -19812,12 +19792,12 @@
       "%" Pd ": [ %#" Px ", %#" Px ", %#" Px ", %#" Px ", %#" Px ", %#" Px
       ", %#" Px ", %#" Px " ]",
       index, static_cast<uword>(instance_class_id_or_signature.ptr()),
-      static_cast<uword>(destination_type.ptr()),
       static_cast<uword>(instance_type_arguments.ptr()),
       static_cast<uword>(instantiator_type_arguments.ptr()),
       static_cast<uword>(function_type_arguments.ptr()),
       static_cast<uword>(instance_parent_function_type_arguments.ptr()),
       static_cast<uword>(instance_delayed_type_arguments.ptr()),
+      static_cast<uword>(destination_type.ptr()),
       static_cast<uword>(result.ptr()));
   if (instance_class_id_or_signature.IsSmi()) {
     buffer->Printf("%sclass id: %" Pd "", separator,
@@ -19827,21 +19807,6 @@
         "%ssignature: %s", separator,
         FunctionType::Cast(instance_class_id_or_signature).ToCString());
   }
-  if (!destination_type.IsNull()) {
-    buffer->Printf("%sdestination type: %s", separator,
-                   destination_type.ToCString());
-    if (!destination_type.IsInstantiated()) {
-      AbstractType& test_type = AbstractType::Handle(
-          zone, destination_type.InstantiateFrom(instantiator_type_arguments,
-                                                 function_type_arguments,
-                                                 kAllFree, Heap::kNew));
-      const auto type_class_id = test_type.type_class_id();
-      buffer->Printf("%sinstantiated type: %s", separator,
-                     test_type.ToCString());
-      buffer->Printf("%sinstantiated type class id: %d", separator,
-                     type_class_id);
-    }
-  }
   if (!instance_type_arguments.IsNull()) {
     if (instance_class_id_or_signature.IsSmi()) {
       buffer->Printf("%sinstance type arguments: %s", separator,
@@ -19868,6 +19833,21 @@
     buffer->Printf("%sclosure delayed function type arguments: %s", separator,
                    instance_delayed_type_arguments.ToCString());
   }
+  if (!destination_type.IsNull()) {
+    buffer->Printf("%sdestination type: %s", separator,
+                   destination_type.ToCString());
+    if (!destination_type.IsInstantiated()) {
+      AbstractType& test_type = AbstractType::Handle(
+          zone, destination_type.InstantiateFrom(instantiator_type_arguments,
+                                                 function_type_arguments,
+                                                 kAllFree, Heap::kNew));
+      const auto type_class_id = test_type.type_class_id();
+      buffer->Printf("%sinstantiated type: %s", separator,
+                     test_type.ToCString());
+      buffer->Printf("%sinstantiated type class id: %d", separator,
+                     type_class_id);
+    }
+  }
   buffer->Printf("%sresult: %s", separator, result.ToCString());
 }
 
@@ -19881,7 +19861,8 @@
           ? nullptr
           : OS::SCreate(zone, "%s%s", line_prefix, line_prefix);
   const intptr_t num_entries = NumEntries();
-  buffer->Printf("SubtypeTestCache(%" Pd "", num_inputs());
+  buffer->Printf("SubtypeTestCache(%" Pd ", %" Pd "", num_inputs(),
+                 num_occupied());
   for (intptr_t i = 0; i < num_entries; i++) {
     if (!IsOccupied(i)) continue;
     buffer->Printf(",%s{", separator);
@@ -19892,6 +19873,7 @@
 }
 
 void SubtypeTestCache::Reset() const {
+  set_num_occupied(0);
   set_cache(Array::Handle(cached_array_));
 }
 
@@ -19903,6 +19885,8 @@
   if (ptr() == other.ptr()) {
     return true;
   }
+  if (num_inputs() != other.num_inputs()) return false;
+  if (num_occupied() != other.num_occupied()) return false;
   return Array::Handle(cache()).Equals(Array::Handle(other.cache()));
 }
 
@@ -19921,13 +19905,14 @@
   auto& entry_cache = Array::Handle(zone, cache());
   entry_cache = entry_cache.Copy();
   result.set_cache(entry_cache);
+  result.set_num_occupied(num_occupied());
   return result.ptr();
 }
 
 bool SubtypeTestCache::IsOccupied(intptr_t index) const {
   ASSERT(!IsNull());
   const intptr_t cache_index =
-      kHeaderSize + index * kTestEntryLength + kInstanceCidOrSignature;
+      index * kTestEntryLength + kInstanceCidOrSignature;
   NoSafepointScope no_safepoint;
   return cache()->untag()->element<std::memory_order_acquire>(cache_index) !=
          Object::null();
@@ -19935,10 +19920,13 @@
 
 intptr_t SubtypeTestCache::UsedInputsForType(const AbstractType& type) {
   if (type.IsType()) {
-    return type.IsInstantiated() ? 3 : 5;
+    return type.IsInstantiated() ? 2 : 4;
   }
-  // Default to the max number of inputs for other cases.
-  return kMaxInputs;
+  // Default to all inputs except for the destination type, which must be
+  // statically known, otherwise this method wouldn't be called.
+  static_assert(kDestinationType == kMaxInputs - 1,
+                "destination type is not last input");
+  return kMaxInputs - 1;
 }
 
 const char* SubtypeTestCache::ToCString() const {
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 7c04cf1..12827cb 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -7406,9 +7406,8 @@
 
 class SubtypeTestCache : public Object {
  public:
-  // The contents of the backing array storage is a header followed by
-  // a number of entry tuples. Any entry that is unoccupied has the null value
-  // as its first component.
+  // The contents of the backing array storage is a number of entry tuples.
+  // Any entry that is unoccupied has the null value as its first component.
   //
   // If the cache is linear, the entries can be accessed in a linear fashion:
   // all occupied entries come first, followed by at least one unoccupied
@@ -7419,16 +7418,6 @@
   // If the cache is hash-based, the array is instead treated as a hash table
   // probed by using a hash value derived from the inputs.
 
-  enum Header {
-    // The number of occupied entries in the cache as a Smi.
-    //
-    // Note: accesses outside of the subtype test cache mutex must have acquire
-    // semantics. In C++ code, use NumOccupied to retrieve the number of
-    // occupied entries.
-    kNumOccupiedIndex = 0,
-    kHeaderSize,
-  };
-
   // The tuple of values stored in a given entry.
   //
   // Note that occupied entry contents are never modified. That means reading a
@@ -7442,19 +7431,19 @@
   // stored in the instantiator type arguments slot.
   enum Entries {
     kInstanceCidOrSignature = 0,
-    kDestinationType = 1,
-    kInstanceTypeArguments = 2,
-    kInstantiatorTypeArguments = 3,
-    kFunctionTypeArguments = 4,
-    kInstanceParentFunctionTypeArguments = 5,
-    kInstanceDelayedFunctionTypeArguments = 6,
+    kInstanceTypeArguments = 1,
+    kInstantiatorTypeArguments = 2,
+    kFunctionTypeArguments = 3,
+    kInstanceParentFunctionTypeArguments = 4,
+    kInstanceDelayedFunctionTypeArguments = 5,
+    kDestinationType = 6,
     kTestResult = 7,
     kTestEntryLength = 8,
   };
 
   // Assumes only one non-input entry in the array, kTestResult.
   static_assert(kInstanceCidOrSignature == 0 &&
-                    kInstanceDelayedFunctionTypeArguments + 1 == kTestResult &&
+                    kDestinationType + 1 == kTestResult &&
                     kTestResult + 1 == kTestEntryLength,
                 "Need to adjust number of max inputs");
   static constexpr intptr_t kMaxInputs = kTestResult;
@@ -7576,6 +7565,8 @@
   }
   intptr_t num_inputs() const { return untag()->num_inputs_; }
 
+  intptr_t num_occupied() const { return untag()->num_occupied_; }
+
   // The maximum number of occupied entries for a linear subtype test cache
   // before swapping to a hash table-based cache. Exposed publicly for tests.
 #if defined(TARGET_ARCH_IA32)
@@ -7600,10 +7591,6 @@
     return occupied / static_cast<double>(capacity);
   }
 
-  // Retrieves the number of occupied entries in a cache backed by the given
-  // array.
-  static intptr_t NumberOfChecks(const Array& array);
-
   // Retrieves the number of entries (occupied or unoccupied) in a cache
   // backed by the given array.
   static intptr_t NumEntries(const Array& array);
@@ -7655,7 +7642,7 @@
   // The maximum size of the array backing a linear cache. All hash based
   // caches are guaranteed to have sizes larger than this.
   static constexpr intptr_t kMaxLinearCacheSize =
-      kHeaderSize + (kMaxLinearCacheEntries + 1) * kTestEntryLength;
+      (kMaxLinearCacheEntries + 1) * kTestEntryLength;
 
  private:
   // The initial number of entries used when converting from a linear to
@@ -7669,6 +7656,7 @@
   static constexpr double kMaxLoadFactor = 0.71;
 
   void set_cache(const Array& value) const;
+  void set_num_occupied(intptr_t value) const;
 
   // Like GetCurrentCheck, but takes the backing storage array.
   static void GetCheckFromArray(
@@ -13454,14 +13442,13 @@
 
 using SubtypeTestCacheTable = ArrayOfTuplesView<SubtypeTestCache::Entries,
                                                 std::tuple<Object,
+                                                           TypeArguments,
+                                                           TypeArguments,
+                                                           TypeArguments,
+                                                           TypeArguments,
+                                                           TypeArguments,
                                                            AbstractType,
-                                                           TypeArguments,
-                                                           TypeArguments,
-                                                           TypeArguments,
-                                                           TypeArguments,
-                                                           TypeArguments,
-                                                           Bool>,
-                                                SubtypeTestCache::kHeaderSize>;
+                                                           Bool>>;
 
 using MegamorphicCacheEntries =
     ArrayOfTuplesView<MegamorphicCache::EntryType, std::tuple<Smi, Object>>;
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index ee18c81..5674458 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -8407,8 +8407,7 @@
   const auto& array = Array::Handle(zone, cache.cache());
   for (intptr_t i = 0; i < cache.NumEntries(); i++) {
     if (!cache.IsOccupied(i)) continue;
-    const intptr_t entry_start =
-        SubtypeTestCache::kHeaderSize + i * SubtypeTestCache::kTestEntryLength;
+    const intptr_t entry_start = i * SubtypeTestCache::kTestEntryLength;
     {
       const intptr_t cid =
           array.At(entry_start + SubtypeTestCache::kTestResult)
@@ -8432,6 +8431,9 @@
   }
 
     switch (used_inputs) {
+      USED_INPUT_CASE(SubtypeTestCache::kDestinationType,
+                      IsConcreteTypeClassId(cid));
+      FALL_THROUGH;
       USED_INPUT_CASE(SubtypeTestCache::kInstanceDelayedFunctionTypeArguments,
                       cid == kNullCid || cid == kTypeArgumentsCid);
       FALL_THROUGH;
@@ -8447,9 +8449,6 @@
       USED_INPUT_CASE(SubtypeTestCache::kInstanceTypeArguments,
                       cid == kNullCid || cid == kTypeArgumentsCid);
       FALL_THROUGH;
-      USED_INPUT_CASE(SubtypeTestCache::kDestinationType,
-                      IsConcreteTypeClassId(cid));
-      FALL_THROUGH;
       USED_INPUT_CASE(SubtypeTestCache::kInstanceCidOrSignature,
                       cid == kSmiCid || cid == kFunctionTypeCid);
       break;
@@ -8512,6 +8511,23 @@
                         delayed_type_arguments, &got_index, got_result));
   EXPECT_EQ(expected_index, got_index);
   EXPECT(got_result->ptr() == expected_result.ptr());
+  if (num_inputs < (SubtypeTestCache::kInstanceTypeArguments + 1)) {
+    // Match replacing unused instance type arguments with null.
+    EXPECT(cache.HasCheck(instance_class_id_or_signature, destination_type,
+                          tav_null, instantiator_type_arguments,
+                          function_type_arguments,
+                          parent_function_type_arguments,
+                          delayed_type_arguments, &got_index, got_result));
+    EXPECT_EQ(expected_index, got_index);
+    EXPECT(got_result->ptr() == expected_result.ptr());
+  } else {
+    // No match replacing used instance type arguments with null.
+    EXPECT(!cache.HasCheck(
+        instance_class_id_or_signature, destination_type, tav_null,
+        instantiator_type_arguments, function_type_arguments,
+        parent_function_type_arguments, delayed_type_arguments,
+        /*index=*/nullptr, /*result=*/nullptr));
+  }
   if (num_inputs < (SubtypeTestCache::kInstantiatorTypeArguments + 1)) {
     // Match replacing unused instantiator type arguments with null.
     EXPECT(cache.HasCheck(instance_class_id_or_signature, destination_type,
@@ -8580,6 +8596,26 @@
                            parent_function_type_arguments, tav_null,
                            /*index=*/nullptr, /*result=*/nullptr));
   }
+  // Make sure we're not accidentally using the same type as the input below.
+  RELEASE_ASSERT(destination_type.ptr() != Type::VoidType());
+  if (num_inputs < (SubtypeTestCache::kDestinationType + 1)) {
+    // Match replacing unused destination type argument with the null type.
+    EXPECT(cache.HasCheck(instance_class_id_or_signature, Object::void_type(),
+                          instance_type_arguments, instantiator_type_arguments,
+                          function_type_arguments,
+                          parent_function_type_arguments,
+                          delayed_type_arguments, &got_index, got_result));
+    EXPECT_EQ(expected_index, got_index);
+    EXPECT(got_result->ptr() == expected_result.ptr());
+  } else {
+    // No match replacing used destination type argument with the null type.
+    EXPECT(!cache.HasCheck(instance_class_id_or_signature, Object::void_type(),
+                           instance_type_arguments, instantiator_type_arguments,
+                           function_type_arguments,
+                           parent_function_type_arguments,
+                           delayed_type_arguments,
+                           /*index=*/nullptr, /*result=*/nullptr));
+  }
   // Once hash-based, should stay a hash-based cache.
   EXPECT(!was_hash || cache.IsHash());
 }
@@ -8588,18 +8624,18 @@
                                  intptr_t num_classes,
                                  bool expect_hash) {
   TextBuffer buffer(MB);
-  buffer.AddString("class D<S> {}\n");
-  buffer.AddString("D<int> createInstanceD() => D<int>();");
-  buffer.AddString("D<int> Function() createClosureD() => () => D<int>();\n");
+  buffer.AddString("class D {}\n");
+  buffer.AddString("D createInstanceD() => D();");
+  buffer.AddString("D Function() createClosureD() => () => D();\n");
   for (intptr_t i = 0; i < num_classes; i++) {
-    buffer.Printf(R"(class C%)" Pd R"(<S> extends D<S> {}
+    buffer.Printf(R"(class C%)" Pd R"( extends D {}
 )"
-                  R"(C%)" Pd R"(<int> createInstanceC%)" Pd R"(() => C%)" Pd
-                  R"(<int>();
+                  R"(C%)" Pd R"( createInstanceC%)" Pd R"(() => C%)" Pd
+                  R"(();
 )"
-                  R"(C%)" Pd R"(<int> Function() createClosureC%)" Pd
+                  R"(C%)" Pd R"( Function() createClosureC%)" Pd
                   R"(() => () => C%)" Pd
-                  R"(<int>();
+                  R"(();
 )",
                   i, i, i, i, i, i, i);
   }
@@ -8633,9 +8669,11 @@
   auto& type_closure_d_int =
       FunctionType::CheckedHandle(zone, closure_d.GetType(Heap::kNew));
 
-  const auto& stc3 = SubtypeTestCache::Handle(zone, SubtypeTestCache::New(3));
-  const auto& stc5 = SubtypeTestCache::Handle(zone, SubtypeTestCache::New(5));
-  const auto& stc7 = SubtypeTestCache::Handle(zone, SubtypeTestCache::New(7));
+  // Test all the possible input values.
+  const SubtypeTestCache* stcs[SubtypeTestCache::kMaxInputs];
+  for (intptr_t i = 0; i < SubtypeTestCache::kMaxInputs; i++) {
+    stcs[i] = &SubtypeTestCache::Handle(zone, SubtypeTestCache::New(i + 1));
+  }
 
   auto& class_c = Class::Handle(zone);
   auto& instance_c = Instance::Handle(zone);
@@ -8684,17 +8722,13 @@
     EXPECT(!instance_c.IsClosure());
     instance_class_id_or_signature = Smi::New(instance_c.GetClassId());
 
-    SubtypeTestCacheEntryTest(
-        thread, stc3, instance_class_id_or_signature, type_instance_d_int,
-        instance_type_arguments, instantiator_type_arguments,
-        function_type_arguments, parent_function_type_arguments,
-        delayed_type_arguments, expected_result, &got_result);
-
-    SubtypeTestCacheEntryTest(
-        thread, stc5, instance_class_id_or_signature, type_instance_d_int,
-        instance_type_arguments, instantiator_type_arguments,
-        function_type_arguments, parent_function_type_arguments,
-        delayed_type_arguments, expected_result, &got_result);
+    for (intptr_t i = 0; i < 5; i++) {
+      SubtypeTestCacheEntryTest(
+          thread, *stcs[i], instance_class_id_or_signature, type_instance_d_int,
+          instance_type_arguments, instantiator_type_arguments,
+          function_type_arguments, parent_function_type_arguments,
+          delayed_type_arguments, expected_result, &got_result);
+    }
 
     auto const function_name = OS::SCreate(zone, "createClosureC%" Pd "", i);
     closure_c ^= Invoke(root_lib, function_name);
@@ -8703,18 +8737,18 @@
     instance_class_id_or_signature =
         Function::Cast(instance_class_id_or_signature).signature();
 
-    SubtypeTestCacheEntryTest(
-        thread, stc7, instance_class_id_or_signature, type_closure_d_int,
-        instance_type_arguments, instantiator_type_arguments,
-        function_type_arguments, parent_function_type_arguments,
-        delayed_type_arguments, expected_result, &got_result);
+    for (intptr_t i = 5; i < SubtypeTestCache::kMaxInputs; i++) {
+      SubtypeTestCacheEntryTest(
+          thread, *stcs[i], instance_class_id_or_signature, type_closure_d_int,
+          instance_type_arguments, instantiator_type_arguments,
+          function_type_arguments, parent_function_type_arguments,
+          delayed_type_arguments, expected_result, &got_result);
+    }
   }
-  SubtypeTestCacheCheckContents(zone, stc3);
-  SubtypeTestCacheCheckContents(zone, stc5);
-  SubtypeTestCacheCheckContents(zone, stc7);
-  EXPECT_EQ(expect_hash, stc3.IsHash());
-  EXPECT_EQ(expect_hash, stc5.IsHash());
-  EXPECT_EQ(expect_hash, stc7.IsHash());
+  for (intptr_t i = 0; i < SubtypeTestCache::kMaxInputs; i++) {
+    SubtypeTestCacheCheckContents(zone, *stcs[i]);
+    EXPECT_EQ(expect_hash, stcs[i]->IsHash());
+  }
 }
 
 TEST_CASE(STC_LinearLookup) {
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 275c8a8..ec6b79b 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -2498,6 +2498,7 @@
   VISIT_FROM(cache)
   VISIT_TO(cache)
   uint32_t num_inputs_;
+  uint32_t num_occupied_;
 };
 
 class UntaggedLoadingUnit : public UntaggedObject {
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index 988e155..6177c5c 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -986,12 +986,12 @@
         "    raw entry: [ %#" Px ", %#" Px ", %#" Px ", %#" Px ", %#" Px
         ", %#" Px ", %#" Px ", %#" Px " ]\n",
         static_cast<uword>(instance_class_id_or_signature.ptr()),
-        static_cast<uword>(destination_type.ptr()),
         static_cast<uword>(instance_type_arguments.ptr()),
         static_cast<uword>(instantiator_type_arguments.ptr()),
         static_cast<uword>(function_type_arguments.ptr()),
         static_cast<uword>(instance_parent_function_type_arguments.ptr()),
         static_cast<uword>(instance_delayed_type_arguments.ptr()),
+        static_cast<uword>(destination_type.ptr()),
         static_cast<uword>(result.ptr()));
     THR_Print("%s", buffer.buffer());
   }
diff --git a/runtime/vm/stub_code.h b/runtime/vm/stub_code.h
index 127cdd4..95c01d7 100644
--- a/runtime/vm/stub_code.h
+++ b/runtime/vm/stub_code.h
@@ -67,10 +67,12 @@
     switch (i) {
       case 1:
         return StubCode::Subtype1TestCache();
-      case 3:
-        return StubCode::Subtype3TestCache();
-      case 5:
-        return StubCode::Subtype5TestCache();
+      case 2:
+        return StubCode::Subtype2TestCache();
+      case 4:
+        return StubCode::Subtype4TestCache();
+      case 6:
+        return StubCode::Subtype6TestCache();
       case 7:
         return StubCode::Subtype7TestCache();
       default:
diff --git a/runtime/vm/stub_code_list.h b/runtime/vm/stub_code_list.h
index d56a3b2..fe906968 100644
--- a/runtime/vm/stub_code_list.h
+++ b/runtime/vm/stub_code_list.h
@@ -108,8 +108,9 @@
   V(NullIsAssignableToType)                                                    \
   V(NullIsAssignableToTypeNullSafe)                                            \
   V(Subtype1TestCache)                                                         \
-  V(Subtype3TestCache)                                                         \
-  V(Subtype5TestCache)                                                         \
+  V(Subtype2TestCache)                                                         \
+  V(Subtype4TestCache)                                                         \
+  V(Subtype6TestCache)                                                         \
   V(Subtype7TestCache)                                                         \
   VM_TYPE_TESTING_STUB_CODE_LIST(V)                                            \
   V(CallClosureNoSuchMethod)                                                   \