[vm] Encapsulate lookup of Symbol members in ObjectStore

For members of program structure that we cache in the ObjectStore we try
to provide only read-only access in the public API. The lazy population
is encapculated in the ObjectStore class.

Use the same mechanism we use for core/isolate/... library members also
for the `dart:_internal` members.

Furthermore cache the Symbol._name field in the ObjectStore to avoid
expensive lookup as well as avoid an extra TLS lookup.

TEST=Existing test suite.

Change-Id: I299faceb39f20576e23244c71c58d698f80f80c7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/208180
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 4a6ac6b..b7e0aef 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -5583,6 +5583,7 @@
                             DECLARE_OBJECT_STORE_FIELD,
                             DECLARE_OBJECT_STORE_FIELD,
                             DECLARE_OBJECT_STORE_FIELD,
+                            DECLARE_OBJECT_STORE_FIELD,
                             DECLARE_OBJECT_STORE_FIELD)
 #undef DECLARE_OBJECT_STORE_FIELD
 };
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index 14d118a..35ca895 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -612,7 +612,6 @@
         IG->object_store()->set_pragma_name(null_field);
         IG->object_store()->set_pragma_options(null_field);
         IG->object_store()->set_completer_class(null_class);
-        IG->object_store()->set_symbol_class(null_class);
         IG->object_store()->set_compiletime_error_class(null_class);
         IG->object_store()->set_growable_list_factory(null_function);
         IG->object_store()->set_simple_instance_of_function(null_function);
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index e1f330e..cb011a5 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -220,11 +220,12 @@
     12;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    176;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 116;
+    184;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 124;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    204;
-static constexpr dart::compiler::target::word ObjectStore_type_type_offset = 96;
+    212;
+static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
+    104;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 12;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 4;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 8;
@@ -762,12 +763,12 @@
     24;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    352;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 232;
+    368;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 248;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    408;
+    424;
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
-    192;
+    208;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 8;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
@@ -1310,11 +1311,12 @@
     12;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    176;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 116;
+    184;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 124;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    204;
-static constexpr dart::compiler::target::word ObjectStore_type_type_offset = 96;
+    212;
+static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
+    104;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 12;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 4;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 8;
@@ -1849,12 +1851,12 @@
     24;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    352;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 232;
+    368;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 248;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    408;
+    424;
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
-    192;
+    208;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 8;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
@@ -2398,12 +2400,12 @@
     24;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    352;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 232;
+    368;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 248;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    408;
+    424;
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
-    192;
+    208;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 8;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
@@ -2946,12 +2948,12 @@
     24;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    352;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 232;
+    368;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 248;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    408;
+    424;
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
-    192;
+    208;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 8;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
@@ -3491,11 +3493,12 @@
     12;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    176;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 116;
+    184;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 124;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    204;
-static constexpr dart::compiler::target::word ObjectStore_type_type_offset = 96;
+    212;
+static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
+    104;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 12;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 4;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 8;
@@ -4027,12 +4030,12 @@
     24;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    352;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 232;
+    368;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 248;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    408;
+    424;
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
-    192;
+    208;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 8;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
@@ -4569,11 +4572,12 @@
     12;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    176;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 116;
+    184;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 124;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    204;
-static constexpr dart::compiler::target::word ObjectStore_type_type_offset = 96;
+    212;
+static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
+    104;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 12;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 4;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 8;
@@ -5102,12 +5106,12 @@
     24;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    352;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 232;
+    368;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 248;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    408;
+    424;
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
-    192;
+    208;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 8;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
@@ -5645,12 +5649,12 @@
     24;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    352;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 232;
+    368;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 248;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    408;
+    424;
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
-    192;
+    208;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 8;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
@@ -6187,12 +6191,12 @@
     24;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    352;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 232;
+    368;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 248;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    408;
+    424;
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
-    192;
+    208;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 8;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
@@ -6761,13 +6765,13 @@
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_double_type_offset = 176;
+    AOT_ObjectStore_double_type_offset = 184;
 static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
-    116;
+    124;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_string_type_offset = 204;
+    AOT_ObjectStore_string_type_offset = 212;
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
-    96;
+    104;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     12;
 static constexpr dart::compiler::target::word
@@ -7368,13 +7372,13 @@
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_double_type_offset = 352;
+    AOT_ObjectStore_double_type_offset = 368;
 static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
-    232;
+    248;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_string_type_offset = 408;
+    AOT_ObjectStore_string_type_offset = 424;
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
-    192;
+    208;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     16;
 static constexpr dart::compiler::target::word
@@ -7981,13 +7985,13 @@
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_double_type_offset = 352;
+    AOT_ObjectStore_double_type_offset = 368;
 static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
-    232;
+    248;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_string_type_offset = 408;
+    AOT_ObjectStore_string_type_offset = 424;
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
-    192;
+    208;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     16;
 static constexpr dart::compiler::target::word
@@ -8591,13 +8595,13 @@
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_double_type_offset = 352;
+    AOT_ObjectStore_double_type_offset = 368;
 static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
-    232;
+    248;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_string_type_offset = 408;
+    AOT_ObjectStore_string_type_offset = 424;
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
-    192;
+    208;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     16;
 static constexpr dart::compiler::target::word
@@ -9200,13 +9204,13 @@
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_double_type_offset = 352;
+    AOT_ObjectStore_double_type_offset = 368;
 static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
-    232;
+    248;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_string_type_offset = 408;
+    AOT_ObjectStore_string_type_offset = 424;
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
-    192;
+    208;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     16;
 static constexpr dart::compiler::target::word
@@ -9805,13 +9809,13 @@
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_double_type_offset = 176;
+    AOT_ObjectStore_double_type_offset = 184;
 static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
-    116;
+    124;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_string_type_offset = 204;
+    AOT_ObjectStore_string_type_offset = 212;
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
-    96;
+    104;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     12;
 static constexpr dart::compiler::target::word
@@ -10405,13 +10409,13 @@
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_double_type_offset = 352;
+    AOT_ObjectStore_double_type_offset = 368;
 static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
-    232;
+    248;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_string_type_offset = 408;
+    AOT_ObjectStore_string_type_offset = 424;
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
-    192;
+    208;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     16;
 static constexpr dart::compiler::target::word
@@ -11011,13 +11015,13 @@
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_double_type_offset = 352;
+    AOT_ObjectStore_double_type_offset = 368;
 static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
-    232;
+    248;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_string_type_offset = 408;
+    AOT_ObjectStore_string_type_offset = 424;
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
-    192;
+    208;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     16;
 static constexpr dart::compiler::target::word
@@ -11614,13 +11618,13 @@
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_double_type_offset = 352;
+    AOT_ObjectStore_double_type_offset = 368;
 static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
-    232;
+    248;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_string_type_offset = 408;
+    AOT_ObjectStore_string_type_offset = 424;
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
-    192;
+    208;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     16;
 static constexpr dart::compiler::target::word
@@ -12216,13 +12220,13 @@
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_double_type_offset = 352;
+    AOT_ObjectStore_double_type_offset = 368;
 static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
-    232;
+    248;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_string_type_offset = 408;
+    AOT_ObjectStore_string_type_offset = 424;
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
-    192;
+    208;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     16;
 static constexpr dart::compiler::target::word
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index c52f156..e7fb75d 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -18902,40 +18902,20 @@
   return true;
 }
 
-static ClassPtr EnsureSymbolClass(Thread* thread) {
-  ObjectStore* const store = thread->isolate_group()->object_store();
-
-  if (store->symbol_class() != Class::null()) {
-    return store->symbol_class();
-  }
-  Zone* const zone = thread->zone();
-  const auto& library = Library::Handle(zone, Library::InternalLibrary());
-  const auto& symbol_class =
-      Class::Handle(zone, library.LookupClass(Symbols::Symbol()));
-  ASSERT(!symbol_class.IsNull());
-  store->set_symbol_class(symbol_class);
-  return symbol_class.ptr();
-}
-
-bool Symbol::IsSymbolCid(classid_t class_id) {
-  Thread* const thread = Thread::Current();
-  Zone* const zone = thread->zone();
-
-  Class& symbol_class = Class::Handle(zone, EnsureSymbolClass(thread));
-
-  return class_id == symbol_class.id();
+bool Symbol::IsSymbolCid(Thread* thread, classid_t class_id) {
+  auto object_store = thread->isolate_group()->object_store();
+  return Class::GetClassId(object_store->symbol_class()) == class_id;
 }
 
 // Must be kept in sync with Symbol.hashCode in symbol_patch.dart
-uint32_t Symbol::CanonicalizeHash(const Instance& instance) {
-  ASSERT(IsSymbolCid(instance.GetClassId()));
+uint32_t Symbol::CanonicalizeHash(Thread* thread, const Instance& instance) {
+  ASSERT(IsSymbolCid(thread, instance.GetClassId()));
 
-  Thread* const thread = Thread::Current();
-  Zone* const zone = thread->zone();
+  auto zone = thread->zone();
+  auto object_store = thread->isolate_group()->object_store();
 
-  Class& symbol_class = Class::Handle(zone, EnsureSymbolClass(thread));
-  const auto& symbol_name_field = Field::Handle(
-      zone, symbol_class.LookupInstanceFieldAllowPrivate(Symbols::_name()));
+  const auto& symbol_name_field =
+      Field::Handle(zone, object_store->symbol_name_field());
   ASSERT(!symbol_name_field.IsNull());
 
   // Keep in sync with sdk/lib/_internal/vm/lib/symbol_patch.dart.
@@ -18956,10 +18936,12 @@
   }
   Zone* zone = thread->zone();
   const Class& cls = Class::Handle(zone, clazz());
+  const bool is_symbol = Symbol::IsSymbolCid(thread, cls.id());
+
   NoSafepointScope no_safepoint(thread);
 
-  if (Symbol::IsSymbolCid(GetClassId())) {
-    hash = Symbol::CanonicalizeHash(*this);
+  if (is_symbol) {
+    hash = Symbol::CanonicalizeHash(thread, *this);
   } else {
     const intptr_t class_id = cls.id();
     ASSERT(class_id != 0);
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 718d4ca..39b4940 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -1328,8 +1328,7 @@
   // Check if this class represents the 'Closure' class.
   bool IsClosureClass() const { return id() == kClosureCid; }
   static bool IsClosureClass(ClassPtr cls) {
-    NoSafepointScope no_safepoint;
-    return cls->untag()->id_ == kClosureCid;
+    return GetClassId(cls) == kClosureCid;
   }
 
   static bool IsInFullSnapshot(ClassPtr cls) {
@@ -1338,6 +1337,11 @@
         cls->untag()->library()->untag()->flags_);
   }
 
+  static intptr_t GetClassId(ClassPtr cls) {
+    NoSafepointScope no_safepoint;
+    return cls->untag()->id_;
+  }
+
   // Returns true if the type specified by cls, type_arguments, and nullability
   // is a subtype of the other type.
   static bool IsSubtypeOf(const Class& cls,
@@ -9123,9 +9127,9 @@
 // TODO(http://dartbug.com/46716): Recognize Symbol in the VM.
 class Symbol : public AllStatic {
  public:
-  static bool IsSymbolCid(classid_t class_id);
+  static bool IsSymbolCid(Thread* thread, classid_t class_id);
 
-  static uint32_t CanonicalizeHash(const Instance& instance);
+  static uint32_t CanonicalizeHash(Thread* thread, const Instance& instance);
 };
 
 // String may not be '\0' terminated.
diff --git a/runtime/vm/object_store.cc b/runtime/vm/object_store.cc
index 9892d6f..ca90802 100644
--- a/runtime/vm/object_store.cc
+++ b/runtime/vm/object_store.cc
@@ -121,9 +121,9 @@
     Object& value = Object::Handle();
     static const char* const names[] = {
 #define EMIT_FIELD_NAME(type, name) #name "_",
-        OBJECT_STORE_FIELD_LIST(EMIT_FIELD_NAME, EMIT_FIELD_NAME,
-                                EMIT_FIELD_NAME, EMIT_FIELD_NAME,
-                                EMIT_FIELD_NAME, EMIT_FIELD_NAME)
+        OBJECT_STORE_FIELD_LIST(
+            EMIT_FIELD_NAME, EMIT_FIELD_NAME, EMIT_FIELD_NAME, EMIT_FIELD_NAME,
+            EMIT_FIELD_NAME, EMIT_FIELD_NAME, EMIT_FIELD_NAME)
 #undef EMIT_FIELD_NAME
     };
     ObjectPtr* current = from();
@@ -271,10 +271,6 @@
     }
   }
 
-  const Library& internal_lib = Library::Handle(zone, _internal_library());
-  cls = internal_lib.LookupClass(Symbols::Symbol());
-  set_symbol_class(cls);
-
   const Library& core_lib = Library::Handle(zone, core_library());
   cls = core_lib.LookupClassAllowPrivate(Symbols::_CompileTimeError());
   ASSERT(!cls.IsNull());
@@ -450,4 +446,29 @@
   }
 }
 
+void ObjectStore::LazyInitInternalMembers() {
+  auto* const thread = Thread::Current();
+  SafepointWriteRwLocker locker(thread,
+                                thread->isolate_group()->program_lock());
+  if (symbol_class_.load() == Type::null()) {
+    ASSERT(symbol_name_field_.load() == Field::null());
+
+    auto* const zone = thread->zone();
+    auto& cls = Class::Handle(zone);
+    auto& field = Field::Handle(zone);
+
+    const auto& internal_lib =
+        Library::Handle(zone, Library::InternalLibrary());
+    cls = internal_lib.LookupClass(Symbols::Symbol());
+    ASSERT(!cls.IsNull());
+    const auto& error = cls.EnsureIsFinalized(thread);
+    ASSERT(error == Error::null());
+    symbol_class_.store(cls.ptr());
+
+    field = cls.LookupInstanceFieldAllowPrivate(Symbols::_name());
+    ASSERT(!field.IsNull());
+    symbol_name_field_.store(field.ptr());
+  }
+}
+
 }  // namespace dart
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 267ff50..cc50d4b 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -37,22 +37,26 @@
 // R_ - needs getter only
 // RW - needs getter and setter
 // ARW - needs getter and setter with atomic access
-// CR - needs lazy Core init getter
-// FR - needs lazy Async init getter
-// IR - needs lazy Isolate init getter
-#define OBJECT_STORE_FIELD_LIST(R_, RW, ARW, CR, FR, IR)                       \
-  CR(Class, list_class)                    /* maybe be null, lazily built */   \
-  CR(Type, non_nullable_list_rare_type)    /* maybe be null, lazily built */   \
-  CR(Type, non_nullable_map_rare_type)     /* maybe be null, lazily built */   \
-  CR(Function, _object_equals_function)    /* maybe be null, lazily built */   \
-  CR(Function, _object_hash_code_function) /* maybe be null, lazily built */   \
-  CR(Function, _object_to_string_function) /* maybe be null, lazily built */   \
-  FR(Type, non_nullable_future_rare_type)  /* maybe be null, lazily built */   \
-  FR(Type, non_nullable_future_never_type) /* maybe be null, lazily built */   \
-  FR(Type, nullable_future_null_type)      /* maybe be null, lazily built */   \
-  IR(Function, lookup_port_handler)        /* maybe be null, lazily built */   \
-  IR(Function, lookup_open_ports)          /* maybe be null, lazily built */   \
-  IR(Function, handle_message_function)    /* maybe be null, lazily built */   \
+// LAZY_CORE - needs lazy init getter for a "dart:core" member
+// LAZY_ASYNC - needs lazy init getter for a "dart:async" member
+// LAZY_ISOLATE - needs lazy init getter for a "dart:isolate" member
+// LAZY_INTERNAL - needs lazy init getter for a "dart:_internal" member
+#define OBJECT_STORE_FIELD_LIST(R_, RW, ARW, LAZY_CORE, LAZY_ASYNC,            \
+                                LAZY_ISOLATE, LAZY_INTERNAL)                   \
+  LAZY_CORE(Class, list_class)                                                 \
+  LAZY_CORE(Type, non_nullable_list_rare_type)                                 \
+  LAZY_CORE(Type, non_nullable_map_rare_type)                                  \
+  LAZY_CORE(Function, _object_equals_function)                                 \
+  LAZY_CORE(Function, _object_hash_code_function)                              \
+  LAZY_CORE(Function, _object_to_string_function)                              \
+  LAZY_INTERNAL(Class, symbol_class)                                           \
+  LAZY_INTERNAL(Field, symbol_name_field)                                      \
+  LAZY_ASYNC(Type, non_nullable_future_rare_type)                              \
+  LAZY_ASYNC(Type, non_nullable_future_never_type)                             \
+  LAZY_ASYNC(Type, nullable_future_null_type)                                  \
+  LAZY_ISOLATE(Function, lookup_port_handler)                                  \
+  LAZY_ISOLATE(Function, lookup_open_ports)                                    \
+  LAZY_ISOLATE(Function, handle_message_function)                              \
   RW(Class, object_class)                                                      \
   RW(Type, object_type)                                                        \
   RW(Type, legacy_object_type)                                                 \
@@ -116,7 +120,6 @@
   RW(Field, pragma_options)                                                    \
   RW(Class, future_class)                                                      \
   RW(Class, completer_class)                                                   \
-  RW(Class, symbol_class)                                                      \
   RW(Class, one_byte_string_class)                                             \
   RW(Class, two_byte_string_class)                                             \
   RW(Class, external_one_byte_string_class)                                    \
@@ -424,12 +427,15 @@
   DECLARE_LAZY_INIT_GETTER(Type, name, LazyInitAsyncMembers)
 #define DECLARE_LAZY_INIT_ISOLATE_GETTER(Type, name)                           \
   DECLARE_LAZY_INIT_GETTER(Type, name, LazyInitIsolateMembers)
+#define DECLARE_LAZY_INIT_INTERNAL_GETTER(Type, name)                          \
+  DECLARE_LAZY_INIT_GETTER(Type, name, LazyInitInternalMembers)
   OBJECT_STORE_FIELD_LIST(DECLARE_GETTER,
                           DECLARE_GETTER_AND_SETTER,
                           DECLARE_ATOMIC_GETTER_AND_SETTER,
                           DECLARE_LAZY_INIT_CORE_GETTER,
                           DECLARE_LAZY_INIT_ASYNC_GETTER,
-                          DECLARE_LAZY_INIT_ISOLATE_GETTER)
+                          DECLARE_LAZY_INIT_ISOLATE_GETTER,
+                          DECLARE_LAZY_INIT_INTERNAL_GETTER)
 #undef DECLARE_OFFSET
 #undef DECLARE_GETTER
 #undef DECLARE_GETTER_AND_SETTER
@@ -438,6 +444,7 @@
 #undef DECLARE_LAZY_INIT_CORE_GETTER
 #undef DECLARE_LAZY_INIT_ASYNC_GETTER
 #undef DECLARE_LAZY_INIT_ISOLATE_GETTER
+#undef DECLARE_LAZY_INIT_INTERNAL_GETTER
 
   LibraryPtr bootstrap_library(BootstrapLibraryId index) {
     switch (index) {
@@ -488,6 +495,7 @@
   void LazyInitCoreMembers();
   void LazyInitAsyncMembers();
   void LazyInitIsolateMembers();
+  void LazyInitInternalMembers();
 
   // Finds a core library private method in Object.
   FunctionPtr PrivateObjectLookup(const String& name);
@@ -503,6 +511,7 @@
                           DECLARE_ATOMIC_OBJECT_STORE_FIELD,
                           DECLARE_LAZY_OBJECT_STORE_FIELD,
                           DECLARE_LAZY_OBJECT_STORE_FIELD,
+                          DECLARE_LAZY_OBJECT_STORE_FIELD,
                           DECLARE_LAZY_OBJECT_STORE_FIELD)
 #undef DECLARE_OBJECT_STORE_FIELD
 #undef DECLARE_ATOMIC_OBJECT_STORE_FIELD