From 1cea4f514e61be080b562ec980ca3bc28c9f7304 Mon Sep 17 00:00:00 2001 From: Ryan Macnak Date: Tue, 31 Mar 2026 12:55:51 -0700 Subject: [PATCH] [vm] Gather global variables pointing into the VM isolate. TEST=ci Change-Id: Ia2110904f4b88aa13b06210902c5a673d9be475c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/491705 Reviewed-by: Alexander Aprelev Commit-Queue: Ryan Macnak --- runtime/vm/app_snapshot.cc | 18 +- runtime/vm/dart.cc | 55 --- runtime/vm/dart.h | 8 - runtime/vm/dart_api_impl.cc | 54 +-- runtime/vm/dart_api_impl.h | 36 +- runtime/vm/dart_entry.cc | 24 +- runtime/vm/dart_entry.h | 3 - runtime/vm/object.cc | 817 ++++++++++++++------------------ runtime/vm/object.h | 194 +++----- runtime/vm/object_graph_copy.cc | 2 +- runtime/vm/raw_object.cc | 2 +- runtime/vm/roots.cc | 32 ++ runtime/vm/roots.h | 308 ++++++++++++ runtime/vm/stub_code.cc | 16 +- runtime/vm/stub_code.h | 13 +- runtime/vm/symbol_list.h | 567 ++++++++++++++++++++++ runtime/vm/symbols.cc | 34 +- runtime/vm/symbols.h | 682 ++------------------------ runtime/vm/vm_sources.gni | 3 + 19 files changed, 1454 insertions(+), 1414 deletions(-) create mode 100644 runtime/vm/roots.cc create mode 100644 runtime/vm/roots.h create mode 100644 runtime/vm/symbol_list.h diff --git a/runtime/vm/app_snapshot.cc b/runtime/vm/app_snapshot.cc index a601c917709..ee6f700f60a 100644 --- a/runtime/vm/app_snapshot.cc +++ b/runtime/vm/app_snapshot.cc @@ -6956,11 +6956,11 @@ class VMSerializationRoots : public SerializationRoots { "ExceptionHandlers", ""); for (intptr_t i = 0; i < ArgumentsDescriptor::kCachedDescriptorCount; i++) { - s->AddBaseObject(ArgumentsDescriptor::cached_args_descriptors_[i], - "ArgumentsDescriptor", ""); + s->AddBaseObject(Roots::cached_args_descriptor(i), "ArgumentsDescriptor", + ""); } for (intptr_t i = 0; i < ICData::kCachedICDataArrayCount; i++) { - s->AddBaseObject(ICData::cached_icdata_arrays_[i], "Array", + s->AddBaseObject(Roots::cached_icdata_array(i), "Array", ""); } @@ -7073,10 +7073,10 @@ class VMDeserializationRoots : public DeserializationRoots { d->AddBaseObject(Object::empty_async_exception_handlers().ptr()); for (intptr_t i = 0; i < ArgumentsDescriptor::kCachedDescriptorCount; i++) { - d->AddBaseObject(ArgumentsDescriptor::cached_args_descriptors_[i]); + d->AddBaseObject(Roots::cached_args_descriptor(i)); } for (intptr_t i = 0; i < ICData::kCachedICDataArrayCount; i++) { - d->AddBaseObject(ICData::cached_icdata_arrays_[i]); + d->AddBaseObject(Roots::cached_icdata_array(i)); } ClassTable* table = d->isolate_group()->class_table(); @@ -7100,9 +7100,7 @@ class VMDeserializationRoots : public DeserializationRoots { void ReadRoots(Deserializer* d) override { for (intptr_t i = 0; i < Symbols::kMaxPredefinedId; i++) { - String* symbol = String::ReadOnlyHandle(); - *symbol ^= d->ReadRef(); - Symbols::InitSymbol(i, symbol); + Symbols::InitSymbol(i, static_cast(d->ReadRef())); } symbol_table_ ^= d->ReadRef(); if (!symbol_table_.IsNull()) { @@ -7111,9 +7109,7 @@ class VMDeserializationRoots : public DeserializationRoots { Symbols::InitFromSnapshot(d->isolate_group()); if (Snapshot::IncludesCode(d->kind())) { for (intptr_t i = 0; i < StubCode::NumEntries(); i++) { - Code* code = Code::ReadOnlyHandle(); - *code ^= d->ReadRef(); - StubCode::EntryAtPut(i, code); + StubCode::EntryAtPut(i, static_cast(d->ReadRef())); } StubCode::InitializationDone(); } diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc index 91c1b0d553d..4ff7edf7e98 100644 --- a/runtime/vm/dart.cc +++ b/runtime/vm/dart.cc @@ -64,7 +64,6 @@ DEFINE_FLAG(bool, trace_shutdown, false, "Trace VM shutdown on stderr"); Isolate* Dart::vm_isolate_ = nullptr; int64_t Dart::start_time_micros_ = 0; ThreadPool* Dart::thread_pool_ = nullptr; -ReadOnlyHandles* Dart::predefined_handles_ = nullptr; Snapshot::Kind Dart::vm_snapshot_kind_ = Snapshot::kInvalid; Dart_ThreadStartCallback Dart::thread_start_callback_ = nullptr; Dart_ThreadExitCallback Dart::thread_exit_callback_ = nullptr; @@ -76,29 +75,6 @@ Dart_EntropySource Dart::entropy_source_callback_ = nullptr; Dart_DwarfStackTraceFootnoteCallback Dart::dwarf_stacktrace_footnote_callback_ = nullptr; -// Structure for managing read-only global handles allocation used for -// creating global read-only handles that are pre created and initialized -// for use across all isolates. Having these global pre created handles -// stored in the vm isolate ensures that we don't constantly create and -// destroy handles for read-only objects referred in the VM code -// (e.g: symbols, null object, empty array etc.) -// The ReadOnlyHandles C++ Wrapper around VMHandles which is a ValueObject is -// to ensure that the handles area is not trashed by automatic running of C++ -// static destructors when 'exit()" is called by any isolate. There might be -// other isolates running at the same time and trashing the handles area will -// have unintended consequences. -class ReadOnlyHandles { - public: - ReadOnlyHandles() {} - - private: - VMHandles handles_; - LocalHandles api_handles_; - - friend class Dart; - DISALLOW_COPY_AND_ASSIGN(ReadOnlyHandles); -}; - class DartInitializationState : public AllStatic { public: static bool StartInit() { @@ -393,9 +369,6 @@ char* Dart::DartInit(const Dart_InitializeParams* params) { #if defined(DART_INCLUDE_SIMULATOR) Simulator::Init(); #endif - // Create the read-only handles area. - ASSERT(predefined_handles_ == nullptr); - predefined_handles_ = new ReadOnlyHandles(); // Create the VM isolate and finish the VM initialization. ASSERT(thread_pool_ == nullptr); thread_pool_ = new ThreadPool(); @@ -770,8 +743,6 @@ char* Dart::Cleanup() { #endif // defined(DART_INCLUDE_PROFILER) Api::Cleanup(); - delete predefined_handles_; - predefined_handles_ = nullptr; // Set the VM isolate as current isolate. if (FLAG_trace_shutdown) { @@ -1205,30 +1176,4 @@ int64_t Dart::UptimeMicros() { return OS::GetCurrentMonotonicMicros() - Dart::start_time_micros_; } -uword Dart::AllocateReadOnlyHandle() { - ASSERT(Isolate::Current() == Dart::vm_isolate()); - ASSERT(predefined_handles_ != nullptr); - uword handle = predefined_handles_->handles_.AllocateScopedHandle(); -#if defined(DEBUG) - *reinterpret_cast(handle + kOffsetOfIsZoneHandle * kWordSize) = 0; -#endif - return handle; -} - -LocalHandle* Dart::AllocateReadOnlyApiHandle() { - ASSERT(Isolate::Current() == Dart::vm_isolate()); - ASSERT(predefined_handles_ != nullptr); - return predefined_handles_->api_handles_.AllocateHandle(); -} - -bool Dart::IsReadOnlyHandle(uword address) { - ASSERT(predefined_handles_ != nullptr); - return predefined_handles_->handles_.IsValidScopedHandle(address); -} - -bool Dart::IsReadOnlyApiHandle(Dart_Handle handle) { - ASSERT(predefined_handles_ != nullptr); - return predefined_handles_->api_handles_.IsValidHandle(handle); -} - } // namespace dart diff --git a/runtime/vm/dart.h b/runtime/vm/dart.h index 6970ca9e7b8..0fbf7f2ba9c 100644 --- a/runtime/vm/dart.h +++ b/runtime/vm/dart.h @@ -18,7 +18,6 @@ namespace dart { // Forward declarations. class Isolate; class LocalHandle; -class ReadOnlyHandles; class ThreadPool; namespace kernel { class Program; @@ -77,12 +76,6 @@ class Dart : public AllStatic { return UptimeMicros() / kMicrosecondsPerMillisecond; } - static LocalHandle* AllocateReadOnlyApiHandle(); - static bool IsReadOnlyApiHandle(Dart_Handle handle); - - static uword AllocateReadOnlyHandle(); - static bool IsReadOnlyHandle(uword address); - // The returned string has to be free()ed. static char* FeaturesString(IsolateGroup* isolate_group, bool is_vm_snapshot, @@ -152,7 +145,6 @@ class Dart : public AllStatic { static Isolate* vm_isolate_; static int64_t start_time_micros_; static ThreadPool* thread_pool_; - static ReadOnlyHandles* predefined_handles_; static Snapshot::Kind vm_snapshot_kind_; static Dart_ThreadStartCallback thread_start_callback_; static Dart_ThreadExitCallback thread_exit_callback_; diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc index 7052fdebe01..dcd3faeb93d 100644 --- a/runtime/vm/dart_api_impl.cc +++ b/runtime/vm/dart_api_impl.cc @@ -102,13 +102,6 @@ DEFINE_FLAG(bool, } \ } -Dart_Handle Api::true_handle_ = nullptr; -Dart_Handle Api::false_handle_ = nullptr; -Dart_Handle Api::null_handle_ = nullptr; -Dart_Handle Api::empty_string_handle_ = nullptr; -Dart_Handle Api::no_callbacks_error_handle_ = nullptr; -Dart_Handle Api::unwind_in_progress_error_handle_ = nullptr; - const char* CanonicalFunction(const char* func) { if (strncmp(func, "dart::", 6) == 0) { return func + 6; @@ -499,8 +492,8 @@ bool Api::IsValid(Dart_Handle handle) { reinterpret_cast(handle)) || isolate_group->api_state()->IsActiveWeakPersistentHandle( reinterpret_cast(handle)) || - Dart::IsReadOnlyApiHandle(handle) || - Dart::IsReadOnlyHandle(reinterpret_cast(handle)); + Roots::IsReadOnlyApiHandle(reinterpret_cast(handle)) || + Roots::IsReadOnlyHandle(reinterpret_cast(handle)); } ApiLocalScope* Api::TopScope(Thread* thread) { @@ -510,13 +503,6 @@ ApiLocalScope* Api::TopScope(Thread* thread) { return scope; } -static Dart_Handle InitNewReadOnlyApiHandle(ObjectPtr raw) { - ASSERT(raw->untag()->InVMIsolateHeap()); - LocalHandle* ref = Dart::AllocateReadOnlyApiHandle(); - ref->set_ptr(raw); - return ref->apiHandle(); -} - void Api::InitHandles() { Isolate* isolate = Isolate::Current(); ASSERT(isolate != nullptr); @@ -524,35 +510,17 @@ void Api::InitHandles() { ApiState* state = isolate->group()->api_state(); ASSERT(state != nullptr); - ASSERT(true_handle_ == nullptr); - true_handle_ = InitNewReadOnlyApiHandle(Bool::True().ptr()); - - ASSERT(false_handle_ == nullptr); - false_handle_ = InitNewReadOnlyApiHandle(Bool::False().ptr()); - - ASSERT(null_handle_ == nullptr); - null_handle_ = InitNewReadOnlyApiHandle(Object::null()); - - ASSERT(empty_string_handle_ == nullptr); - empty_string_handle_ = InitNewReadOnlyApiHandle(Symbols::Empty().ptr()); - - ASSERT(no_callbacks_error_handle_ == nullptr); - no_callbacks_error_handle_ = - InitNewReadOnlyApiHandle(Object::no_callbacks_error().ptr()); - - ASSERT(unwind_in_progress_error_handle_ == nullptr); - unwind_in_progress_error_handle_ = - InitNewReadOnlyApiHandle(Object::unwind_in_progress_error().ptr()); + Roots::true_api_handle()->set_ptr(Bool::True().ptr()); + Roots::false_api_handle()->set_ptr(Bool::False().ptr()); + Roots::null_api_handle()->set_ptr(Object::null()); + Roots::empty_string_api_handle()->set_ptr(Symbols::Empty().ptr()); + Roots::no_callbacks_error_api_handle()->set_ptr( + Object::no_callbacks_error().ptr()); + Roots::unwind_in_progress_error_api_handle()->set_ptr( + Object::unwind_in_progress_error().ptr()); } -void Api::Cleanup() { - true_handle_ = nullptr; - false_handle_ = nullptr; - null_handle_ = nullptr; - empty_string_handle_ = nullptr; - no_callbacks_error_handle_ = nullptr; - unwind_in_progress_error_handle_ = nullptr; -} +void Api::Cleanup() {} bool Api::StringGetPeerHelper(NativeArguments* arguments, int arg_index, diff --git a/runtime/vm/dart_api_impl.h b/runtime/vm/dart_api_impl.h index a01d1a869dd..9859f256741 100644 --- a/runtime/vm/dart_api_impl.h +++ b/runtime/vm/dart_api_impl.h @@ -217,31 +217,40 @@ class Api : AllStatic { PRINTF_ATTRIBUTE(1, 2); // Gets a handle to Null. - static Dart_Handle Null() { return null_handle_; } + static Dart_Handle Null() { + return reinterpret_cast(Roots::null_api_handle()); + } // Gets a handle to True. - static Dart_Handle True() { return true_handle_; } + static Dart_Handle True() { + return reinterpret_cast(Roots::true_api_handle()); + } // Gets a handle to False. - static Dart_Handle False() { return false_handle_; } + static Dart_Handle False() { + return reinterpret_cast(Roots::false_api_handle()); + } // Gets a handle to EmptyString. - static Dart_Handle EmptyString() { return empty_string_handle_; } + static Dart_Handle EmptyString() { + return reinterpret_cast(Roots::empty_string_api_handle()); + } // Gets the handle which holds the pre-created acquired error object. - static Dart_Handle NoCallbacksError() { return no_callbacks_error_handle_; } + static Dart_Handle NoCallbacksError() { + return reinterpret_cast( + Roots::no_callbacks_error_api_handle()); + } // Gets the handle for unwind-is-in-progress error. static Dart_Handle UnwindInProgressError() { - return unwind_in_progress_error_handle_; + return reinterpret_cast( + Roots::unwind_in_progress_error_api_handle()); } static bool IsProtectedHandle(Dart_Handle object) { if (object == nullptr) return false; - return (object == true_handle_) || (object == false_handle_) || - (object == null_handle_) || (object == empty_string_handle_) || - (object == no_callbacks_error_handle_) || - (object == unwind_in_progress_error_handle_); + return Roots::IsReadOnlyApiHandle(reinterpret_cast(object)); } // Retrieves the top ApiLocalScope. @@ -310,13 +319,6 @@ class Api : AllStatic { static StringPtr CallEnvironmentCallback(Thread* thread, const String& name); - static Dart_Handle true_handle_; - static Dart_Handle false_handle_; - static Dart_Handle null_handle_; - static Dart_Handle empty_string_handle_; - static Dart_Handle no_callbacks_error_handle_; - static Dart_Handle unwind_in_progress_error_handle_; - friend class ApiNativeScope; }; diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc index f15cab25565..a0fa05f8131 100644 --- a/runtime/vm/dart_entry.cc +++ b/runtime/vm/dart_entry.cc @@ -15,6 +15,7 @@ #include "vm/log.h" #include "vm/object_store.h" #include "vm/resolver.h" +#include "vm/roots.h" #include "vm/runtime_entry.h" #include "vm/simulator.h" #include "vm/stub_code.h" @@ -29,9 +30,6 @@ namespace dart { DECLARE_FLAG(bool, precompiled_mode); -// A cache of VM heap allocated arguments descriptors. -ArrayPtr ArgumentsDescriptor::cached_args_descriptors_[kCachedDescriptorCount]; - ObjectPtr DartEntry::InvokeFunction(const Function& function, const Array& arguments) { ASSERT(Thread::Current()->IsDartMutatorThread()); @@ -487,8 +485,8 @@ bool ArgumentsDescriptor::IsCached() const { const intptr_t num_type_arguments = TypeArgsLen(); const intptr_t num_arguments = Count(); return CanUseCachedDescriptor(num_type_arguments, num_arguments) && - (array_.ptr() == cached_args_descriptors_[CacheIndexFor( - num_type_arguments, num_arguments)]); + (array_.ptr() == Roots::cached_args_descriptor(CacheIndexFor( + num_type_arguments, num_arguments))); } ArrayPtr ArgumentsDescriptor::New(intptr_t type_args_len, @@ -570,8 +568,8 @@ ArrayPtr ArgumentsDescriptor::New(intptr_t type_args_len, if (num_arguments == size_arguments && CanUseCachedDescriptor(type_args_len, num_arguments)) { - return cached_args_descriptors_[CacheIndexFor(type_args_len, - num_arguments)]; + return Roots::cached_args_descriptor( + CacheIndexFor(type_args_len, num_arguments)); } return NewNonCached(type_args_len, num_arguments, size_arguments, true, space); @@ -624,20 +622,16 @@ void ArgumentsDescriptor::Init() { for (intptr_t num_arguments = 0; num_arguments <= kMaxNumArgumentsForCachedDescriptor[type_args_len]; num_arguments++) { - cached_args_descriptors_[cache_index++] = + Roots::set_cached_args_descriptor( + cache_index++, NewNonCached(type_args_len, num_arguments, num_arguments, - /*canonicalize=*/false, Heap::kOld); + /*canonicalize=*/false, Heap::kOld)); } } ASSERT(cache_index == kCachedDescriptorCount); } -void ArgumentsDescriptor::Cleanup() { - for (int i = 0; i < kCachedDescriptorCount; i++) { - // Don't free pointers to RawArray objects managed by the VM. - cached_args_descriptors_[i] = nullptr; - } -} +void ArgumentsDescriptor::Cleanup() {} ObjectPtr DartLibraryCalls::InstanceCreate(const Library& lib, const String& class_name, diff --git a/runtime/vm/dart_entry.h b/runtime/vm/dart_entry.h index 6e90076f9f2..949f5d950ee 100644 --- a/runtime/vm/dart_entry.h +++ b/runtime/vm/dart_entry.h @@ -196,9 +196,6 @@ class ArgumentsDescriptor : public ValueObject { const Array& array_; - // A cache of VM heap allocated arguments descriptors. - static ArrayPtr cached_args_descriptors_[kCachedDescriptorCount]; - friend class Interpreter; friend class InterpreterHelpers; friend class VMSerializationRoots; diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc index 2104245e2d4..fe5ef505525 100644 --- a/runtime/vm/object.cc +++ b/runtime/vm/object.cc @@ -122,18 +122,8 @@ static const intptr_t kSetterPrefixLength = strlen(kSetterPrefix); static const char* const kInitPrefix = "init:"; static const intptr_t kInitPrefixLength = strlen(kInitPrefix); -// A cache of VM heap allocated preinitialized empty ic data entry arrays. -ArrayPtr ICData::cached_icdata_arrays_[kCachedICDataArrayCount]; - cpp_vtable Object::builtin_vtables_[kNumPredefinedCids] = {}; -// These are initialized to a value that will force an illegal memory access if -// they are being used. -#if defined(RAW_NULL) -#error RAW_NULL should not be defined. -#endif -#define RAW_NULL static_cast(kHeapObjectTag) - #define CHECK_ERROR(error) \ { \ ErrorPtr err = (error); \ @@ -142,58 +132,6 @@ cpp_vtable Object::builtin_vtables_[kNumPredefinedCids] = {}; } \ } -#define DEFINE_SHARED_READONLY_HANDLE(Type, name) \ - Type* Object::name##_ = nullptr; -SHARED_READONLY_HANDLES_LIST(DEFINE_SHARED_READONLY_HANDLE) -#undef DEFINE_SHARED_READONLY_HANDLE - -ObjectPtr Object::null_ = static_cast(RAW_NULL); -BoolPtr Object::true_ = static_cast(RAW_NULL); -BoolPtr Object::false_ = static_cast(RAW_NULL); -ClassPtr Object::class_class_ = static_cast(RAW_NULL); -ClassPtr Object::dynamic_class_ = static_cast(RAW_NULL); -ClassPtr Object::void_class_ = static_cast(RAW_NULL); -ClassPtr Object::type_parameters_class_ = static_cast(RAW_NULL); -ClassPtr Object::type_arguments_class_ = static_cast(RAW_NULL); -ClassPtr Object::patch_class_class_ = static_cast(RAW_NULL); -ClassPtr Object::function_class_ = static_cast(RAW_NULL); -ClassPtr Object::closure_data_class_ = static_cast(RAW_NULL); -ClassPtr Object::ffi_trampoline_data_class_ = static_cast(RAW_NULL); -ClassPtr Object::field_class_ = static_cast(RAW_NULL); -ClassPtr Object::script_class_ = static_cast(RAW_NULL); -ClassPtr Object::library_class_ = static_cast(RAW_NULL); -ClassPtr Object::namespace_class_ = static_cast(RAW_NULL); -ClassPtr Object::kernel_program_info_class_ = static_cast(RAW_NULL); -ClassPtr Object::code_class_ = static_cast(RAW_NULL); -ClassPtr Object::instructions_class_ = static_cast(RAW_NULL); -ClassPtr Object::instructions_section_class_ = static_cast(RAW_NULL); -ClassPtr Object::instructions_table_class_ = static_cast(RAW_NULL); -ClassPtr Object::object_pool_class_ = static_cast(RAW_NULL); -ClassPtr Object::pc_descriptors_class_ = static_cast(RAW_NULL); -ClassPtr Object::code_source_map_class_ = static_cast(RAW_NULL); -ClassPtr Object::compressed_stackmaps_class_ = static_cast(RAW_NULL); -ClassPtr Object::var_descriptors_class_ = static_cast(RAW_NULL); -ClassPtr Object::exception_handlers_class_ = static_cast(RAW_NULL); -ClassPtr Object::context_class_ = static_cast(RAW_NULL); -ClassPtr Object::context_scope_class_ = static_cast(RAW_NULL); -ClassPtr Object::bytecode_class_ = static_cast(RAW_NULL); -ClassPtr Object::sentinel_class_ = static_cast(RAW_NULL); -ClassPtr Object::singletargetcache_class_ = static_cast(RAW_NULL); -ClassPtr Object::unlinkedcall_class_ = static_cast(RAW_NULL); -ClassPtr Object::monomorphicsmiablecall_class_ = - static_cast(RAW_NULL); -ClassPtr Object::icdata_class_ = static_cast(RAW_NULL); -ClassPtr Object::megamorphic_cache_class_ = static_cast(RAW_NULL); -ClassPtr Object::subtypetestcache_class_ = static_cast(RAW_NULL); -ClassPtr Object::loadingunit_class_ = static_cast(RAW_NULL); -ClassPtr Object::api_error_class_ = static_cast(RAW_NULL); -ClassPtr Object::language_error_class_ = static_cast(RAW_NULL); -ClassPtr Object::unhandled_exception_class_ = static_cast(RAW_NULL); -ClassPtr Object::unwind_error_class_ = static_cast(RAW_NULL); -ClassPtr Object::weak_serialization_reference_class_ = - static_cast(RAW_NULL); -ClassPtr Object::weak_array_class_ = static_cast(RAW_NULL); - static void AppendSubString(BaseTextBuffer* buffer, const char* name, intptr_t start_pos, @@ -558,7 +496,7 @@ void Object::InitNullAndBool(IsolateGroup* isolate_group) { auto heap = isolate_group->heap(); // TODO(iposva): NoSafepointScope needs to be added here. - ASSERT(class_class() == null_); + ASSERT(class_class() == Roots::null_obj()); // Allocate and initialize the null instance. // 'null_' must be the first object allocated as it is used in allocation to @@ -566,9 +504,9 @@ void Object::InitNullAndBool(IsolateGroup* isolate_group) { { uword address = heap->Allocate(thread, Instance::InstanceSize(), Heap::kOld); - null_ = static_cast(address + kHeapObjectTag); + Roots::set_null_obj(static_cast(address + kHeapObjectTag)); InitializeObjectVariant(address, kNullCid); - null_->untag()->SetCanonical(); + Roots::null_obj()->untag()->SetCanonical(); } // Allocate and initialize the bool instances. @@ -584,32 +522,32 @@ void Object::InitNullAndBool(IsolateGroup* isolate_group) { { // Allocate true. uword address = heap->Allocate(thread, Bool::InstanceSize(), Heap::kOld); - true_ = static_cast(address + kHeapObjectTag); + Roots::set_true_obj(static_cast(address + kHeapObjectTag)); InitializeObject(address); - true_->untag()->value_ = true; - true_->untag()->SetCanonical(); + Roots::true_obj()->untag()->value_ = true; + Roots::true_obj()->untag()->SetCanonical(); } { // Allocate false. uword address = heap->Allocate(thread, Bool::InstanceSize(), Heap::kOld); - false_ = static_cast(address + kHeapObjectTag); + Roots::set_false_obj(static_cast(address + kHeapObjectTag)); InitializeObject(address); - false_->untag()->value_ = false; - false_->untag()->SetCanonical(); + Roots::false_obj()->untag()->value_ = false; + Roots::false_obj()->untag()->SetCanonical(); } // Check that the objects have been allocated at appropriate addresses. - ASSERT(static_cast(true_) == - static_cast(null_) + kTrueOffsetFromNull); - ASSERT(static_cast(false_) == - static_cast(null_) + kFalseOffsetFromNull); - ASSERT((static_cast(true_) & kBoolValueMask) == 0); - ASSERT((static_cast(false_) & kBoolValueMask) != 0); - ASSERT(static_cast(false_) == - (static_cast(true_) | kBoolValueMask)); - ASSERT((static_cast(null_) & kBoolVsNullMask) == 0); - ASSERT((static_cast(true_) & kBoolVsNullMask) != 0); - ASSERT((static_cast(false_) & kBoolVsNullMask) != 0); + uword null_ = static_cast(Roots::null_obj()); + uword true_ = static_cast(Roots::true_obj()); + uword false_ = static_cast(Roots::false_obj()); + ASSERT(true_ == null_ + kTrueOffsetFromNull); + ASSERT(false_ == null_ + kFalseOffsetFromNull); + ASSERT((true_ & kBoolValueMask) == 0); + ASSERT((false_ & kBoolValueMask) != 0); + ASSERT(false_ == (true_ | kBoolValueMask)); + ASSERT((null_ & kBoolVsNullMask) == 0); + ASSERT((true_ & kBoolVsNullMask) != 0); + ASSERT((false_ & kBoolVsNullMask) != 0); } void Object::InitVtables() { @@ -729,35 +667,30 @@ void Object::Init(IsolateGroup* isolate_group) { InitVtables(); -// Allocate the read only object handles here. -#define INITIALIZE_SHARED_READONLY_HANDLE(Type, name) \ - name##_ = Type::ReadOnlyHandle(); - SHARED_READONLY_HANDLES_LIST(INITIALIZE_SHARED_READONLY_HANDLE) -#undef INITIALIZE_SHARED_READONLY_HANDLE - - *null_object_ = Object::null(); - *null_class_ = Class::null(); - *null_array_ = Array::null(); - *null_string_ = String::null(); - *null_instance_ = Instance::null(); - *null_function_ = Function::null(); - *null_function_type_ = FunctionType::null(); - *null_record_type_ = RecordType::null(); - *null_type_arguments_ = TypeArguments::null(); - *null_closure_ = Closure::null(); - *empty_type_arguments_ = TypeArguments::null(); - *null_abstract_type_ = AbstractType::null(); - *null_compressed_stackmaps_ = CompressedStackMaps::null(); - *bool_true_ = true_; - *bool_false_ = false_; + // Allocate the read only object handles here. + Roots::null_object().initRO(Object::null()); + Roots::null_class().initRO(Class::null()); + Roots::null_array().initRO(Array::null()); + Roots::null_string().initRO(String::null()); + Roots::null_instance().initRO(Instance::null()); + Roots::null_function().initRO(Function::null()); + Roots::null_function_type().initRO(FunctionType::null()); + Roots::null_record_type().initRO(RecordType::null()); + Roots::null_type_arguments().initRO(TypeArguments::null()); + Roots::null_closure().initRO(Closure::null()); + Roots::empty_type_arguments().initRO(TypeArguments::null()); + Roots::null_abstract_type().initRO(AbstractType::null()); + Roots::null_compressed_stackmaps().initRO(CompressedStackMaps::null()); + Roots::bool_true().initRO(Roots::true_obj()); + Roots::bool_false().initRO(Roots::false_obj()); // Initialize the empty array and empty instantiations cache array handles to // null_ in order to be able to check if the empty and zero arrays were // allocated (RAW_NULL is not available). - *empty_array_ = Array::null(); - *empty_instantiations_cache_array_ = Array::null(); - *empty_subtype_test_cache_array_ = Array::null(); - *mutable_empty_array_ = Array::null(); + Roots::empty_array().initRO(Array::null()); + Roots::empty_instantiations_cache_array().initRO(Array::null()); + Roots::empty_subtype_test_cache_array().initRO(Array::null()); + Roots::mutable_empty_array().initRO(Array::null()); Class& cls = Class::Handle(); @@ -765,14 +698,14 @@ void Object::Init(IsolateGroup* isolate_group) { { intptr_t size = Class::InstanceSize(); uword address = heap->Allocate(thread, size, Heap::kOld); - class_class_ = static_cast(address + kHeapObjectTag); + Roots::set_class_class(static_cast(address + kHeapObjectTag)); InitializeObject(address); Class fake; // Initialization from Class::New. // Directly set ptr_ to break a circular dependency: SetRaw will attempt // to lookup class class in the class table where it is not registered yet. - cls.ptr_ = class_class_; + cls.ptr_ = Roots::class_class(); ASSERT(builtin_vtables_[kClassCid] == fake.vtable()); cls.set_instance_size( Class::InstanceSize(), @@ -826,138 +759,138 @@ void Object::Init(IsolateGroup* isolate_group) { // Allocate and initialize Sentinel class. cls = Class::New(isolate_group); - sentinel_class_ = cls.ptr(); + Roots::set_sentinel_class(cls.ptr()); // Allocate and initialize the sentinel values. { - *sentinel_ ^= Sentinel::New(); + Roots::sentinel().initRO(Sentinel::New()); } // Allocate and initialize optimizing compiler constants. { - *unknown_constant_ ^= Sentinel::New(); - *non_constant_ ^= Sentinel::New(); - *optimized_out_ ^= Sentinel::New(); + Roots::unknown_constant().initRO(Sentinel::New()); + Roots::non_constant().initRO(Sentinel::New()); + Roots::optimized_out().initRO(Sentinel::New()); } // Allocate the remaining VM internal classes. cls = Class::New(isolate_group); - type_parameters_class_ = cls.ptr(); + Roots::set_type_parameters_class(cls.ptr()); cls = Class::New(isolate_group); - type_arguments_class_ = cls.ptr(); + Roots::set_type_arguments_class(cls.ptr()); cls = Class::New(isolate_group); - patch_class_class_ = cls.ptr(); + Roots::set_patch_class_class(cls.ptr()); cls = Class::New(isolate_group); - function_class_ = cls.ptr(); + Roots::set_function_class(cls.ptr()); cls = Class::New(isolate_group); - closure_data_class_ = cls.ptr(); + Roots::set_closure_data_class(cls.ptr()); cls = Class::New(isolate_group); - ffi_trampoline_data_class_ = cls.ptr(); + Roots::set_ffi_trampoline_data_class(cls.ptr()); cls = Class::New(isolate_group); - field_class_ = cls.ptr(); + Roots::set_field_class(cls.ptr()); cls = Class::New(isolate_group); - script_class_ = cls.ptr(); + Roots::set_script_class(cls.ptr()); cls = Class::New(isolate_group); - library_class_ = cls.ptr(); + Roots::set_library_class(cls.ptr()); cls = Class::New(isolate_group); - namespace_class_ = cls.ptr(); + Roots::set_namespace_class(cls.ptr()); cls = Class::New(isolate_group); - kernel_program_info_class_ = cls.ptr(); + Roots::set_kernel_program_info_class(cls.ptr()); cls = Class::New(isolate_group); - code_class_ = cls.ptr(); + Roots::set_code_class(cls.ptr()); cls = Class::New(isolate_group); - instructions_class_ = cls.ptr(); + Roots::set_instructions_class(cls.ptr()); cls = Class::New(isolate_group); - instructions_section_class_ = cls.ptr(); + Roots::set_instructions_section_class(cls.ptr()); cls = Class::New(isolate_group); - instructions_table_class_ = cls.ptr(); + Roots::set_instructions_table_class(cls.ptr()); cls = Class::New(isolate_group); - object_pool_class_ = cls.ptr(); + Roots::set_object_pool_class(cls.ptr()); cls = Class::New(isolate_group); - pc_descriptors_class_ = cls.ptr(); + Roots::set_pc_descriptors_class(cls.ptr()); cls = Class::New(isolate_group); - code_source_map_class_ = cls.ptr(); + Roots::set_code_source_map_class(cls.ptr()); cls = Class::New(isolate_group); - compressed_stackmaps_class_ = cls.ptr(); + Roots::set_compressed_stackmaps_class(cls.ptr()); cls = Class::New(isolate_group); - var_descriptors_class_ = cls.ptr(); + Roots::set_var_descriptors_class(cls.ptr()); cls = Class::New(isolate_group); - exception_handlers_class_ = cls.ptr(); + Roots::set_exception_handlers_class(cls.ptr()); cls = Class::New(isolate_group); - context_class_ = cls.ptr(); + Roots::set_context_class(cls.ptr()); cls = Class::New(isolate_group); - context_scope_class_ = cls.ptr(); + Roots::set_context_scope_class(cls.ptr()); cls = Class::New(isolate_group); - bytecode_class_ = cls.ptr(); + Roots::set_bytecode_class(cls.ptr()); cls = Class::New(isolate_group); - singletargetcache_class_ = cls.ptr(); + Roots::set_singletargetcache_class(cls.ptr()); cls = Class::New(isolate_group); - unlinkedcall_class_ = cls.ptr(); + Roots::set_unlinkedcall_class(cls.ptr()); cls = Class::New( isolate_group); - monomorphicsmiablecall_class_ = cls.ptr(); + Roots::set_monomorphicsmiablecall_class(cls.ptr()); cls = Class::New(isolate_group); - icdata_class_ = cls.ptr(); + Roots::set_icdata_class(cls.ptr()); cls = Class::New(isolate_group); - megamorphic_cache_class_ = cls.ptr(); + Roots::set_megamorphic_cache_class(cls.ptr()); cls = Class::New(isolate_group); - subtypetestcache_class_ = cls.ptr(); + Roots::set_subtypetestcache_class(cls.ptr()); cls = Class::New(isolate_group); - loadingunit_class_ = cls.ptr(); + Roots::set_loadingunit_class(cls.ptr()); cls = Class::New(isolate_group); - api_error_class_ = cls.ptr(); + Roots::set_api_error_class(cls.ptr()); cls = Class::New(isolate_group); - language_error_class_ = cls.ptr(); + Roots::set_language_error_class(cls.ptr()); cls = Class::New(isolate_group); - unhandled_exception_class_ = cls.ptr(); + Roots::set_unhandled_exception_class(cls.ptr()); cls = Class::New(isolate_group); - unwind_error_class_ = cls.ptr(); + Roots::set_unwind_error_class(cls.ptr()); cls = Class::New( isolate_group); - weak_serialization_reference_class_ = cls.ptr(); + Roots::set_weak_serialization_reference_class(cls.ptr()); cls = Class::New(isolate_group); - weak_array_class_ = cls.ptr(); + Roots::set_weak_array_class(cls.ptr()); - ASSERT(class_class() != null_); + ASSERT(class_class() != Roots::null_obj()); // Pre-allocate classes in the vm isolate so that we can for example create a // symbol table and populate it with some frequently used strings as symbols. @@ -1008,20 +941,20 @@ void Object::Init(IsolateGroup* isolate_group) { { uword address = heap->Allocate(thread, Array::InstanceSize(0), Heap::kOld); InitializeObjectVariant(address, kImmutableArrayCid, 0); - Array::initializeHandle(empty_array_, - static_cast(address + kHeapObjectTag)); - empty_array_->untag()->set_length(Smi::New(0)); - empty_array_->SetCanonical(); - empty_array_->SetDeeplyImmutable(); + Roots::empty_array().initRO( + static_cast(address + kHeapObjectTag)); + Roots::empty_array().untag()->set_length(Smi::New(0)); + Roots::empty_array().SetCanonical(); + Roots::empty_array().SetDeeplyImmutable(); } { uword address = heap->Allocate(thread, Array::InstanceSize(0), Heap::kOld); InitializeObjectVariant(address, kArrayCid, 0); - Array::initializeHandle(mutable_empty_array_, - static_cast(address + kHeapObjectTag)); - mutable_empty_array_->untag()->set_length(Smi::New(0)); - mutable_empty_array_->SetCanonical(); - mutable_empty_array_->SetDeeplyImmutable(); + Roots::mutable_empty_array().initRO( + static_cast(address + kHeapObjectTag)); + Roots::mutable_empty_array().untag()->set_length(Smi::New(0)); + Roots::mutable_empty_array().SetCanonical(); + Roots::mutable_empty_array().SetDeeplyImmutable(); } Smi& smi = Smi::Handle(); @@ -1035,21 +968,21 @@ void Object::Init(IsolateGroup* isolate_group) { uword address = heap->Allocate(thread, Array::InstanceSize(array_size), Heap::kOld); InitializeObjectVariant(address, kImmutableArrayCid, array_size); - Array::initializeHandle(empty_instantiations_cache_array_, - static_cast(address + kHeapObjectTag)); - empty_instantiations_cache_array_->untag()->set_length( + Roots::empty_instantiations_cache_array().initRO( + static_cast(address + kHeapObjectTag)); + Roots::empty_instantiations_cache_array().untag()->set_length( Smi::New(array_size)); // The empty cache has no occupied entries and is not a hash-based cache. smi = Smi::New(0); - empty_instantiations_cache_array_->SetAt( + Roots::empty_instantiations_cache_array().SetAt( TypeArguments::Cache::kMetadataIndex, smi); // Make the first (and only) entry unoccupied by setting its first element // to the sentinel value. smi = TypeArguments::Cache::Sentinel(); - InstantiationsCacheTable table(*empty_instantiations_cache_array_); + InstantiationsCacheTable table(Roots::empty_instantiations_cache_array()); table.At(0).Set(smi); // The other contents of the array are immaterial. - empty_instantiations_cache_array_->SetCanonical(); + Roots::empty_instantiations_cache_array().SetCanonical(); } // Allocate and initialize the empty subtype test cache array instance, @@ -1059,19 +992,20 @@ void Object::Init(IsolateGroup* isolate_group) { uword address = heap->Allocate(thread, Array::InstanceSize(array_size), Heap::kOld); InitializeObjectVariant(address, kImmutableArrayCid, array_size); - Array::initializeHandle(empty_subtype_test_cache_array_, - static_cast(address + kHeapObjectTag)); - empty_subtype_test_cache_array_->untag()->set_length(Smi::New(array_size)); + Roots::empty_subtype_test_cache_array().initRO( + static_cast(address + kHeapObjectTag)); + Roots::empty_subtype_test_cache_array().untag()->set_length( + Smi::New(array_size)); // Make the first (and only) entry unoccupied by setting its first element // to the null value. - empty_subtype_test_cache_array_->SetAt( + Roots::empty_subtype_test_cache_array().SetAt( SubtypeTestCache::kInstanceCidOrSignature, Object::null_object()); smi = TypeArguments::Cache::Sentinel(); - SubtypeTestCacheTable table(*empty_subtype_test_cache_array_); + SubtypeTestCacheTable table(Roots::empty_subtype_test_cache_array()); table.At(0).Set( Object::null_object()); // The other contents of the array are immaterial. - empty_subtype_test_cache_array_->SetCanonical(); + Roots::empty_subtype_test_cache_array().SetCanonical(); } // Allocate and initialize the canonical empty context scope object. @@ -1079,14 +1013,13 @@ void Object::Init(IsolateGroup* isolate_group) { uword address = heap->Allocate(thread, ContextScope::InstanceSize(0), Heap::kOld); InitializeObject(address, 0); - ContextScope::initializeHandle( - empty_context_scope_, + Roots::empty_context_scope().initRO( static_cast(address + kHeapObjectTag)); - empty_context_scope_->StoreNonPointer( - &empty_context_scope_->untag()->num_variables_, 0); - empty_context_scope_->StoreNonPointer( - &empty_context_scope_->untag()->is_implicit_, true); - empty_context_scope_->SetCanonical(); + Roots::empty_context_scope().StoreNonPointer( + &Roots::empty_context_scope().untag()->num_variables_, 0); + Roots::empty_context_scope().StoreNonPointer( + &Roots::empty_context_scope().untag()->is_implicit_, true); + Roots::empty_context_scope().SetCanonical(); } // Allocate and initialize the canonical empty object pool object. @@ -1094,12 +1027,11 @@ void Object::Init(IsolateGroup* isolate_group) { uword address = heap->Allocate(thread, ObjectPool::InstanceSize(0), Heap::kOld); InitializeObject(address, 0); - ObjectPool::initializeHandle( - empty_object_pool_, + Roots::empty_object_pool().initRO( static_cast(address + kHeapObjectTag)); - empty_object_pool_->StoreNonPointer(&empty_object_pool_->untag()->length_, - 0); - empty_object_pool_->SetCanonical(); + Roots::empty_object_pool().StoreNonPointer( + &Roots::empty_object_pool().untag()->length_, 0); + Roots::empty_object_pool().SetCanonical(); } // Allocate and initialize the empty_compressed_stackmaps instance. @@ -1107,11 +1039,11 @@ void Object::Init(IsolateGroup* isolate_group) { const intptr_t instance_size = CompressedStackMaps::InstanceSize(0); uword address = heap->Allocate(thread, instance_size, Heap::kOld); InitializeObject(address, 0); - CompressedStackMaps::initializeHandle( - empty_compressed_stackmaps_, + Roots::empty_compressed_stackmaps().initRO( static_cast(address + kHeapObjectTag)); - empty_compressed_stackmaps_->untag()->payload()->set_flags_and_size(0); - empty_compressed_stackmaps_->SetCanonical(); + Roots::empty_compressed_stackmaps().untag()->payload()->set_flags_and_size( + 0); + Roots::empty_compressed_stackmaps().SetCanonical(); } // Allocate and initialize the empty_descriptors instance. @@ -1119,12 +1051,11 @@ void Object::Init(IsolateGroup* isolate_group) { uword address = heap->Allocate(thread, PcDescriptors::InstanceSize(0), Heap::kOld); InitializeObject(address, 0); - PcDescriptors::initializeHandle( - empty_descriptors_, + Roots::empty_descriptors().initRO( static_cast(address + kHeapObjectTag)); - empty_descriptors_->StoreNonPointer(&empty_descriptors_->untag()->length_, - 0); - empty_descriptors_->SetCanonical(); + Roots::empty_descriptors().StoreNonPointer( + &Roots::empty_descriptors().untag()->length_, 0); + Roots::empty_descriptors().SetCanonical(); } // Allocate and initialize the canonical empty variable descriptor object. @@ -1132,12 +1063,11 @@ void Object::Init(IsolateGroup* isolate_group) { uword address = heap->Allocate(thread, LocalVarDescriptors::InstanceSize(0), Heap::kOld); InitializeObject(address, 0); - LocalVarDescriptors::initializeHandle( - empty_var_descriptors_, + Roots::empty_var_descriptors().initRO( static_cast(address + kHeapObjectTag)); - empty_var_descriptors_->StoreNonPointer( - &empty_var_descriptors_->untag()->num_entries_, 0); - empty_var_descriptors_->SetCanonical(); + Roots::empty_var_descriptors().StoreNonPointer( + &Roots::empty_var_descriptors().untag()->num_entries_, 0); + Roots::empty_var_descriptors().SetCanonical(); } // Allocate and initialize the canonical empty exception handler info object. @@ -1147,12 +1077,11 @@ void Object::Init(IsolateGroup* isolate_group) { uword address = heap->Allocate(thread, ExceptionHandlers::InstanceSize(0), Heap::kOld); InitializeObject(address, 0); - ExceptionHandlers::initializeHandle( - empty_exception_handlers_, + Roots::empty_exception_handlers().initRO( static_cast(address + kHeapObjectTag)); - empty_exception_handlers_->StoreNonPointer( - &empty_exception_handlers_->untag()->packed_fields_, 0); - empty_exception_handlers_->SetCanonical(); + Roots::empty_exception_handlers().StoreNonPointer( + &Roots::empty_exception_handlers().untag()->packed_fields_, 0); + Roots::empty_exception_handlers().SetCanonical(); } // Empty exception handlers for async/async* functions. @@ -1160,13 +1089,12 @@ void Object::Init(IsolateGroup* isolate_group) { uword address = heap->Allocate(thread, ExceptionHandlers::InstanceSize(0), Heap::kOld); InitializeObject(address, 0); - ExceptionHandlers::initializeHandle( - empty_async_exception_handlers_, + Roots::empty_async_exception_handlers().initRO( static_cast(address + kHeapObjectTag)); - empty_async_exception_handlers_->StoreNonPointer( - &empty_async_exception_handlers_->untag()->packed_fields_, + Roots::empty_async_exception_handlers().StoreNonPointer( + &Roots::empty_async_exception_handlers().untag()->packed_fields_, UntaggedExceptionHandlers::AsyncHandlerBit::update(true, 0)); - empty_async_exception_handlers_->SetCanonical(); + Roots::empty_async_exception_handlers().SetCanonical(); } // Allocate and initialize the canonical empty type arguments object. @@ -1174,18 +1102,17 @@ void Object::Init(IsolateGroup* isolate_group) { uword address = heap->Allocate(thread, TypeArguments::InstanceSize(0), Heap::kOld); InitializeObject(address, 0); - TypeArguments::initializeHandle( - empty_type_arguments_, + Roots::empty_type_arguments().initRO( static_cast(address + kHeapObjectTag)); - empty_type_arguments_->untag()->set_length(Smi::New(0)); - empty_type_arguments_->untag()->set_hash(Smi::New(0)); - empty_type_arguments_->ComputeHash(); - empty_type_arguments_->SetCanonical(); + Roots::empty_type_arguments().untag()->set_length(Smi::New(0)); + Roots::empty_type_arguments().untag()->set_hash(Smi::New(0)); + Roots::empty_type_arguments().ComputeHash(); + Roots::empty_type_arguments().SetCanonical(); } // The VM isolate snapshot object table is initialized to an empty array // as we do not have any VM isolate snapshot at this time. - *vm_isolate_snapshot_object_table_ = Object::empty_array().ptr(); + Roots::vm_isolate_snapshot_object_table().initRO(Object::empty_array().ptr()); cls = Class::New(kDynamicCid, isolate_group); cls.set_is_abstract(); @@ -1193,14 +1120,14 @@ void Object::Init(IsolateGroup* isolate_group) { cls.set_is_allocate_finalized(); cls.set_is_declaration_loaded(); cls.set_is_type_finalized(); - dynamic_class_ = cls.ptr(); + Roots::set_dynamic_class(cls.ptr()); cls = Class::New(kVoidCid, isolate_group); cls.set_num_type_arguments_unsafe(0); cls.set_is_allocate_finalized(); cls.set_is_declaration_loaded(); cls.set_is_type_finalized(); - void_class_ = cls.ptr(); + Roots::set_void_class(cls.ptr()); cls = Class::New(isolate_group); cls.set_is_allocate_finalized(); @@ -1217,25 +1144,25 @@ void Object::Init(IsolateGroup* isolate_group) { cls.set_is_declaration_loaded(); cls.set_is_type_finalized(); - cls = dynamic_class_; - *dynamic_type_ = - Type::New(cls, Object::null_type_arguments(), Nullability::kNullable); - dynamic_type_->SetIsFinalized(); - dynamic_type_->ComputeHash(); - dynamic_type_->SetCanonical(); + cls = Roots::dynamic_class(); + Roots::dynamic_type().initRO( + Type::New(cls, Object::null_type_arguments(), Nullability::kNullable)); + Roots::dynamic_type().SetIsFinalized(); + Roots::dynamic_type().ComputeHash(); + Roots::dynamic_type().SetCanonical(); - cls = void_class_; - *void_type_ = - Type::New(cls, Object::null_type_arguments(), Nullability::kNullable); - void_type_->SetIsFinalized(); - void_type_->ComputeHash(); - void_type_->SetCanonical(); + cls = Roots::void_class(); + Roots::void_type().initRO( + Type::New(cls, Object::null_type_arguments(), Nullability::kNullable)); + Roots::void_type().SetIsFinalized(); + Roots::void_type().ComputeHash(); + Roots::void_type().SetCanonical(); // Since TypeArguments objects are passed as function arguments, make them // behave as Dart instances, although they are just VM objects. // Note that we cannot set the super type to ObjectType, which does not live // in the vm isolate. See special handling in Class::SuperClass(). - cls = type_arguments_class_; + cls = Roots::type_arguments_class(); cls.set_interfaces(Object::empty_array()); cls.SetFields(Object::empty_array()); cls.SetFunctions(Object::empty_array()); @@ -1243,8 +1170,8 @@ void Object::Init(IsolateGroup* isolate_group) { cls = Class::New(isolate_group); isolate_group->object_store()->set_bool_class(cls); - *smi_illegal_cid_ = Smi::New(kIllegalCid); - *smi_zero_ = Smi::New(0); + Roots::smi_illegal_cid().initRO(Smi::New(kIllegalCid)); + Roots::smi_zero().initRO(Smi::New(0)); String& error_str = String::Handle(); error_str = String::New( @@ -1252,196 +1179,203 @@ void Object::Init(IsolateGroup* isolate_group) { "outstanding pointers from Dart_TypedDataAcquireData that have not been " "released with Dart_TypedDataReleaseData, or a finalizer is running.", Heap::kOld); - *no_callbacks_error_ = ApiError::New(error_str, Heap::kOld); + Roots::no_callbacks_error().initRO(ApiError::New(error_str, Heap::kOld)); error_str = String::New("isolate is exiting", Heap::kOld); - *unwind_error_ = UnwindError::New(error_str, Heap::kOld); + Roots::unwind_error().initRO(UnwindError::New(error_str, Heap::kOld)); error_str = String::New( "No api calls are allowed while unwind is in progress", Heap::kOld); - *unwind_in_progress_error_ = UnwindError::New(error_str, Heap::kOld); + Roots::unwind_in_progress_error().initRO( + UnwindError::New(error_str, Heap::kOld)); error_str = String::New("SnapshotWriter Error", Heap::kOld); - *snapshot_writer_error_ = - LanguageError::New(error_str, Report::kError, Heap::kOld); + Roots::snapshot_writer_error().initRO( + LanguageError::New(error_str, Report::kError, Heap::kOld)); error_str = String::New("Branch offset overflow", Heap::kOld); - *branch_offset_error_ = - LanguageError::New(error_str, Report::kBailout, Heap::kOld); + Roots::branch_offset_error().initRO( + LanguageError::New(error_str, Report::kBailout, Heap::kOld)); error_str = String::New("Background Compilation Failed", Heap::kOld); - *background_compilation_error_ = - LanguageError::New(error_str, Report::kBailout, Heap::kOld); + Roots::background_compilation_error().initRO( + LanguageError::New(error_str, Report::kBailout, Heap::kOld)); error_str = String::New("No debuggable code where breakpoint was requested", Heap::kOld); - *no_debuggable_code_error_ = - LanguageError::New(error_str, Report::kError, Heap::kOld); + Roots::no_debuggable_code_error().initRO( + LanguageError::New(error_str, Report::kError, Heap::kOld)); error_str = String::New("Out of memory", Heap::kOld); - *out_of_memory_error_ = - LanguageError::New(error_str, Report::kError, Heap::kOld); - *unhandled_oom_exception_ = - UnhandledException::New(error_str, StackTrace::Handle(), Heap::kOld); + Roots::out_of_memory_error().initRO( + LanguageError::New(error_str, Report::kError, Heap::kOld)); + Roots::unhandled_oom_exception().initRO( + UnhandledException::New(error_str, StackTrace::Handle(), Heap::kOld)); // Allocate the parameter types and names for synthetic getters. - *synthetic_getter_parameter_types_ = Array::New(1, Heap::kOld); - synthetic_getter_parameter_types_->SetAt(0, Object::dynamic_type()); - *synthetic_getter_parameter_names_ = Array::New(1, Heap::kOld); + Roots::synthetic_getter_parameter_types().initRO(Array::New(1, Heap::kOld)); + Roots::synthetic_getter_parameter_types().SetAt(0, Object::dynamic_type()); + Roots::synthetic_getter_parameter_names().initRO(Array::New(1, Heap::kOld)); // Fill in synthetic_getter_parameter_names_ later, after symbols are // initialized (in Object::FinalizeVMIsolate). // synthetic_getter_parameter_names_ object needs to be created earlier as // VM isolate snapshot reader references it before Object::FinalizeVMIsolate. #if defined(DART_DYNAMIC_MODULES) - *implicit_getter_bytecode_ = - CreateVMInternalBytecode(KernelBytecode::kVMInternal_ImplicitGetter); - - *implicit_setter_bytecode_ = - CreateVMInternalBytecode(KernelBytecode::kVMInternal_ImplicitSetter); - - *implicit_static_getter_bytecode_ = CreateVMInternalBytecode( - KernelBytecode::kVMInternal_ImplicitStaticGetter); - - *implicit_shared_static_getter_bytecode_ = CreateVMInternalBytecode( - KernelBytecode::kVMInternal_ImplicitSharedStaticGetter); - - *implicit_static_setter_bytecode_ = CreateVMInternalBytecode( - KernelBytecode::kVMInternal_ImplicitStaticSetter); - - *implicit_shared_static_setter_bytecode_ = CreateVMInternalBytecode( - KernelBytecode::kVMInternal_ImplicitSharedStaticSetter); - - *method_extractor_bytecode_ = - CreateVMInternalBytecode(KernelBytecode::kVMInternal_MethodExtractor); - - *invoke_closure_bytecode_ = - CreateVMInternalBytecode(KernelBytecode::kVMInternal_InvokeClosure); - - *invoke_field_bytecode_ = - CreateVMInternalBytecode(KernelBytecode::kVMInternal_InvokeField); - - *nsm_dispatcher_bytecode_ = CreateVMInternalBytecode( - KernelBytecode::kVMInternal_NoSuchMethodDispatcher); - - *dynamic_invocation_forwarder_bytecode_ = CreateVMInternalBytecode( - KernelBytecode::kVMInternal_ForwardDynamicInvocation); - - *implicit_static_closure_bytecode_ = CreateVMInternalBytecode( - KernelBytecode::kVMInternal_ImplicitStaticClosure); - - *implicit_instance_closure_bytecode_ = CreateVMInternalBytecode( - KernelBytecode::kVMInternal_ImplicitInstanceClosure); - - *implicit_constructor_closure_bytecode_ = CreateVMInternalBytecode( - KernelBytecode::kVMInternal_ImplicitConstructorClosure); + Roots::implicit_getter_bytecode().initRO( + CreateVMInternalBytecode(KernelBytecode::kVMInternal_ImplicitGetter)); + Roots::implicit_setter_bytecode().initRO( + CreateVMInternalBytecode(KernelBytecode::kVMInternal_ImplicitSetter)); + Roots::implicit_static_getter_bytecode().initRO(CreateVMInternalBytecode( + KernelBytecode::kVMInternal_ImplicitStaticGetter)); + Roots::implicit_shared_static_getter_bytecode().initRO( + CreateVMInternalBytecode( + KernelBytecode::kVMInternal_ImplicitSharedStaticGetter)); + Roots::implicit_static_setter_bytecode().initRO(CreateVMInternalBytecode( + KernelBytecode::kVMInternal_ImplicitStaticSetter)); + Roots::implicit_shared_static_setter_bytecode().initRO( + CreateVMInternalBytecode( + KernelBytecode::kVMInternal_ImplicitSharedStaticSetter)); + Roots::method_extractor_bytecode().initRO( + CreateVMInternalBytecode(KernelBytecode::kVMInternal_MethodExtractor)); + Roots::invoke_closure_bytecode().initRO( + CreateVMInternalBytecode(KernelBytecode::kVMInternal_InvokeClosure)); + Roots::invoke_field_bytecode().initRO( + CreateVMInternalBytecode(KernelBytecode::kVMInternal_InvokeField)); + Roots::nsm_dispatcher_bytecode().initRO(CreateVMInternalBytecode( + KernelBytecode::kVMInternal_NoSuchMethodDispatcher)); + Roots::dynamic_invocation_forwarder_bytecode().initRO( + CreateVMInternalBytecode( + KernelBytecode::kVMInternal_ForwardDynamicInvocation)); + Roots::implicit_static_closure_bytecode().initRO(CreateVMInternalBytecode( + KernelBytecode::kVMInternal_ImplicitStaticClosure)); + Roots::implicit_instance_closure_bytecode().initRO(CreateVMInternalBytecode( + KernelBytecode::kVMInternal_ImplicitInstanceClosure)); + Roots::implicit_constructor_closure_bytecode().initRO( + CreateVMInternalBytecode( + KernelBytecode::kVMInternal_ImplicitConstructorClosure)); +#else + Roots::implicit_getter_bytecode().initRO(Bytecode::null()); + Roots::implicit_setter_bytecode().initRO(Bytecode::null()); + Roots::implicit_static_getter_bytecode().initRO(Bytecode::null()); + Roots::implicit_shared_static_getter_bytecode().initRO(Bytecode::null()); + Roots::implicit_static_setter_bytecode().initRO(Bytecode::null()); + Roots::implicit_shared_static_setter_bytecode().initRO(Bytecode::null()); + Roots::method_extractor_bytecode().initRO(Bytecode::null()); + Roots::invoke_closure_bytecode().initRO(Bytecode::null()); + Roots::invoke_field_bytecode().initRO(Bytecode::null()); + Roots::nsm_dispatcher_bytecode().initRO(Bytecode::null()); + Roots::dynamic_invocation_forwarder_bytecode().initRO(Bytecode::null()); + Roots::implicit_static_closure_bytecode().initRO(Bytecode::null()); + Roots::implicit_instance_closure_bytecode().initRO(Bytecode::null()); + Roots::implicit_constructor_closure_bytecode().initRO(Bytecode::null()); #endif // defined(DART_DYNAMIC_MODULES) - *uninitialized_index_ = + Roots::uninitialized_index().initRO( TypedData::New(kTypedDataUint32ArrayCid, - LinkedHashBase::kUninitializedIndexSize, Heap::kOld); - *uninitialized_data_ = Array::New(0, Heap::kOld); + LinkedHashBase::kUninitializedIndexSize, Heap::kOld)); + Roots::uninitialized_data().initRO(Array::New(0, Heap::kOld)); // Some thread fields need to be reinitialized as null constants have not been // initialized until now. thread->ClearStickyError(); - ASSERT(!null_object_->IsSmi()); - ASSERT(!null_class_->IsSmi()); - ASSERT(null_class_->IsClass()); - ASSERT(!null_array_->IsSmi()); - ASSERT(null_array_->IsArray()); - ASSERT(!null_string_->IsSmi()); - ASSERT(null_string_->IsString()); - ASSERT(!null_instance_->IsSmi()); - ASSERT(null_instance_->IsInstance()); - ASSERT(!null_function_->IsSmi()); - ASSERT(null_function_->IsFunction()); - ASSERT(!null_function_type_->IsSmi()); - ASSERT(null_function_type_->IsFunctionType()); - ASSERT(!null_record_type_->IsSmi()); - ASSERT(null_record_type_->IsRecordType()); - ASSERT(!null_type_arguments_->IsSmi()); - ASSERT(null_type_arguments_->IsTypeArguments()); - ASSERT(!null_compressed_stackmaps_->IsSmi()); - ASSERT(null_compressed_stackmaps_->IsCompressedStackMaps()); - ASSERT(!empty_array_->IsSmi()); - ASSERT(empty_array_->IsArray()); - ASSERT(!empty_instantiations_cache_array_->IsSmi()); - ASSERT(empty_instantiations_cache_array_->IsArray()); - ASSERT(!empty_subtype_test_cache_array_->IsSmi()); - ASSERT(empty_subtype_test_cache_array_->IsArray()); - ASSERT(!empty_type_arguments_->IsSmi()); - ASSERT(empty_type_arguments_->IsTypeArguments()); - ASSERT(!empty_context_scope_->IsSmi()); - ASSERT(empty_context_scope_->IsContextScope()); - ASSERT(!empty_compressed_stackmaps_->IsSmi()); - ASSERT(empty_compressed_stackmaps_->IsCompressedStackMaps()); - ASSERT(!empty_descriptors_->IsSmi()); - ASSERT(empty_descriptors_->IsPcDescriptors()); - ASSERT(!empty_var_descriptors_->IsSmi()); - ASSERT(empty_var_descriptors_->IsLocalVarDescriptors()); - ASSERT(!empty_exception_handlers_->IsSmi()); - ASSERT(empty_exception_handlers_->IsExceptionHandlers()); - ASSERT(!empty_async_exception_handlers_->IsSmi()); - ASSERT(empty_async_exception_handlers_->IsExceptionHandlers()); - ASSERT(!sentinel_->IsSmi()); - ASSERT(sentinel_->IsSentinel()); - ASSERT(!unknown_constant_->IsSmi()); - ASSERT(unknown_constant_->IsSentinel()); - ASSERT(!non_constant_->IsSmi()); - ASSERT(non_constant_->IsSentinel()); - ASSERT(!optimized_out_->IsSmi()); - ASSERT(optimized_out_->IsSentinel()); - ASSERT(!bool_true_->IsSmi()); - ASSERT(bool_true_->IsBool()); - ASSERT(!bool_false_->IsSmi()); - ASSERT(bool_false_->IsBool()); - ASSERT(smi_illegal_cid_->IsSmi()); - ASSERT(smi_zero_->IsSmi()); - ASSERT(!no_callbacks_error_->IsSmi()); - ASSERT(no_callbacks_error_->IsApiError()); - ASSERT(!unwind_error_->IsSmi()); - ASSERT(unwind_error_->IsUnwindError()); - ASSERT(!unwind_in_progress_error_->IsSmi()); - ASSERT(unwind_in_progress_error_->IsUnwindError()); - ASSERT(!snapshot_writer_error_->IsSmi()); - ASSERT(snapshot_writer_error_->IsLanguageError()); - ASSERT(!branch_offset_error_->IsSmi()); - ASSERT(branch_offset_error_->IsLanguageError()); - ASSERT(!background_compilation_error_->IsSmi()); - ASSERT(background_compilation_error_->IsLanguageError()); - ASSERT(!out_of_memory_error_->IsSmi()); - ASSERT(out_of_memory_error_->IsLanguageError()); - ASSERT(!unhandled_oom_exception_->IsSmi()); - ASSERT(unhandled_oom_exception_->IsUnhandledException()); - ASSERT(!vm_isolate_snapshot_object_table_->IsSmi()); - ASSERT(vm_isolate_snapshot_object_table_->IsArray()); - ASSERT(!synthetic_getter_parameter_types_->IsSmi()); - ASSERT(synthetic_getter_parameter_types_->IsArray()); - ASSERT(!synthetic_getter_parameter_names_->IsSmi()); - ASSERT(synthetic_getter_parameter_names_->IsArray()); - ASSERT(!implicit_getter_bytecode_->IsSmi()); - ASSERT(implicit_getter_bytecode_->IsBytecode()); - ASSERT(!implicit_setter_bytecode_->IsSmi()); - ASSERT(implicit_setter_bytecode_->IsBytecode()); - ASSERT(!implicit_static_getter_bytecode_->IsSmi()); - ASSERT(implicit_static_getter_bytecode_->IsBytecode()); - ASSERT(!implicit_static_setter_bytecode_->IsSmi()); - ASSERT(implicit_static_setter_bytecode_->IsBytecode()); - ASSERT(!method_extractor_bytecode_->IsSmi()); - ASSERT(method_extractor_bytecode_->IsBytecode()); - ASSERT(!invoke_closure_bytecode_->IsSmi()); - ASSERT(invoke_closure_bytecode_->IsBytecode()); - ASSERT(!invoke_field_bytecode_->IsSmi()); - ASSERT(invoke_field_bytecode_->IsBytecode()); - ASSERT(!nsm_dispatcher_bytecode_->IsSmi()); - ASSERT(nsm_dispatcher_bytecode_->IsBytecode()); - ASSERT(!dynamic_invocation_forwarder_bytecode_->IsSmi()); - ASSERT(dynamic_invocation_forwarder_bytecode_->IsBytecode()); - ASSERT(!implicit_static_closure_bytecode_->IsSmi()); - ASSERT(implicit_static_closure_bytecode_->IsBytecode()); - ASSERT(!implicit_instance_closure_bytecode_->IsSmi()); - ASSERT(implicit_instance_closure_bytecode_->IsBytecode()); - ASSERT(!implicit_constructor_closure_bytecode_->IsSmi()); - ASSERT(implicit_constructor_closure_bytecode_->IsBytecode()); - ASSERT(!uninitialized_index_->IsSmi()); - ASSERT(uninitialized_index_->IsTypedData()); - ASSERT(!uninitialized_data_->IsSmi()); - ASSERT(uninitialized_data_->IsArray()); + ASSERT(!Roots::null_object().IsSmi()); + ASSERT(!Roots::null_class().IsSmi()); + ASSERT(Roots::null_class().IsClass()); + ASSERT(!Roots::null_array().IsSmi()); + ASSERT(Roots::null_array().IsArray()); + ASSERT(!Roots::null_string().IsSmi()); + ASSERT(Roots::null_string().IsString()); + ASSERT(!Roots::null_instance().IsSmi()); + ASSERT(Roots::null_instance().IsInstance()); + ASSERT(!Roots::null_function().IsSmi()); + ASSERT(Roots::null_function().IsFunction()); + ASSERT(!Roots::null_function_type().IsSmi()); + ASSERT(Roots::null_function_type().IsFunctionType()); + ASSERT(!Roots::null_record_type().IsSmi()); + ASSERT(Roots::null_record_type().IsRecordType()); + ASSERT(!Roots::null_type_arguments().IsSmi()); + ASSERT(Roots::null_type_arguments().IsTypeArguments()); + ASSERT(!Roots::null_compressed_stackmaps().IsSmi()); + ASSERT(Roots::null_compressed_stackmaps().IsCompressedStackMaps()); + ASSERT(!Roots::empty_array().IsSmi()); + ASSERT(Roots::empty_array().IsArray()); + ASSERT(!Roots::empty_instantiations_cache_array().IsSmi()); + ASSERT(Roots::empty_instantiations_cache_array().IsArray()); + ASSERT(!Roots::empty_subtype_test_cache_array().IsSmi()); + ASSERT(Roots::empty_subtype_test_cache_array().IsArray()); + ASSERT(!Roots::empty_type_arguments().IsSmi()); + ASSERT(Roots::empty_type_arguments().IsTypeArguments()); + ASSERT(!Roots::empty_context_scope().IsSmi()); + ASSERT(Roots::empty_context_scope().IsContextScope()); + ASSERT(!Roots::empty_compressed_stackmaps().IsSmi()); + ASSERT(Roots::empty_compressed_stackmaps().IsCompressedStackMaps()); + ASSERT(!Roots::empty_descriptors().IsSmi()); + ASSERT(Roots::empty_descriptors().IsPcDescriptors()); + ASSERT(!Roots::empty_var_descriptors().IsSmi()); + ASSERT(Roots::empty_var_descriptors().IsLocalVarDescriptors()); + ASSERT(!Roots::empty_exception_handlers().IsSmi()); + ASSERT(Roots::empty_exception_handlers().IsExceptionHandlers()); + ASSERT(!Roots::empty_async_exception_handlers().IsSmi()); + ASSERT(Roots::empty_async_exception_handlers().IsExceptionHandlers()); + ASSERT(!Roots::sentinel().IsSmi()); + ASSERT(Roots::sentinel().IsSentinel()); + ASSERT(!Roots::unknown_constant().IsSmi()); + ASSERT(Roots::unknown_constant().IsSentinel()); + ASSERT(!Roots::non_constant().IsSmi()); + ASSERT(Roots::non_constant().IsSentinel()); + ASSERT(!Roots::optimized_out().IsSmi()); + ASSERT(Roots::optimized_out().IsSentinel()); + ASSERT(!Roots::bool_true().IsSmi()); + ASSERT(Roots::bool_true().IsBool()); + ASSERT(!Roots::bool_false().IsSmi()); + ASSERT(Roots::bool_false().IsBool()); + ASSERT(Roots::smi_illegal_cid().IsSmi()); + ASSERT(Roots::smi_zero().IsSmi()); + ASSERT(!Roots::no_callbacks_error().IsSmi()); + ASSERT(Roots::no_callbacks_error().IsApiError()); + ASSERT(!Roots::unwind_error().IsSmi()); + ASSERT(Roots::unwind_error().IsUnwindError()); + ASSERT(!Roots::unwind_in_progress_error().IsSmi()); + ASSERT(Roots::unwind_in_progress_error().IsUnwindError()); + ASSERT(!Roots::snapshot_writer_error().IsSmi()); + ASSERT(Roots::snapshot_writer_error().IsLanguageError()); + ASSERT(!Roots::branch_offset_error().IsSmi()); + ASSERT(Roots::branch_offset_error().IsLanguageError()); + ASSERT(!Roots::background_compilation_error().IsSmi()); + ASSERT(Roots::background_compilation_error().IsLanguageError()); + ASSERT(!Roots::out_of_memory_error().IsSmi()); + ASSERT(Roots::out_of_memory_error().IsLanguageError()); + ASSERT(!Roots::unhandled_oom_exception().IsSmi()); + ASSERT(Roots::unhandled_oom_exception().IsUnhandledException()); + ASSERT(!Roots::vm_isolate_snapshot_object_table().IsSmi()); + ASSERT(Roots::vm_isolate_snapshot_object_table().IsArray()); + ASSERT(!Roots::synthetic_getter_parameter_types().IsSmi()); + ASSERT(Roots::synthetic_getter_parameter_types().IsArray()); + ASSERT(!Roots::synthetic_getter_parameter_names().IsSmi()); + ASSERT(Roots::synthetic_getter_parameter_names().IsArray()); + ASSERT(!Roots::implicit_getter_bytecode().IsSmi()); + ASSERT(Roots::implicit_getter_bytecode().IsBytecode()); + ASSERT(!Roots::implicit_setter_bytecode().IsSmi()); + ASSERT(Roots::implicit_setter_bytecode().IsBytecode()); + ASSERT(!Roots::implicit_static_getter_bytecode().IsSmi()); + ASSERT(Roots::implicit_static_getter_bytecode().IsBytecode()); + ASSERT(!Roots::implicit_static_setter_bytecode().IsSmi()); + ASSERT(Roots::implicit_static_setter_bytecode().IsBytecode()); + ASSERT(!Roots::method_extractor_bytecode().IsSmi()); + ASSERT(Roots::method_extractor_bytecode().IsBytecode()); + ASSERT(!Roots::invoke_closure_bytecode().IsSmi()); + ASSERT(Roots::invoke_closure_bytecode().IsBytecode()); + ASSERT(!Roots::invoke_field_bytecode().IsSmi()); + ASSERT(Roots::invoke_field_bytecode().IsBytecode()); + ASSERT(!Roots::nsm_dispatcher_bytecode().IsSmi()); + ASSERT(Roots::nsm_dispatcher_bytecode().IsBytecode()); + ASSERT(!Roots::dynamic_invocation_forwarder_bytecode().IsSmi()); + ASSERT(Roots::dynamic_invocation_forwarder_bytecode().IsBytecode()); + ASSERT(!Roots::implicit_static_closure_bytecode().IsSmi()); + ASSERT(Roots::implicit_static_closure_bytecode().IsBytecode()); + ASSERT(!Roots::implicit_instance_closure_bytecode().IsSmi()); + ASSERT(Roots::implicit_instance_closure_bytecode().IsBytecode()); + ASSERT(!Roots::implicit_constructor_closure_bytecode().IsSmi()); + ASSERT(Roots::implicit_constructor_closure_bytecode().IsBytecode()); + ASSERT(!Roots::uninitialized_index().IsSmi()); + ASSERT(Roots::uninitialized_index().IsTypedData()); + ASSERT(!Roots::uninitialized_data().IsSmi()); + ASSERT(Roots::uninitialized_data().IsArray()); } void Object::FinishInit(IsolateGroup* isolate_group) { @@ -1450,55 +1384,15 @@ void Object::FinishInit(IsolateGroup* isolate_group) { // method, which is called after StubCode::InitOnce(). Code& code = Code::Handle(); - code = TypeTestingStubGenerator::DefaultCodeForType(*dynamic_type_); - dynamic_type_->InitializeTypeTestingStubNonAtomic(code); + code = TypeTestingStubGenerator::DefaultCodeForType(Roots::dynamic_type()); + Roots::dynamic_type().InitializeTypeTestingStubNonAtomic(code); - code = TypeTestingStubGenerator::DefaultCodeForType(*void_type_); - void_type_->InitializeTypeTestingStubNonAtomic(code); + code = TypeTestingStubGenerator::DefaultCodeForType(Roots::void_type()); + Roots::void_type().InitializeTypeTestingStubNonAtomic(code); } void Object::Cleanup() { - null_ = static_cast(RAW_NULL); - true_ = static_cast(RAW_NULL); - false_ = static_cast(RAW_NULL); - class_class_ = static_cast(RAW_NULL); - dynamic_class_ = static_cast(RAW_NULL); - void_class_ = static_cast(RAW_NULL); - type_parameters_class_ = static_cast(RAW_NULL); - type_arguments_class_ = static_cast(RAW_NULL); - patch_class_class_ = static_cast(RAW_NULL); - function_class_ = static_cast(RAW_NULL); - closure_data_class_ = static_cast(RAW_NULL); - ffi_trampoline_data_class_ = static_cast(RAW_NULL); - field_class_ = static_cast(RAW_NULL); - script_class_ = static_cast(RAW_NULL); - library_class_ = static_cast(RAW_NULL); - namespace_class_ = static_cast(RAW_NULL); - kernel_program_info_class_ = static_cast(RAW_NULL); - code_class_ = static_cast(RAW_NULL); - instructions_class_ = static_cast(RAW_NULL); - instructions_section_class_ = static_cast(RAW_NULL); - instructions_table_class_ = static_cast(RAW_NULL); - object_pool_class_ = static_cast(RAW_NULL); - pc_descriptors_class_ = static_cast(RAW_NULL); - code_source_map_class_ = static_cast(RAW_NULL); - compressed_stackmaps_class_ = static_cast(RAW_NULL); - var_descriptors_class_ = static_cast(RAW_NULL); - exception_handlers_class_ = static_cast(RAW_NULL); - context_class_ = static_cast(RAW_NULL); - context_scope_class_ = static_cast(RAW_NULL); - bytecode_class_ = static_cast(RAW_NULL); - singletargetcache_class_ = static_cast(RAW_NULL); - unlinkedcall_class_ = static_cast(RAW_NULL); - monomorphicsmiablecall_class_ = static_cast(RAW_NULL); - icdata_class_ = static_cast(RAW_NULL); - megamorphic_cache_class_ = static_cast(RAW_NULL); - subtypetestcache_class_ = static_cast(RAW_NULL); - loadingunit_class_ = static_cast(RAW_NULL); - api_error_class_ = static_cast(RAW_NULL); - language_error_class_ = static_cast(RAW_NULL); - unhandled_exception_class_ = static_cast(RAW_NULL); - unwind_error_class_ = static_cast(RAW_NULL); + Roots::Current().Reset(); } // An object visitor which will mark all visited objects. This is used to @@ -1572,7 +1466,7 @@ void Object::FinalizeVMIsolate(IsolateGroup* isolate_group) { // Finish initialization of synthetic_getter_parameter_names_ which was // Started in Object::InitOnce() - synthetic_getter_parameter_names_->SetAt(0, Symbols::This()); + Roots::synthetic_getter_parameter_names().SetAt(0, Symbols::This()); // Set up names for all VM singleton classes. Class& cls = Class::Handle(); @@ -1700,7 +1594,7 @@ void Object::FinalizeReadOnlyObject(ObjectPtr object) { void Object::set_vm_isolate_snapshot_object_table(const Array& table) { ASSERT(Isolate::Current() == Dart::vm_isolate()); - *vm_isolate_snapshot_object_table_ = table.ptr(); + Roots::vm_isolate_snapshot_object_table().initRO(table.ptr()); } // Make unused space in an object whose type has been transformed safe @@ -2923,7 +2817,7 @@ void Object::InitializeObject(uword address, cur += kWordSize; } // Initialize any pointer fields with Object::null(). - initial_value = static_cast(null_); + initial_value = static_cast(Roots::null_obj()); #if defined(DART_COMPRESSED_POINTERS) if (compressed) { initial_value &= 0xFFFFFFFF; @@ -3120,7 +3014,7 @@ bool Object::IsZoneHandle() const { } bool Object::IsReadOnlyHandle() const { - return Dart::IsReadOnlyHandle(reinterpret_cast(this)); + return Roots::IsReadOnlyHandle(reinterpret_cast(this)); } bool Object::IsNotTemporaryScopedHandle() const { @@ -18072,19 +17966,15 @@ bool ICData::IsUsedAt(intptr_t i) const { void ICData::Init() { for (int i = 0; i <= kCachedICDataMaxArgsTestedWithoutExactnessTracking; i++) { - cached_icdata_arrays_ - [kCachedICDataZeroArgTestedWithoutExactnessTrackingIdx + i] = - ICData::NewNonCachedEmptyICDataArray(i, false); + Roots::set_cached_icdata_array( + kCachedICDataZeroArgTestedWithoutExactnessTrackingIdx + i, + ICData::NewNonCachedEmptyICDataArray(i, false)); } - cached_icdata_arrays_[kCachedICDataOneArgWithExactnessTrackingIdx] = - ICData::NewNonCachedEmptyICDataArray(1, true); + Roots::set_cached_icdata_array(kCachedICDataOneArgWithExactnessTrackingIdx, + ICData::NewNonCachedEmptyICDataArray(1, true)); } -void ICData::Cleanup() { - for (int i = 0; i < kCachedICDataArrayCount; ++i) { - cached_icdata_arrays_[i] = nullptr; - } -} +void ICData::Cleanup() {} ArrayPtr ICData::NewNonCachedEmptyICDataArray(intptr_t num_args_tested, bool tracking_exactness) { @@ -18101,20 +17991,21 @@ ArrayPtr ICData::CachedEmptyICDataArray(intptr_t num_args_tested, bool tracking_exactness) { if (tracking_exactness) { ASSERT(num_args_tested == 1); - return cached_icdata_arrays_[kCachedICDataOneArgWithExactnessTrackingIdx]; + return Roots::cached_icdata_array( + kCachedICDataOneArgWithExactnessTrackingIdx); } else { ASSERT(num_args_tested >= 0); ASSERT(num_args_tested <= kCachedICDataMaxArgsTestedWithoutExactnessTracking); - return cached_icdata_arrays_ - [kCachedICDataZeroArgTestedWithoutExactnessTrackingIdx + - num_args_tested]; + return Roots::cached_icdata_array( + kCachedICDataZeroArgTestedWithoutExactnessTrackingIdx + + num_args_tested); } } bool ICData::IsCachedEmptyEntry(const Array& array) { for (int i = 0; i < kCachedICDataArrayCount; ++i) { - if (cached_icdata_arrays_[i] == array.ptr()) return true; + if (Roots::cached_icdata_array(i) == array.ptr()) return true; } return false; } diff --git a/runtime/vm/object.h b/runtime/vm/object.h index f901f03743d..f8bc544ea62 100644 --- a/runtime/vm/object.h +++ b/runtime/vm/object.h @@ -36,6 +36,7 @@ #include "vm/raw_object.h" #include "vm/regexp/regexp-flags.h" #include "vm/report.h" +#include "vm/roots.h" #include "vm/static_type_exactness_state.h" #include "vm/thread.h" #include "vm/token_position.h" @@ -155,9 +156,6 @@ class BaseTextBuffer; DART_NOINLINE static object& ZoneHandle(Zone* zone, object##Ptr ptr) { \ return static_cast(ZoneHandleImpl(zone, ptr, kClassId)); \ } \ - static object* ReadOnlyHandle() { \ - return static_cast(ReadOnlyHandleImpl(kClassId)); \ - } \ DART_NOINLINE static object& CheckedHandle(Zone* zone, ObjectPtr ptr) { \ object* obj = reinterpret_cast(VMHandles::AllocateHandle(zone)); \ initializeHandle(obj, ptr); \ @@ -249,6 +247,9 @@ class BaseTextBuffer; DART_NOINLINE void operator=(object##Ptr value) { \ initializeHandle(this, value); \ } \ + DART_NOINLINE void initRO(object##Ptr value) const { \ + initializeHandle(const_cast(this), value); \ + } \ DART_NOINLINE void operator^=(ObjectPtr value) { \ initializeHandle(this, value); \ ASSERT(IsNull() || Is##object()); \ @@ -280,6 +281,9 @@ extern "C" void DLRT_ExitSafepoint(); ptr_ = value; \ CHECK_HANDLE(); \ } \ + DART_NOINLINE void initRO(object##Ptr value) const { \ + initializeHandle(const_cast(this), value); \ + } \ void operator^=(ObjectPtr value) { \ ptr_ = value; \ CHECK_HANDLE(); \ @@ -349,6 +353,9 @@ class Object { } ObjectPtr ptr() const { return ptr_; } void operator=(ObjectPtr value) { initializeHandle(this, value); } + void initRO(ObjectPtr value) const { + initializeHandle(const_cast(this), value); + } bool IsCanonical() const { return ptr()->untag()->IsCanonical(); } void SetCanonical() const { ptr()->untag()->SetCanonical(); } @@ -418,7 +425,7 @@ class Object { CLASS_LIST_FOR_HANDLES(DEFINE_CLASS_TESTER); #undef DEFINE_CLASS_TESTER - bool IsNull() const { return ptr_ == null_; } + bool IsNull() const { return ptr_ == Roots::null_obj(); } // Matches Object.toString on instances (except String::ToCString, bug 20583). virtual const char* ToCString() const { @@ -463,10 +470,10 @@ class Object { #endif static Object& Handle() { - return HandleImpl(Thread::Current()->zone(), null_, kObjectCid); + return HandleImpl(Thread::Current()->zone(), Roots::null_obj(), kObjectCid); } static Object& Handle(Zone* zone) { - return HandleImpl(zone, null_, kObjectCid); + return HandleImpl(zone, Roots::null_obj(), kObjectCid); } static Object& Handle(ObjectPtr ptr) { return HandleImpl(Thread::Current()->zone(), ptr, kObjectCid); @@ -475,10 +482,11 @@ class Object { return HandleImpl(zone, ptr, kObjectCid); } static Object& ZoneHandle() { - return ZoneHandleImpl(Thread::Current()->zone(), null_, kObjectCid); + return ZoneHandleImpl(Thread::Current()->zone(), Roots::null_obj(), + kObjectCid); } static Object& ZoneHandle(Zone* zone) { - return ZoneHandleImpl(zone, null_, kObjectCid); + return ZoneHandleImpl(zone, Roots::null_obj(), kObjectCid); } static Object& ZoneHandle(ObjectPtr ptr) { return ZoneHandleImpl(Thread::Current()->zone(), ptr, kObjectCid); @@ -486,9 +494,8 @@ class Object { static Object& ZoneHandle(Zone* zone, ObjectPtr ptr) { return ZoneHandleImpl(zone, ptr, kObjectCid); } - static Object* ReadOnlyHandle() { return ReadOnlyHandleImpl(kObjectCid); } - static ObjectPtr null() { return null_; } + static ObjectPtr null() { return Roots::null_obj(); } #if defined(HASH_IN_OBJECT_HEADER) static uint32_t GetCachedHash(const ObjectPtr obj) { @@ -574,74 +581,89 @@ class Object { V(Array, uninitialized_data) #define DEFINE_SHARED_READONLY_HANDLE_GETTER(Type, name) \ - static const Type& name() { \ - ASSERT(name##_ != nullptr); \ - return *name##_; \ - } + static const Type& name() { return Roots::name(); } SHARED_READONLY_HANDLES_LIST(DEFINE_SHARED_READONLY_HANDLE_GETTER) #undef DEFINE_SHARED_READONLY_HANDLE_GETTER static void set_vm_isolate_snapshot_object_table(const Array& table); - static ClassPtr class_class() { return class_class_; } - static ClassPtr dynamic_class() { return dynamic_class_; } - static ClassPtr void_class() { return void_class_; } - static ClassPtr type_parameters_class() { return type_parameters_class_; } - static ClassPtr type_arguments_class() { return type_arguments_class_; } - static ClassPtr patch_class_class() { return patch_class_class_; } - static ClassPtr function_class() { return function_class_; } - static ClassPtr closure_data_class() { return closure_data_class_; } + static ClassPtr class_class() { return Roots::class_class(); } + static ClassPtr dynamic_class() { return Roots::dynamic_class(); } + static ClassPtr void_class() { return Roots::void_class(); } + static ClassPtr type_parameters_class() { + return Roots::type_parameters_class(); + } + static ClassPtr type_arguments_class() { + return Roots::type_arguments_class(); + } + static ClassPtr patch_class_class() { return Roots::patch_class_class(); } + static ClassPtr function_class() { return Roots::function_class(); } + static ClassPtr closure_data_class() { return Roots::closure_data_class(); } static ClassPtr ffi_trampoline_data_class() { - return ffi_trampoline_data_class_; + return Roots::ffi_trampoline_data_class(); } - static ClassPtr field_class() { return field_class_; } - static ClassPtr script_class() { return script_class_; } - static ClassPtr library_class() { return library_class_; } - static ClassPtr namespace_class() { return namespace_class_; } + static ClassPtr field_class() { return Roots::field_class(); } + static ClassPtr script_class() { return Roots::script_class(); } + static ClassPtr library_class() { return Roots::library_class(); } + static ClassPtr namespace_class() { return Roots::namespace_class(); } static ClassPtr kernel_program_info_class() { - return kernel_program_info_class_; + return Roots::kernel_program_info_class(); } - static ClassPtr code_class() { return code_class_; } - static ClassPtr instructions_class() { return instructions_class_; } + static ClassPtr code_class() { return Roots::code_class(); } + static ClassPtr instructions_class() { return Roots::instructions_class(); } static ClassPtr instructions_section_class() { - return instructions_section_class_; + return Roots::instructions_section_class(); } static ClassPtr instructions_table_class() { - return instructions_table_class_; + return Roots::instructions_table_class(); + } + static ClassPtr object_pool_class() { return Roots::object_pool_class(); } + static ClassPtr pc_descriptors_class() { + return Roots::pc_descriptors_class(); + } + static ClassPtr code_source_map_class() { + return Roots::code_source_map_class(); } - static ClassPtr object_pool_class() { return object_pool_class_; } - static ClassPtr pc_descriptors_class() { return pc_descriptors_class_; } - static ClassPtr code_source_map_class() { return code_source_map_class_; } static ClassPtr compressed_stackmaps_class() { - return compressed_stackmaps_class_; + return Roots::compressed_stackmaps_class(); + } + static ClassPtr var_descriptors_class() { + return Roots::var_descriptors_class(); } - static ClassPtr var_descriptors_class() { return var_descriptors_class_; } static ClassPtr exception_handlers_class() { - return exception_handlers_class_; + return Roots::exception_handlers_class(); + } + static ClassPtr context_class() { return Roots::context_class(); } + static ClassPtr context_scope_class() { return Roots::context_scope_class(); } + static ClassPtr bytecode_class() { return Roots::bytecode_class(); } + static ClassPtr sentinel_class() { return Roots::sentinel_class(); } + static ClassPtr api_error_class() { return Roots::api_error_class(); } + static ClassPtr language_error_class() { + return Roots::language_error_class(); } - static ClassPtr context_class() { return context_class_; } - static ClassPtr context_scope_class() { return context_scope_class_; } - static ClassPtr bytecode_class() { return bytecode_class_; } - static ClassPtr sentinel_class() { return sentinel_class_; } - static ClassPtr api_error_class() { return api_error_class_; } - static ClassPtr language_error_class() { return language_error_class_; } static ClassPtr unhandled_exception_class() { - return unhandled_exception_class_; + return Roots::unhandled_exception_class(); } - static ClassPtr unwind_error_class() { return unwind_error_class_; } - static ClassPtr singletargetcache_class() { return singletargetcache_class_; } - static ClassPtr unlinkedcall_class() { return unlinkedcall_class_; } + static ClassPtr unwind_error_class() { return Roots::unwind_error_class(); } + static ClassPtr singletargetcache_class() { + return Roots::singletargetcache_class(); + } + static ClassPtr unlinkedcall_class() { return Roots::unlinkedcall_class(); } static ClassPtr monomorphicsmiablecall_class() { - return monomorphicsmiablecall_class_; + return Roots::monomorphicsmiablecall_class(); } - static ClassPtr icdata_class() { return icdata_class_; } - static ClassPtr megamorphic_cache_class() { return megamorphic_cache_class_; } - static ClassPtr subtypetestcache_class() { return subtypetestcache_class_; } - static ClassPtr loadingunit_class() { return loadingunit_class_; } + static ClassPtr icdata_class() { return Roots::icdata_class(); } + static ClassPtr megamorphic_cache_class() { + return Roots::megamorphic_cache_class(); + } + static ClassPtr subtypetestcache_class() { + return Roots::subtypetestcache_class(); + } + static ClassPtr loadingunit_class() { return Roots::loadingunit_class(); } static ClassPtr weak_serialization_reference_class() { - return weak_serialization_reference_class_; + return Roots::weak_serialization_reference_class(); } - static ClassPtr weak_array_class() { return weak_array_class_; } + static ClassPtr weak_array_class() { return Roots::weak_array_class(); } // Initialize the VM isolate. static void InitNullAndBool(IsolateGroup* isolate_group); @@ -742,7 +764,7 @@ class Object { friend ObjectPtr AllocateObject(intptr_t, intptr_t, intptr_t); // Used for extracting the C++ vtable during bringup. - Object() : ptr_(null_) {} + Object() : ptr_(Roots::null_obj()) {} uword raw_value() const { return static_cast(ptr()); } @@ -763,11 +785,6 @@ class Object { obj->setPtr(ptr, default_cid); return *obj; } - DART_NOINLINE static Object* ReadOnlyHandleImpl(intptr_t cid) { - Object* obj = reinterpret_cast(Dart::AllocateReadOnlyHandle()); - obj->setPtr(Object::null(), cid); - return obj; - } // Memcpy to account for the strict aliasing rule. // Explicit cast to silence -Wdynamic-class-memaccess. @@ -1078,58 +1095,6 @@ class Object { static cpp_vtable builtin_vtables_[kNumPredefinedCids]; - // The static values below are singletons shared between the different - // isolates. They are all allocated in the non-GC'd Dart::vm_isolate_. - static ObjectPtr null_; - static BoolPtr true_; - static BoolPtr false_; - - static ClassPtr class_class_; - static ClassPtr dynamic_class_; - static ClassPtr void_class_; - static ClassPtr type_parameters_class_; - static ClassPtr type_arguments_class_; - static ClassPtr patch_class_class_; - static ClassPtr function_class_; - static ClassPtr closure_data_class_; - static ClassPtr ffi_trampoline_data_class_; - static ClassPtr field_class_; - static ClassPtr script_class_; - static ClassPtr library_class_; - static ClassPtr namespace_class_; - static ClassPtr kernel_program_info_class_; - static ClassPtr code_class_; - static ClassPtr instructions_class_; - static ClassPtr instructions_section_class_; - static ClassPtr instructions_table_class_; - static ClassPtr object_pool_class_; - static ClassPtr pc_descriptors_class_; - static ClassPtr code_source_map_class_; - static ClassPtr compressed_stackmaps_class_; - static ClassPtr var_descriptors_class_; - static ClassPtr exception_handlers_class_; - static ClassPtr context_class_; - static ClassPtr context_scope_class_; - static ClassPtr bytecode_class_; - static ClassPtr sentinel_class_; - static ClassPtr singletargetcache_class_; - static ClassPtr unlinkedcall_class_; - static ClassPtr monomorphicsmiablecall_class_; - static ClassPtr icdata_class_; - static ClassPtr megamorphic_cache_class_; - static ClassPtr subtypetestcache_class_; - static ClassPtr loadingunit_class_; - static ClassPtr api_error_class_; - static ClassPtr language_error_class_; - static ClassPtr unhandled_exception_class_; - static ClassPtr unwind_error_class_; - static ClassPtr weak_serialization_reference_class_; - static ClassPtr weak_array_class_; - -#define DECLARE_SHARED_READONLY_HANDLE(Type, name) static Type* name##_; - SHARED_READONLY_HANDLES_LIST(DECLARE_SHARED_READONLY_HANDLE) -#undef DECLARE_SHARED_READONLY_HANDLE - friend void ClassTable::Register(const Class& cls); friend void UntaggedObject::Validate(IsolateGroup* isolate_group) const; friend class Closure; @@ -2951,9 +2916,6 @@ class ICData : public CallSiteData { intptr_t test_entry_length, const Object& back_ref); - // A cache of VM heap allocated preinitialized empty ic data entry arrays. - static ArrayPtr cached_icdata_arrays_[kCachedICDataArrayCount]; - FINAL_HEAP_OBJECT_IMPLEMENTATION(ICData, CallSiteData); friend class CallSiteResetter; friend class CallTargets; diff --git a/runtime/vm/object_graph_copy.cc b/runtime/vm/object_graph_copy.cc index 92d1699a795..9dbbb4e5e7a 100644 --- a/runtime/vm/object_graph_copy.cc +++ b/runtime/vm/object_graph_copy.cc @@ -103,7 +103,7 @@ DEFINE_FLAG(bool, false, "Cause a GC when falling off the fast path for fast object copy."); -const char* kFastAllocationFailed = "fast allocation failed"; +const char* const kFastAllocationFailed = "fast allocation failed"; struct PtrTypes { using Object = ObjectPtr; diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc index a6eaa8f3c05..9c56e16738c 100644 --- a/runtime/vm/raw_object.cc +++ b/runtime/vm/raw_object.cc @@ -40,7 +40,7 @@ void ObjectPtr::Validate(IsolateGroup* isolate_group) const { } void UntaggedObject::Validate(IsolateGroup* isolate_group) const { - if (static_cast(Object::void_class_) == kHeapObjectTag) { + if (static_cast(Roots::void_class()) == kHeapObjectTag) { // Validation relies on properly initialized class classes. Skip if the // VM is still being initialized. return; diff --git a/runtime/vm/roots.cc b/runtime/vm/roots.cc new file mode 100644 index 00000000000..e7c00b1a50b --- /dev/null +++ b/runtime/vm/roots.cc @@ -0,0 +1,32 @@ +// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +#include "vm/roots.h" + +#include "vm/dart_entry.h" +#include "vm/object.h" +#include "vm/visitor.h" + +namespace dart { + +Roots Roots::roots_ = {}; + +COMPILE_ASSERT(ArgumentsDescriptor::kCachedDescriptorCount == 35); +COMPILE_ASSERT(ICData::kCachedICDataArrayCount == 4); + +void Roots::VisitObjectPointers(ObjectPointerVisitor* visitor) { + ObjectPtr* from = reinterpret_cast(&raw_); + visitor->VisitPointers(from, from + sizeof(Raw) / sizeof(ObjectPtr) - 1); + + from = reinterpret_cast(&api_); + visitor->VisitPointers(from, from + sizeof(Api) / sizeof(ObjectPtr) - 1); + + VMHandle* fromh = reinterpret_cast(&internal_); + VMHandle* toh = fromh + sizeof(Internal) / sizeof(VMHandle) - 1; + for (VMHandle* h = fromh; h <= toh; h++) { + visitor->VisitPointer(&(h->ptr)); + } +} + +} // namespace dart diff --git a/runtime/vm/roots.h b/runtime/vm/roots.h new file mode 100644 index 00000000000..42530eeda0e --- /dev/null +++ b/runtime/vm/roots.h @@ -0,0 +1,308 @@ +// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +#ifndef RUNTIME_VM_ROOTS_H_ +#define RUNTIME_VM_ROOTS_H_ + +#include "vm/stub_code_list.h" +#include "vm/symbol_list.h" +#include "vm/tagged_pointer.h" + +namespace dart { + +#define RAW_ROOTS_LIST(V) \ + V(ObjectPtr, null_obj) \ + V(BoolPtr, true_obj) \ + V(BoolPtr, false_obj) \ + V(ClassPtr, class_class) \ + V(ClassPtr, dynamic_class) \ + V(ClassPtr, void_class) \ + V(ClassPtr, type_parameters_class) \ + V(ClassPtr, type_arguments_class) \ + V(ClassPtr, patch_class_class) \ + V(ClassPtr, function_class) \ + V(ClassPtr, closure_data_class) \ + V(ClassPtr, ffi_trampoline_data_class) \ + V(ClassPtr, field_class) \ + V(ClassPtr, script_class) \ + V(ClassPtr, library_class) \ + V(ClassPtr, namespace_class) \ + V(ClassPtr, kernel_program_info_class) \ + V(ClassPtr, code_class) \ + V(ClassPtr, instructions_class) \ + V(ClassPtr, instructions_section_class) \ + V(ClassPtr, instructions_table_class) \ + V(ClassPtr, object_pool_class) \ + V(ClassPtr, pc_descriptors_class) \ + V(ClassPtr, code_source_map_class) \ + V(ClassPtr, compressed_stackmaps_class) \ + V(ClassPtr, var_descriptors_class) \ + V(ClassPtr, exception_handlers_class) \ + V(ClassPtr, context_class) \ + V(ClassPtr, context_scope_class) \ + V(ClassPtr, bytecode_class) \ + V(ClassPtr, sentinel_class) \ + V(ClassPtr, singletargetcache_class) \ + V(ClassPtr, unlinkedcall_class) \ + V(ClassPtr, monomorphicsmiablecall_class) \ + V(ClassPtr, icdata_class) \ + V(ClassPtr, megamorphic_cache_class) \ + V(ClassPtr, subtypetestcache_class) \ + V(ClassPtr, loadingunit_class) \ + V(ClassPtr, api_error_class) \ + V(ClassPtr, language_error_class) \ + V(ClassPtr, unhandled_exception_class) \ + V(ClassPtr, unwind_error_class) \ + V(ClassPtr, weak_serialization_reference_class) \ + V(ClassPtr, weak_array_class) + +#define HANDLE_ROOTS_LIST(V) \ + V(Object, null_object) \ + V(Class, null_class) \ + V(Array, null_array) \ + V(String, null_string) \ + V(Instance, null_instance) \ + V(Function, null_function) \ + V(FunctionType, null_function_type) \ + V(RecordType, null_record_type) \ + V(TypeArguments, null_type_arguments) \ + V(CompressedStackMaps, null_compressed_stackmaps) \ + V(Closure, null_closure) \ + V(TypeArguments, empty_type_arguments) \ + V(Array, empty_array) \ + V(Array, empty_instantiations_cache_array) \ + V(Array, empty_subtype_test_cache_array) \ + V(Array, mutable_empty_array) \ + V(ContextScope, empty_context_scope) \ + V(ObjectPool, empty_object_pool) \ + V(CompressedStackMaps, empty_compressed_stackmaps) \ + V(PcDescriptors, empty_descriptors) \ + V(LocalVarDescriptors, empty_var_descriptors) \ + V(ExceptionHandlers, empty_exception_handlers) \ + V(ExceptionHandlers, empty_async_exception_handlers) \ + V(Array, synthetic_getter_parameter_types) \ + V(Array, synthetic_getter_parameter_names) \ + V(Bytecode, implicit_getter_bytecode) \ + V(Bytecode, implicit_setter_bytecode) \ + V(Bytecode, implicit_static_getter_bytecode) \ + V(Bytecode, implicit_shared_static_getter_bytecode) \ + V(Bytecode, implicit_static_setter_bytecode) \ + V(Bytecode, implicit_shared_static_setter_bytecode) \ + V(Bytecode, method_extractor_bytecode) \ + V(Bytecode, invoke_closure_bytecode) \ + V(Bytecode, invoke_field_bytecode) \ + V(Bytecode, nsm_dispatcher_bytecode) \ + V(Bytecode, dynamic_invocation_forwarder_bytecode) \ + V(Bytecode, implicit_static_closure_bytecode) \ + V(Bytecode, implicit_instance_closure_bytecode) \ + V(Bytecode, implicit_constructor_closure_bytecode) \ + V(Sentinel, sentinel) \ + V(Sentinel, unknown_constant) \ + V(Sentinel, non_constant) \ + V(Sentinel, optimized_out) \ + V(Bool, bool_true) \ + V(Bool, bool_false) \ + V(Smi, smi_illegal_cid) \ + V(Smi, smi_zero) \ + V(ApiError, no_callbacks_error) \ + V(UnwindError, unwind_error) \ + V(UnwindError, unwind_in_progress_error) \ + V(LanguageError, snapshot_writer_error) \ + V(LanguageError, branch_offset_error) \ + V(LanguageError, background_compilation_error) \ + V(LanguageError, no_debuggable_code_error) \ + V(LanguageError, out_of_memory_error) \ + V(UnhandledException, unhandled_oom_exception) \ + V(Array, vm_isolate_snapshot_object_table) \ + V(Type, dynamic_type) \ + V(Type, void_type) \ + V(AbstractType, null_abstract_type) \ + V(TypedData, uninitialized_index) \ + V(Array, uninitialized_data) + +#define API_HANDLE_ROOTS_LIST(V) \ + V(true_api_handle) \ + V(false_api_handle) \ + V(null_api_handle) \ + V(empty_string_api_handle) \ + V(no_callbacks_error_api_handle) \ + V(unwind_in_progress_error_api_handle) + +class AbstractType; +class ApiError; +class Array; +class Bool; +class Bytecode; +class Class; +class Closure; +class Code; +class CompressedStackMaps; +class ContextScope; +class ExceptionHandlers; +class Function; +class FunctionType; +class Instance; +class LanguageError; +class LocalVarDescriptors; +class Object; +class ObjectPool; +class PcDescriptors; +class RecordType; +class Sentinel; +class Smi; +class String; +class Type; +class TypeArguments; +class TypedData; +class UnhandledException; +class UnwindError; + +class LocalHandle; +class ObjectPointerVisitor; + +class Roots { + enum { +#define DEFINE_SYMBOL_INDEX(symbol, literal) k##symbol##Id, + PREDEFINED_SYMBOLS_LIST(DEFINE_SYMBOL_INDEX) +#undef DEFINE_SYMBOL_INDEX + kNumPredefinedSymbols, + }; + enum { +#define STUB_CODE_ENTRY(name) k##name##Index, + VM_STUB_CODE_LIST(STUB_CODE_ENTRY) +#undef STUB_CODE_ENTRY + kNumStubEntries, + }; + + public: +#define DECL(type, name) \ + static type name() { return roots_.raw_.name##_; } \ + static void set_##name(type v) { roots_.raw_.name##_ = v; } + RAW_ROOTS_LIST(DECL) +#undef DECL + + static ArrayPtr cached_args_descriptor(intptr_t i) { + return roots_.raw_.cached_args_descriptors_[i]; + } + static void set_cached_args_descriptor(intptr_t i, ArrayPtr v) { + roots_.raw_.cached_args_descriptors_[i] = v; + } + static ArrayPtr cached_icdata_array(intptr_t i) { + return roots_.raw_.cached_icdata_arrays_[i]; + } + static void set_cached_icdata_array(intptr_t i, ArrayPtr v) { + roots_.raw_.cached_icdata_arrays_[i] = v; + } + static StringPtr one_char_symbol(intptr_t i) { + return roots_.raw_.one_char_symbols_[i]; + } + static void set_one_char_symbol(intptr_t i, StringPtr v) { + roots_.raw_.one_char_symbols_[i] = v; + } + static StringPtr* one_char_symbols() { + return &roots_.raw_.one_char_symbols_[0]; + } + +#define DECL(type, name) \ + static const type& name() { \ + return *reinterpret_cast(&roots_.internal_.name##_); \ + } + HANDLE_ROOTS_LIST(DECL) +#undef DECL + static const String& symbol_handle(intptr_t i) { + return *reinterpret_cast( + &roots_.internal_.symbol_handles_[i]); + } + static const Code& stub_handle(intptr_t i) { + return *reinterpret_cast(&roots_.internal_.stub_handles_[i]); + } + +#define DECL(name) \ + static LocalHandle* name() { \ + return reinterpret_cast(&roots_.api_.name##_); \ + } + API_HANDLE_ROOTS_LIST(DECL) +#undef DECL + + void Reset() { +#define DECL(type, name) \ + raw_.name##_ = type{static_cast(kHeapObjectTag)}; + RAW_ROOTS_LIST(DECL) +#undef DECL + for (size_t i = 0; i < ARRAY_SIZE(raw_.cached_args_descriptors_); i++) { + raw_.cached_args_descriptors_[i] = + ArrayPtr{static_cast(kHeapObjectTag)}; + } + for (size_t i = 0; i < ARRAY_SIZE(raw_.cached_icdata_arrays_); i++) { + raw_.cached_icdata_arrays_[i] = + ArrayPtr{static_cast(kHeapObjectTag)}; + } + for (size_t i = 0; i < ARRAY_SIZE(raw_.one_char_symbols_); i++) { + raw_.one_char_symbols_[i] = StringPtr{static_cast(kHeapObjectTag)}; + } + } + + static Roots& Current() { return roots_; } + + static bool IsReadOnlyHandle(uword handle) { + return handle - reinterpret_cast(&roots_.internal_) < + sizeof(Internal); + } + static bool IsReadOnlyApiHandle(uword handle) { + return handle - reinterpret_cast(&roots_.api_) < sizeof(Api); + } + + void VisitObjectPointers(ObjectPointerVisitor* visitor); + + private: + Roots() {} + + struct Raw { +#define DECL(type, name) \ + type name##_ = type{static_cast(kHeapObjectTag)}; + RAW_ROOTS_LIST(DECL) +#undef DECL + ArrayPtr cached_args_descriptors_[35]; + ArrayPtr cached_icdata_arrays_[4]; + StringPtr one_char_symbols_[256]; + }; + Raw raw_; + + struct ApiHandle { + uword ptr; + }; + struct Api { + // COMPILE_ASSERT(sizeof(ApiHandle) == sizeof(LocalHandle)) +#define DECL(name) ApiHandle name##_ = {}; + API_HANDLE_ROOTS_LIST(DECL) +#undef DECL + }; + Api api_; + + struct VMHandle { + cpp_vtable vtable; + ObjectPtr ptr; +#if defined(DEBUG) + uword is_zone_handle = false; +#endif + }; + // COMPILE_ASSERT(sizeof(Handle) == kVMHandleSizeInWords * kWordSize) + struct Internal { +#define DECL(type, name) VMHandle name##_ = {}; + HANDLE_ROOTS_LIST(DECL) +#undef DECL + VMHandle symbol_handles_[kNumPredefinedSymbols + 256] = {}; + VMHandle stub_handles_[kNumStubEntries] = {}; + }; + Internal internal_; + + static Roots roots_; + static inline thread_local Roots* current_ = nullptr; + + DISALLOW_COPY_AND_ASSIGN(Roots); +}; + +} // namespace dart + +#endif // RUNTIME_VM_ROOTS_H_ diff --git a/runtime/vm/stub_code.cc b/runtime/vm/stub_code.cc index 7961702dddd..e3d605229c0 100644 --- a/runtime/vm/stub_code.cc +++ b/runtime/vm/stub_code.cc @@ -31,7 +31,6 @@ DEFINE_FLAG(bool, "Generate probe points for installation of user space probes"); #endif -Code* StubCode::handles_[kNumStubEntries] = {nullptr}; AcqRelAtomic StubCode::initialized_ = {false}; #if defined(DART_PRECOMPILED_RUNTIME) @@ -54,16 +53,15 @@ void StubCode::Init() { }; for (intptr_t i = 0; i < kNumStubEntries; i++) { - handles_[i] = Code::ReadOnlyHandle(); - *(handles_[i]) = - Generate(StubNames[i], &object_pool_builder, generators[i]); + Roots::stub_handle(i).initRO( + Generate(StubNames[i], &object_pool_builder, generators[i])); } const ObjectPool& object_pool = ObjectPool::Handle(ObjectPool::NewFromBuilder(object_pool_builder)); for (intptr_t i = 0; i < kNumStubEntries; i++) { - handles_[i]->set_object_pool(object_pool.ptr()); + Roots::stub_handle(i).set_object_pool(object_pool.ptr()); } InitializationDone(); @@ -128,10 +126,6 @@ CodePtr StubCode::Generate(const char* name, void StubCode::Cleanup() { initialized_.store(false, std::memory_order_release); - - for (intptr_t i = 0; i < kNumStubEntries; i++) { - handles_[i] = nullptr; - } } bool StubCode::InInvocationStub(uword pc, bool is_interpreted_frame) { @@ -348,8 +342,8 @@ const Code& StubCode::UnoptimizedStaticCallEntry(intptr_t num_args_tested) { void StubCode::ForEachStub( const std::function& callback) { for (intptr_t i = 0; i < kNumStubEntries; i++) { - if (handles_[i] != nullptr && !handles_[i]->IsNull()) { - if (!callback(StubNames[i], handles_[i]->EntryPoint())) { + if (Roots::stub_handle(i).ptr() != nullptr) { + if (!callback(StubNames[i], Roots::stub_handle(i).EntryPoint())) { return; } } diff --git a/runtime/vm/stub_code.h b/runtime/vm/stub_code.h index 615dfe47d26..cb9b0061635 100644 --- a/runtime/vm/stub_code.h +++ b/runtime/vm/stub_code.h @@ -69,7 +69,7 @@ class StubCode : public AllStatic { // Define the shared stub code accessors. #define STUB_CODE_ACCESSOR(name) \ - static const Code& name() { return *handles_[k##name##Index]; } \ + static const Code& name() { return Roots::stub_handle(k##name##Index); } \ static intptr_t name##Size() { return name().Size(); } VM_STUB_CODE_LIST(STUB_CODE_ACCESSOR); #undef STUB_CODE_ACCESSOR @@ -110,11 +110,11 @@ class StubCode : public AllStatic { static const char* NameAt(intptr_t index) { return StubNames[index]; } - static const Code& EntryAt(intptr_t index) { return *(handles_[index]); } - static void EntryAtPut(intptr_t index, Code* entry) { - DEBUG_ASSERT(entry->IsReadOnlyHandle()); - ASSERT(handles_[index] == nullptr); - handles_[index] = entry; + static const Code& EntryAt(intptr_t index) { + return Roots::stub_handle(index); + } + static void EntryAtPut(intptr_t index, CodePtr code) { + Roots::stub_handle(index).initRO(code); } static intptr_t NumEntries() { return kNumStubEntries; } @@ -140,7 +140,6 @@ class StubCode : public AllStatic { kNumStubEntries }; - static Code* handles_[kNumStubEntries]; static AcqRelAtomic initialized_; }; diff --git a/runtime/vm/symbol_list.h b/runtime/vm/symbol_list.h new file mode 100644 index 00000000000..a4d6ae90f70 --- /dev/null +++ b/runtime/vm/symbol_list.h @@ -0,0 +1,567 @@ +// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +#ifndef RUNTIME_VM_SYMBOL_LIST_H_ +#define RUNTIME_VM_SYMBOL_LIST_H_ + +namespace dart { + +// One-character symbols are added implicitly. +#define PREDEFINED_SYMBOLS_LIST(V) \ + V(Empty, "") \ + V(False, "false") \ + V(Library, "library") \ + V(This, "this") \ + V(True, "true") \ + V(Void, "void") \ + V(AbiSpecificInteger, "AbiSpecificInteger") \ + V(AbstractClassInstantiationError, "AbstractClassInstantiationError") \ + V(_AddStreamState, "_AddStreamState") \ + V(AllocateInvocationMirror, "_allocateInvocationMirror") \ + V(AllocateInvocationMirrorForClosure, "_allocateInvocationMirrorForClosure") \ + V(AnonymousClosure, "") \ + V(ApiError, "ApiError") \ + V(ArgDescVar, ":arg_desc") \ + V(ArgumentError, "ArgumentError") \ + V(Array, "Array") \ + V(StateError, "StateError") \ + V(AssertionError, "_AssertionError") \ + V(AssignIndexToken, "[]=") \ + V(_BigIntImpl, "_BigIntImpl") \ + V(Bool, "bool") \ + V(BooleanExpression, "boolean expression") \ + V(ByteData, "ByteData") \ + V(Bytecode, "Bytecode") \ + V(Capability, "Capability") \ + V(CheckLoaded, "_checkLoaded") \ + V(Class, "Class") \ + V(ClassID, "ClassID") \ + V(ClosureData, "ClosureData") \ + V(ClosureParameter, ":closure") \ + V(Code, "Code") \ + V(CodeSourceMap, "CodeSourceMap") \ + V(_Completer, "_Completer") \ + V(ConditionVariable, "ConditionVariable") \ + V(_AsyncCompleter, "_AsyncCompleter") \ + V(_SyncCompleter, "_SyncCompleter") \ + V(_Compound, "_Compound") \ + V(CompressedStackMaps, "CompressedStackMaps") \ + V(Context, "Context") \ + V(ContextScope, "ContextScope") \ + V(Current, "current") \ + V(CurrentContextVar, ":current_context_var") \ + V(DartAsync, "dart:async") \ + V(DartCollection, "dart:collection") \ + V(DartCompactHash, "dart:_compact_hash") \ + V(DartConcurrent, "dart:concurrent") \ + V(DartCore, "dart:core") \ + V(DartDeveloper, "dart:developer") \ + V(DartDeveloperTimeline, "dart.developer.timeline") \ + V(DartFfi, "dart:ffi") \ + V(DartInternal, "dart:_internal") \ + V(DartIsVM, "dart.isVM") \ + V(DartIo, "dart:io") \ + V(DartIsolate, "dart:isolate") \ + V(DartLibrary, "dart.library.") \ + V(DartLibraryFfi, "dart.library.ffi") \ + V(DartLibraryMirrors, "dart.library.mirrors") \ + V(DartMirrors, "dart:mirrors") \ + V(DartNativeWrappers, "dart:nativewrappers") \ + V(DartNativeWrappersLibName, "nativewrappers") \ + V(DartScheme, "dart:") \ + V(DartSchemePrivate, "dart:_") \ + V(DartTypedData, "dart:typed_data") \ + V(DartVM, "dart:_vm") \ + V(DartVMProduct, "dart.vm.product") \ + V(DartVMASAN, "dart.vm.asan") \ + V(DartVMMSAN, "dart.vm.msan") \ + V(DartVMTSAN, "dart.vm.tsan") \ + V(DartVMService, "dart:_vmservice") \ + V(DebugProcedureName, ":Eval") \ + V(Default, "Default") \ + V(DotCreate, "._create") \ + V(DotFieldADI, ".fieldADI") \ + V(DotFieldAI, ".fieldAI") \ + V(DotFieldNI, ".fieldNI") \ + V(DotStaticFieldAccessedWithoutIsolate, \ + ".staticFieldAccessedWithoutIsolate") \ + V(DotRange, ".range") \ + V(DotUnder, "._") \ + V(DotValue, ".value") \ + V(DotWithType, "._withType") \ + V(Double, "double") \ + V(Dynamic, "dynamic") \ + V(DynamicCall, "dyn:call") \ + V(DynamicCallCurrentFunctionVar, ":dyn_call_current_function") \ + V(DynamicCallCurrentNumProcessedVar, ":dyn_call_current_num_processed") \ + V(DynamicCallCurrentParamIndexVar, ":dyn_call_current_param_index") \ + V(DynamicCallCurrentTypeParamVar, ":dyn_call_current_type_param") \ + V(DynamicCallFunctionTypeArgsVar, ":dyn_call_function_type_args") \ + V(DynamicImplicitCall, "dyn:implicit:call") \ + V(DynamicPrefix, "dyn:") \ + V(EntryPointsTemp, ":entry_points_temp") \ + V(EqualOperator, "==") \ + V(NotEqualOperator, "!=") \ + V(Error, "Error") \ + V(EvalSourceUri, "evaluate:source") \ + V(ExceptionHandlers, "ExceptionHandlers") \ + V(Expando, "Expando") \ + V(ExprTemp, ":expr_temp") \ + V(FfiAbiSpecificMapping, "_FfiAbiSpecificMapping") \ + V(FfiAsyncCallback, "_FfiAsyncCallback") \ + V(FfiBool, "Bool") \ + V(FfiCallback, "_FfiCallback") \ + V(FfiDouble, "Double") \ + V(FfiDynamicLibrary, "DynamicLibrary") \ + V(FfiElementType, "elementType") \ + V(FfiFieldPacking, "packing") \ + V(FfiFieldTypes, "fieldTypes") \ + V(FfiFloat, "Float") \ + V(FfiHandle, "Handle") \ + V(FfiInt16, "Int16") \ + V(FfiInt32, "Int32") \ + V(FfiInt64, "Int64") \ + V(FfiInt8, "Int8") \ + V(FfiIntPtr, "IntPtr") \ + V(FfiIsolateLocalCallback, "_FfiIsolateLocalCallback") \ + V(FfiIsolateGroupBoundCallback, "_FfiIsolateGroupBoundCallback") \ + V(FfiNative, "Native") \ + V(FfiNativeFunction, "NativeFunction") \ + V(FfiNativeType, "NativeType") \ + V(FfiNativeTypes, "nativeTypes") \ + V(FfiPointer, "Pointer") \ + V(FfiFromAddress, "_fromAddress") \ + V(FfiStructLayout, "_FfiStructLayout") \ + V(FfiStructLayoutArray, "_FfiInlineArray") \ + V(FfiTrampolineData, "FfiTrampolineData") \ + V(FfiUint16, "Uint16") \ + V(FfiUint32, "Uint32") \ + V(FfiUint64, "Uint64") \ + V(FfiUint8, "Uint8") \ + V(FfiVoid, "Void") \ + V(Field, "Field") \ + V(FieldAccessError, "FieldAccessError") \ + V(Finalizable, "Finalizable") \ + V(FinalizerBase, "FinalizerBase") \ + V(FinalizerEntry, "FinalizerEntry") \ + V(FirstArg, "x") \ + V(Float32List, "Float32List") \ + V(Float32x4, "Float32x4") \ + V(Float32x4List, "Float32x4List") \ + V(Float64List, "Float64List") \ + V(Float64x2, "Float64x2") \ + V(Float64x2List, "Float64x2List") \ + V(FormatException, "FormatException") \ + V(ForwardingCorpse, "ForwardingCorpse") \ + V(FreeListElement, "FreeListElement") \ + V(Function, "Function") \ + V(FunctionResult, "function result") \ + V(FunctionTypeArgumentsVar, ":function_type_arguments_var") \ + V(Future, "Future") \ + V(_Future, "_Future") \ + V(FutureOr, "FutureOr") \ + V(FutureValue, "Future.value") \ + V(GetCall, "get:call") \ + V(GetLength, "get:length") \ + V(GetRuntimeType, "get:runtimeType") \ + V(GetterPrefix, "get:") \ + V(Get_fieldNames, "get:_fieldNames") \ + V(GreaterEqualOperator, ">=") \ + V(HaveSameRuntimeType, "_haveSameRuntimeType") \ + V(ICData, "ICData") \ + V(Identical, "identical") \ + V(InTypeCast, " in type cast") \ + V(Index, "index") \ + V(IndexToken, "[]") \ + V(InitPrefix, "init:") \ + V(Instructions, "Instructions") \ + V(InstructionsSection, "InstructionsSection") \ + V(InstructionsTable, "InstructionsTable") \ + V(Int, "int") \ + V(Int16List, "Int16List") \ + V(Int32List, "Int32List") \ + V(Int32x4, "Int32x4") \ + V(Int32x4List, "Int32x4List") \ + V(Int64List, "Int64List") \ + V(Int8List, "Int8List") \ + V(IntegerDivisionByZeroException, "IntegerDivisionByZeroException") \ + V(Interpolate, "_interpolate") \ + V(InterpolateSingle, "_interpolateSingle") \ + V(InvocationMirror, "_InvocationMirror") \ + V(IsolateSpawnException, "IsolateSpawnException") \ + V(Iterable, "Iterable") \ + V(Iterator, "iterator") \ + V(KernelProgramInfo, "KernelProgramInfo") \ + V(LanguageError, "LanguageError") \ + V(LateError, "LateError") \ + V(LeftShiftOperator, "<<") \ + V(Length, "length") \ + V(LessEqualOperator, "<=") \ + V(LibraryClass, "Library") \ + V(LibraryPrefix, "LibraryPrefix") \ + V(List, "List") \ + V(ListFactory, "List.") \ + V(ListFilledFactory, "List.filled") \ + V(LoadLibrary, "_loadLibrary") \ + V(LoadingUnit, "LoadingUnit") \ + V(LocalVarDescriptors, "LocalVarDescriptors") \ + V(Map, "Map") \ + V(MapLiteralFactory, "Map._fromLiteral") \ + V(MapKeyValuesFactory, "Map._fromKeyValues") \ + V(MegamorphicCache, "MegamorphicCache") \ + V(MonomorphicSmiableCall, "MonomorphicSmiableCall") \ + V(MoveNext, "moveNext") \ + V(Mutex, "Mutex") \ + V(Namespace, "Namespace") \ + V(Never, "Never") \ + V(NoSuchMethod, "noSuchMethod") \ + V(NoSuchMethodError, "NoSuchMethodError") \ + V(Null, "Null") \ + V(Number, "num") \ + V(Object, "Object") \ + V(ObjectPool, "ObjectPool") \ + V(OneByteString, "_OneByteString") \ + V(OptimizedOut, "") \ + V(OriginalParam, ":original:") \ + V(OutOfMemoryError, "OutOfMemoryError") \ + V(PackageScheme, "package:") \ + V(Patch, "patch") \ + V(PatchClass, "PatchClass") \ + V(PcDescriptors, "PcDescriptors") \ + V(Pragma, "pragma") \ + V(PrependTypeArguments, "_prependTypeArguments") \ + V(QuoteIsNotASubtypeOf, "' is not a subtype of ") \ + V(RangeError, "RangeError") \ + V(Record, "Record") \ + V(RegExp, "RegExp") \ + V(RightShiftOperator, ">>") \ + V(Script, "Script") \ + V(SecondArg, "y") \ + V(SendPort, "SendPort") \ + V(Sentinel, "Sentinel") \ + V(Set, "Set") \ + V(SetterPrefix, "set:") \ + V(SingleTargetCache, "SingleTargetCache") \ + V(SpaceIsFromSpace, " is from ") \ + V(SpaceOfSpace, " of ") \ + V(SpaceWhereNewLine, " where\n") \ + V(StackOverflowError, "StackOverflowError") \ + V(Stream, "Stream") \ + V(StringBase, "_StringBase") \ + V(Struct, "Struct") \ + V(SubtypeTestCache, "SubtypeTestCache") \ + V(SuspendStateVar, ":suspend_state_var") \ + V(SwitchExpr, ":switch_expr") \ + V(Symbol, "Symbol") \ + V(ThrowNew, "_throwNew") \ + V(ThrowNewSource, "_throwNewSource") \ + V(ThrowNewInvocation, "_throwNewInvocation") \ + V(TopLevel, "::") \ + V(TransferableTypedData, "TransferableTypedData") \ + V(TruncDivOperator, "~/") \ + V(TryFinallyReturnValue, ":try_finally_return_value") \ + V(TwoByteString, "_TwoByteString") \ + V(TwoSpaces, " ") \ + V(Type, "Type") \ + V(TypeArguments, "TypeArguments") \ + V(TypeArgumentsParameter, ":type_arguments") \ + V(TypedData, "TypedData") \ + V(TypeError, "_TypeError") \ + V(TypeParameters, "TypeParameters") \ + V(TypeQuote, "type '") \ + V(Uint16List, "Uint16List") \ + V(Uint32List, "Uint32List") \ + V(Uint64List, "Uint64List") \ + V(Uint8ClampedList, "Uint8ClampedList") \ + V(Uint8List, "Uint8List") \ + V(UnaryMinus, "unary-") \ + V(UnhandledException, "UnhandledException") \ + V(Union, "Union") \ + V(UnlinkedCall, "UnlinkedCall") \ + V(UnsafeCast, "unsafeCast") \ + V(UnsignedRightShiftOperator, ">>>") \ + V(UnsupportedError, "UnsupportedError") \ + V(UnwindError, "UnwindError") \ + V(Value, "value") \ + V(Values, "values") \ + V(VarArgs, "VarArgs") \ + V(VariableLength, "variableLength") \ + V(WeakArray, "WeakArray") \ + V(WeakSerializationReference, "WeakSerializationReference") \ + V(_AsyncStarStreamController, "_AsyncStarStreamController") \ + V(_BufferingStreamSubscription, "_BufferingStreamSubscription") \ + V(_ByteBuffer, "_ByteBuffer") \ + V(_ByteBufferDot_New, "_ByteBuffer._New") \ + V(_ByteDataView, "_ByteDataView") \ + V(_Capability, "_Capability") \ + V(_ClassMirror, "_ClassMirror") \ + V(_Closure, "_Closure") \ + V(_ClosureCall, "_Closure.call") \ + V(_CombinatorMirror, "_CombinatorMirror") \ + V(_CompileTimeError, "_CompileTimeError") \ + V(_ConstMap, "_ConstMap") \ + V(_ConstSet, "_ConstSet") \ + V(_ControllerSubscription, "_ControllerSubscription") \ + V(_DeletedEnumPrefix, "Deleted enum value from ") \ + V(_DeletedEnumSentinel, "_deleted_enum_sentinel") \ + V(_Double, "_Double") \ + V(_Enum, "_Enum") \ + V(_ExternalFloat32Array, "_ExternalFloat32Array") \ + V(_ExternalFloat32x4Array, "_ExternalFloat32x4Array") \ + V(_ExternalFloat64Array, "_ExternalFloat64Array") \ + V(_ExternalFloat64x2Array, "_ExternalFloat64x2Array") \ + V(_ExternalInt16Array, "_ExternalInt16Array") \ + V(_ExternalInt32Array, "_ExternalInt32Array") \ + V(_ExternalInt32x4Array, "_ExternalInt32x4Array") \ + V(_ExternalInt64Array, "_ExternalInt64Array") \ + V(_ExternalInt8Array, "_ExternalInt8Array") \ + V(_ExternalUint16Array, "_ExternalUint16Array") \ + V(_ExternalUint32Array, "_ExternalUint32Array") \ + V(_ExternalUint64Array, "_ExternalUint64Array") \ + V(_ExternalUint8Array, "_ExternalUint8Array") \ + V(_ExternalUint8ClampedArray, "_ExternalUint8ClampedArray") \ + V(_FinalizerImpl, "_FinalizerImpl") \ + V(_Float32ArrayFactory, "Float32List.") \ + V(_Float32ArrayView, "_Float32ArrayView") \ + V(_Float32List, "_Float32List") \ + V(_Float32x4, "_Float32x4") \ + V(_Float32x4ArrayFactory, "Float32x4List.") \ + V(_Float32x4ArrayView, "_Float32x4ArrayView") \ + V(_Float32x4List, "_Float32x4List") \ + V(_Float64ArrayFactory, "Float64List.") \ + V(_Float64ArrayView, "_Float64ArrayView") \ + V(_Float64List, "_Float64List") \ + V(_Float64x2, "_Float64x2") \ + V(_Float64x2ArrayFactory, "Float64x2List.") \ + V(_Float64x2ArrayView, "_Float64x2ArrayView") \ + V(_Float64x2List, "_Float64x2List") \ + V(_FunctionType, "_FunctionType") \ + V(_FunctionTypeMirror, "_FunctionTypeMirror") \ + V(_FutureListener, "_FutureListener") \ + V(_GrowableList, "_GrowableList") \ + V(_GrowableListFactory, "_GrowableList.") \ + V(_GrowableListFilledFactory, "_GrowableList.filled") \ + V(_GrowableListGenerateFactory, "_GrowableList.generate") \ + V(_GrowableListLiteralFactory, "_GrowableList._literal") \ + V(_GrowableListWithData, "_GrowableList._withData") \ + V(_ImmutableList, "_ImmutableList") \ + V(_Int16ArrayFactory, "Int16List.") \ + V(_Int16ArrayView, "_Int16ArrayView") \ + V(_Int16List, "_Int16List") \ + V(_Int32ArrayFactory, "Int32List.") \ + V(_Int32ArrayView, "_Int32ArrayView") \ + V(_Int32List, "_Int32List") \ + V(_Int32x4, "_Int32x4") \ + V(_Int32x4ArrayFactory, "Int32x4List.") \ + V(_Int32x4ArrayView, "_Int32x4ArrayView") \ + V(_Int32x4List, "_Int32x4List") \ + V(_Int64ArrayFactory, "Int64List.") \ + V(_Int64ArrayView, "_Int64ArrayView") \ + V(_Int64List, "_Int64List") \ + V(_Int8ArrayFactory, "Int8List.") \ + V(_Int8ArrayView, "_Int8ArrayView") \ + V(_Int8List, "_Int8List") \ + V(_IntegerImplementation, "_IntegerImplementation") \ + V(_IsolateMirror, "_IsolateMirror") \ + V(_LibraryDependencyMirror, "_LibraryDependencyMirror") \ + V(_LibraryMirror, "_LibraryMirror") \ + V(_LibraryPrefix, "_LibraryPrefix") \ + V(_List, "_List") \ + V(_ListFactory, "_List.") \ + V(_ListFilledFactory, "_List.filled") \ + V(_ListGenerateFactory, "_List.generate") \ + V(_Map, "_Map") \ + V(_MethodMirror, "_MethodMirror") \ + V(_Mint, "_Mint") \ + V(_MirrorReference, "_MirrorReference") \ + V(_NativeFinalizer, "_NativeFinalizer") \ + V(_ParameterMirror, "_ParameterMirror") \ + V(_Random, "_Random") \ + V(_RawReceivePort, "_RawReceivePort") \ + V(_Record, "_Record") \ + V(_RecordType, "_RecordType") \ + V(_RegExp, "_RegExp") \ + V(_SendPort, "_SendPort") \ + V(_Set, "_Set") \ + V(_Smi, "_Smi") \ + V(_SourceLocation, "_SourceLocation") \ + V(_SpecialTypeMirror, "_SpecialTypeMirror") \ + V(_StackTrace, "_StackTrace") \ + V(_StreamController, "_StreamController") \ + V(_StreamControllerAddStreamState, "_StreamControllerAddStreamState") \ + V(_StreamIterator, "_StreamIterator") \ + V(_String, "String") \ + V(_SuspendState, "_SuspendState") \ + V(_SyncStarIterator, "_SyncStarIterator") \ + V(_SyncStreamController, "_SyncStreamController") \ + V(_TransferableTypedDataImpl, "_TransferableTypedDataImpl") \ + V(_Type, "_Type") \ + V(_TypeParameter, "_TypeParameter") \ + V(_TypeVariableMirror, "_TypeVariableMirror") \ + V(_TypedList, "_TypedList") \ + V(_TypedListBase, "_TypedListBase") \ + V(_Uint16ArrayFactory, "Uint16List.") \ + V(_Uint16ArrayView, "_Uint16ArrayView") \ + V(_Uint16List, "_Uint16List") \ + V(_Uint32ArrayFactory, "Uint32List.") \ + V(_Uint32ArrayView, "_Uint32ArrayView") \ + V(_Uint32List, "_Uint32List") \ + V(_Uint64ArrayFactory, "Uint64List.") \ + V(_Uint64ArrayView, "_Uint64ArrayView") \ + V(_Uint64List, "_Uint64List") \ + V(_Uint8ArrayFactory, "Uint8List.") \ + V(_Uint8ArrayView, "_Uint8ArrayView") \ + V(_Uint8ClampedArrayFactory, "Uint8ClampedList.") \ + V(_Uint8ClampedArrayView, "_Uint8ClampedArrayView") \ + V(_Uint8ClampedList, "_Uint8ClampedList") \ + V(_Uint8List, "_Uint8List") \ + V(_UnmodifiableByteDataView, "_UnmodifiableByteDataView") \ + V(_UnmodifiableFloat32ArrayView, "_UnmodifiableFloat32ArrayView") \ + V(_UnmodifiableFloat32x4ArrayView, "_UnmodifiableFloat32x4ArrayView") \ + V(_UnmodifiableFloat64ArrayView, "_UnmodifiableFloat64ArrayView") \ + V(_UnmodifiableFloat64x2ArrayView, "_UnmodifiableFloat64x2ArrayView") \ + V(_UnmodifiableInt16ArrayView, "_UnmodifiableInt16ArrayView") \ + V(_UnmodifiableInt32ArrayView, "_UnmodifiableInt32ArrayView") \ + V(_UnmodifiableInt32x4ArrayView, "_UnmodifiableInt32x4ArrayView") \ + V(_UnmodifiableInt64ArrayView, "_UnmodifiableInt64ArrayView") \ + V(_UnmodifiableInt8ArrayView, "_UnmodifiableInt8ArrayView") \ + V(_UnmodifiableUint16ArrayView, "_UnmodifiableUint16ArrayView") \ + V(_UnmodifiableUint32ArrayView, "_UnmodifiableUint32ArrayView") \ + V(_UnmodifiableUint64ArrayView, "_UnmodifiableUint64ArrayView") \ + V(_UnmodifiableUint8ArrayView, "_UnmodifiableUint8ArrayView") \ + V(_UnmodifiableUint8ClampedArrayView, "_UnmodifiableUint8ClampedArrayView") \ + V(_UserTag, "_UserTag") \ + V(_Utf8Decoder, "_Utf8Decoder") \ + V(_VariableMirror, "_VariableMirror") \ + V(_WeakProperty, "_WeakProperty") \ + V(_WeakReference, "_WeakReference") \ + V(_await, "_await") \ + V(_awaitWithTypeCheck, "_awaitWithTypeCheck") \ + V(_checkSetRangeArguments, "_checkSetRangeArguments") \ + V(_current, "_current") \ + V(_ffi_resolver_function, "_ffi_resolver_function") \ + V(future, "future") \ + V(_future, "_future") \ + V(_handleException, "_handleException") \ + V(_handleFinalizerMessage, "_handleFinalizerMessage") \ + V(_handleMessage, "_handleMessage") \ + V(_handleNativeFinalizerMessage, "_handleNativeFinalizerMessage") \ + V(_hasValue, "_hasValue") \ + V(_initAsync, "_initAsync") \ + V(_initAsyncStar, "_initAsyncStar") \ + V(_initSyncStar, "_initSyncStar") \ + V(_instanceOf, "_instanceOf") \ + V(_instantiateClosure, "_instantiateClosure") \ + V(_listGetAt, "_listGetAt") \ + V(_listLength, "_listLength") \ + V(_listSetAt, "_listSetAt") \ + V(_lookupHandler, "_lookupHandler") \ + V(_lookupOpenPorts, "_lookupOpenPorts") \ + V(_mapContainsKey, "_mapContainsKey") \ + V(_mapGet, "_mapGet") \ + V(_mapKeys, "_mapKeys") \ + V(_name, "_name") \ + V(_nextListener, "_nextListener") \ + V(_nativeGetFloat32, "_nativeGetFloat32") \ + V(_nativeSetFloat32, "_nativeSetFloat32") \ + V(_nativeGetFloat64, "_nativeGetFloat64") \ + V(_nativeSetFloat64, "_nativeSetFloat64") \ + V(_nativeGetFloat32x4, "_nativeGetFloat32x4") \ + V(_nativeSetFloat32x4, "_nativeSetFloat32x4") \ + V(_nativeGetInt32x4, "_nativeGetInt32x4") \ + V(_nativeSetInt32x4, "_nativeSetInt32x4") \ + V(_nativeGetFloat64x2, "_nativeGetFloat64x2") \ + V(_nativeSetFloat64x2, "_nativeSetFloat64x2") \ + V(_nativeSetRange, "_nativeSetRange") \ + V(_objectEquals, "_objectEquals") \ + V(_objectHashCode, "_objectHashCode") \ + V(_objectNoSuchMethod, "_objectNoSuchMethod") \ + V(_objectToString, "_objectToString") \ + V(_offsetInBytes, "_offsetInBytes") \ + V(_onData, "_onData") \ + V(_onDone, "_onDone") \ + V(_onError, "_onError") \ + V(_rehashObjects, "_rehashObjects") \ + V(_resultOrListeners, "_resultOrListeners") \ + V(_returnAsync, "_returnAsync") \ + V(_returnAsyncNotFuture, "_returnAsyncNotFuture") \ + V(_returnAsyncStar, "_returnAsyncStar") \ + V(_runExtension, "_runExtension") \ + V(_runPendingImmediateCallback, "_runPendingImmediateCallback") \ + V(_scanFlags, "_scanFlags") \ + V(_simpleInstanceOf, "_simpleInstanceOf") \ + V(_simpleInstanceOfFalse, "_simpleInstanceOfFalse") \ + V(_simpleInstanceOfTrue, "_simpleInstanceOfTrue") \ + V(_stackTrace, "_stackTrace") \ + V(_state, "_state") \ + V(_stateData, "_stateData") \ + V(_suspendSyncStarAtStart, "_suspendSyncStarAtStart") \ + V(_toString, "_toString") \ + V(_typedDataBase, "_typedDataBase") \ + V(_varData, "_varData") \ + V(_yieldAsyncStar, "_yieldAsyncStar") \ + V(_yieldStarIterable, "_yieldStarIterable") \ + V(_yieldSyncStar, "_yieldSyncStar") \ + V(absolute, "absolute") \ + V(add, "add") \ + V(addStream, "addStream") \ + V(addStreamFuture, "addStreamFuture") \ + V(assetId, "assetId") \ + V(asyncStarBody, "asyncStarBody") \ + V(byteOffset, "byteOffset") \ + V(call, "call") \ + V(callback, "callback") \ + V(controller, "controller") \ + V(dynamic_assert_assignable_stc_check, \ + ":dynamic_assert_assignable_stc_check") \ + V(dyn_module_callable, "dyn-module:callable") \ + V(dyn_module_extendable, "dyn-module:extendable") \ + V(dyn_module_implicitly_callable, "dyn-module:implicitly-callable") \ + V(dyn_module_can_be_used_as_type, "dyn-module:can-be-used-as-type") \ + V(executable, "executable") \ + V(get, "get") \ + V(isLeaf, "isLeaf") \ + V(isPaused, "isPaused") \ + V(main, "main") \ + V(name, "name") \ + V(native_assets, "native-assets") \ + V(null, "null") \ + V(options, "options") \ + V(print, "print") \ + V(process, "process") \ + V(relative, "relative") \ + V(result, "result") \ + V(set, "set") \ + V(state, "state") \ + V(symbol, "symbol") \ + V(system, "system") \ + V(vm_always_consider_inlining, "vm:always-consider-inlining") \ + V(vm_awaiter_link, "vm:awaiter-link") \ + V(vm_entry_point, "vm:entry-point") \ + V(vm_exact_result_type, "vm:exact-result-type") \ + V(vm_external_name, "vm:external-name") \ + V(vm_ffi_abi_specific_mapping, "vm:ffi:abi-specific-mapping") \ + V(vm_ffi_call_closure, "vm:ffi:call-closure") \ + V(vm_ffi_native, "vm:ffi:native") \ + V(vm_ffi_native_assets, "vm:ffi:native-assets") \ + V(vm_ffi_struct_fields, "vm:ffi:struct-fields") \ + V(vm_force_optimize, "vm:force-optimize") \ + V(vm_idempotent, "vm:idempotent") \ + V(vm_invisible, "vm:invisible") \ + V(vm_isolate_unsendable, "vm:isolate-unsendable") \ + V(vm_cachable_idempotent, "vm:cachable-idempotent") \ + V(vm_never_inline, "vm:never-inline") \ + V(vm_notify_debugger_on_exception, "vm:notify-debugger-on-exception") \ + V(vm_prefer_inline, "vm:prefer-inline") \ + V(vm_recognized, "vm:recognized") \ + V(vm_shared, "vm:shared") \ + V(vm_testing_print_flow_graph, "vm:testing:print-flow-graph") \ + V(vm_trace_entrypoints, "vm:testing.unsafe.trace-entrypoints-fn") \ + V(vm_unsafe_no_interrupts, "vm:unsafe:no-interrupts") \ + V(vm_align_loops, "vm:align-loops") \ + V(vm_unsafe_no_bounds_checks, "vm:unsafe:no-bounds-checks") + +} // namespace dart + +#endif // RUNTIME_VM_SYMBOL_LIST_H_ diff --git a/runtime/vm/symbols.cc b/runtime/vm/symbols.cc index b5e0958df49..d5cd9683a8c 100644 --- a/runtime/vm/symbols.cc +++ b/runtime/vm/symbols.cc @@ -18,9 +18,6 @@ namespace dart { -StringPtr Symbols::predefined_[Symbols::kNumberOfOneCharCodeSymbols]; -String* Symbols::symbol_handles_[Symbols::kMaxPredefinedId]; - #if !defined(DART_PRECOMPILED_RUNTIME) // clang-format off static const char* const names[] = { @@ -82,13 +79,13 @@ void Symbols::Init(IsolateGroup* vm_isolate_group) { // Create symbols for language keywords. Some keywords are equal to // symbols we already created, so use New() instead of Add() to ensure // that the symbols are canonicalized. + String& str = String::Handle(); for (intptr_t i = 0; i < Symbols::kNullCharId; i++) { - String* str = String::ReadOnlyHandle(); - *str = OneByteString::New(names[i], Heap::kOld); - str->Hash(); - *str ^= table.InsertOrGet(*str); - str->SetCanonical(); // Make canonical once entered. - symbol_handles_[i] = str; + str = OneByteString::New(names[i], Heap::kOld); + str.Hash(); + str ^= table.InsertOrGet(str); + str.SetCanonical(); // Make canonical once entered. + InitSymbol(i, str.ptr()); } // Add Latin1 characters as Symbols, so that Symbols::FromCharCode is fast. @@ -97,14 +94,13 @@ void Symbols::Init(IsolateGroup* vm_isolate_group) { ASSERT(idx < kMaxPredefinedId); ASSERT(Utf::IsLatin1(c)); uint8_t ch = static_cast(c); - String* str = String::ReadOnlyHandle(); - *str = OneByteString::New(&ch, 1, Heap::kOld); - str->Hash(); - *str ^= table.InsertOrGet(*str); - ASSERT(predefined_[c] == nullptr); - str->SetCanonical(); // Make canonical once entered. - predefined_[c] = str->ptr(); - symbol_handles_[idx] = str; + str = OneByteString::New(&ch, 1, Heap::kOld); + str.Hash(); + str ^= table.InsertOrGet(str); + str.SetCanonical(); // Make canonical once entered. + ASSERT(Roots::one_char_symbol(c) == nullptr); + Roots::set_one_char_symbol(c, str.ptr()); + InitSymbol(idx, str.ptr()); } vm_isolate_group->object_store()->set_symbol_table(table.Release()); @@ -114,7 +110,7 @@ void Symbols::Init(IsolateGroup* vm_isolate_group) { void Symbols::InitFromSnapshot(IsolateGroup* vm_isolate_group) { for (intptr_t c = 0; c < kNumberOfOneCharCodeSymbols; c++) { intptr_t idx = (kNullCharId + c); - predefined_[c] = symbol_handles_[idx]->ptr(); + Roots::set_one_char_symbol(c, Symbol(idx).ptr()); } } @@ -425,7 +421,7 @@ StringPtr Symbols::FromCharCode(Thread* thread, uint16_t char_code) { if (char_code > kMaxOneCharCodeSymbol) { return FromUTF16(thread, &char_code, 1); } - return predefined_[char_code]; + return Roots::one_char_symbol(char_code); } void Symbols::DumpStats(IsolateGroup* isolate_group) { diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h index dc4e9a49b25..232659c10f4 100644 --- a/runtime/vm/symbols.h +++ b/runtime/vm/symbols.h @@ -7,6 +7,7 @@ #include "vm/growable_array.h" #include "vm/object.h" +#include "vm/symbol_list.h" namespace dart { @@ -14,561 +15,6 @@ namespace dart { class IsolateGroup; class ObjectPointerVisitor; -// One-character symbols are added implicitly. -#define PREDEFINED_SYMBOLS_LIST(V) \ - V(Empty, "") \ - V(False, "false") \ - V(Library, "library") \ - V(This, "this") \ - V(True, "true") \ - V(Void, "void") \ - V(AbiSpecificInteger, "AbiSpecificInteger") \ - V(AbstractClassInstantiationError, "AbstractClassInstantiationError") \ - V(_AddStreamState, "_AddStreamState") \ - V(AllocateInvocationMirror, "_allocateInvocationMirror") \ - V(AllocateInvocationMirrorForClosure, "_allocateInvocationMirrorForClosure") \ - V(AnonymousClosure, "") \ - V(ApiError, "ApiError") \ - V(ArgDescVar, ":arg_desc") \ - V(ArgumentError, "ArgumentError") \ - V(Array, "Array") \ - V(StateError, "StateError") \ - V(AssertionError, "_AssertionError") \ - V(AssignIndexToken, "[]=") \ - V(_BigIntImpl, "_BigIntImpl") \ - V(Bool, "bool") \ - V(BooleanExpression, "boolean expression") \ - V(ByteData, "ByteData") \ - V(Bytecode, "Bytecode") \ - V(Capability, "Capability") \ - V(CheckLoaded, "_checkLoaded") \ - V(Class, "Class") \ - V(ClassID, "ClassID") \ - V(ClosureData, "ClosureData") \ - V(ClosureParameter, ":closure") \ - V(Code, "Code") \ - V(CodeSourceMap, "CodeSourceMap") \ - V(_Completer, "_Completer") \ - V(ConditionVariable, "ConditionVariable") \ - V(_AsyncCompleter, "_AsyncCompleter") \ - V(_SyncCompleter, "_SyncCompleter") \ - V(_Compound, "_Compound") \ - V(CompressedStackMaps, "CompressedStackMaps") \ - V(Context, "Context") \ - V(ContextScope, "ContextScope") \ - V(Current, "current") \ - V(CurrentContextVar, ":current_context_var") \ - V(DartAsync, "dart:async") \ - V(DartCollection, "dart:collection") \ - V(DartCompactHash, "dart:_compact_hash") \ - V(DartConcurrent, "dart:concurrent") \ - V(DartCore, "dart:core") \ - V(DartDeveloper, "dart:developer") \ - V(DartDeveloperTimeline, "dart.developer.timeline") \ - V(DartFfi, "dart:ffi") \ - V(DartInternal, "dart:_internal") \ - V(DartIsVM, "dart.isVM") \ - V(DartIo, "dart:io") \ - V(DartIsolate, "dart:isolate") \ - V(DartLibrary, "dart.library.") \ - V(DartLibraryFfi, "dart.library.ffi") \ - V(DartLibraryMirrors, "dart.library.mirrors") \ - V(DartMirrors, "dart:mirrors") \ - V(DartNativeWrappers, "dart:nativewrappers") \ - V(DartNativeWrappersLibName, "nativewrappers") \ - V(DartScheme, "dart:") \ - V(DartSchemePrivate, "dart:_") \ - V(DartTypedData, "dart:typed_data") \ - V(DartVM, "dart:_vm") \ - V(DartVMProduct, "dart.vm.product") \ - V(DartVMASAN, "dart.vm.asan") \ - V(DartVMMSAN, "dart.vm.msan") \ - V(DartVMTSAN, "dart.vm.tsan") \ - V(DartVMService, "dart:_vmservice") \ - V(DebugProcedureName, ":Eval") \ - V(Default, "Default") \ - V(DotCreate, "._create") \ - V(DotFieldADI, ".fieldADI") \ - V(DotFieldAI, ".fieldAI") \ - V(DotFieldNI, ".fieldNI") \ - V(DotStaticFieldAccessedWithoutIsolate, \ - ".staticFieldAccessedWithoutIsolate") \ - V(DotRange, ".range") \ - V(DotUnder, "._") \ - V(DotValue, ".value") \ - V(DotWithType, "._withType") \ - V(Double, "double") \ - V(Dynamic, "dynamic") \ - V(DynamicCall, "dyn:call") \ - V(DynamicCallCurrentFunctionVar, ":dyn_call_current_function") \ - V(DynamicCallCurrentNumProcessedVar, ":dyn_call_current_num_processed") \ - V(DynamicCallCurrentParamIndexVar, ":dyn_call_current_param_index") \ - V(DynamicCallCurrentTypeParamVar, ":dyn_call_current_type_param") \ - V(DynamicCallFunctionTypeArgsVar, ":dyn_call_function_type_args") \ - V(DynamicImplicitCall, "dyn:implicit:call") \ - V(DynamicPrefix, "dyn:") \ - V(EntryPointsTemp, ":entry_points_temp") \ - V(EqualOperator, "==") \ - V(NotEqualOperator, "!=") \ - V(Error, "Error") \ - V(EvalSourceUri, "evaluate:source") \ - V(ExceptionHandlers, "ExceptionHandlers") \ - V(Expando, "Expando") \ - V(ExprTemp, ":expr_temp") \ - V(FfiAbiSpecificMapping, "_FfiAbiSpecificMapping") \ - V(FfiAsyncCallback, "_FfiAsyncCallback") \ - V(FfiBool, "Bool") \ - V(FfiCallback, "_FfiCallback") \ - V(FfiDouble, "Double") \ - V(FfiDynamicLibrary, "DynamicLibrary") \ - V(FfiElementType, "elementType") \ - V(FfiFieldPacking, "packing") \ - V(FfiFieldTypes, "fieldTypes") \ - V(FfiFloat, "Float") \ - V(FfiHandle, "Handle") \ - V(FfiInt16, "Int16") \ - V(FfiInt32, "Int32") \ - V(FfiInt64, "Int64") \ - V(FfiInt8, "Int8") \ - V(FfiIntPtr, "IntPtr") \ - V(FfiIsolateLocalCallback, "_FfiIsolateLocalCallback") \ - V(FfiIsolateGroupBoundCallback, "_FfiIsolateGroupBoundCallback") \ - V(FfiNative, "Native") \ - V(FfiNativeFunction, "NativeFunction") \ - V(FfiNativeType, "NativeType") \ - V(FfiNativeTypes, "nativeTypes") \ - V(FfiPointer, "Pointer") \ - V(FfiFromAddress, "_fromAddress") \ - V(FfiStructLayout, "_FfiStructLayout") \ - V(FfiStructLayoutArray, "_FfiInlineArray") \ - V(FfiTrampolineData, "FfiTrampolineData") \ - V(FfiUint16, "Uint16") \ - V(FfiUint32, "Uint32") \ - V(FfiUint64, "Uint64") \ - V(FfiUint8, "Uint8") \ - V(FfiVoid, "Void") \ - V(Field, "Field") \ - V(FieldAccessError, "FieldAccessError") \ - V(Finalizable, "Finalizable") \ - V(FinalizerBase, "FinalizerBase") \ - V(FinalizerEntry, "FinalizerEntry") \ - V(FirstArg, "x") \ - V(Float32List, "Float32List") \ - V(Float32x4, "Float32x4") \ - V(Float32x4List, "Float32x4List") \ - V(Float64List, "Float64List") \ - V(Float64x2, "Float64x2") \ - V(Float64x2List, "Float64x2List") \ - V(FormatException, "FormatException") \ - V(ForwardingCorpse, "ForwardingCorpse") \ - V(FreeListElement, "FreeListElement") \ - V(Function, "Function") \ - V(FunctionResult, "function result") \ - V(FunctionTypeArgumentsVar, ":function_type_arguments_var") \ - V(Future, "Future") \ - V(_Future, "_Future") \ - V(FutureOr, "FutureOr") \ - V(FutureValue, "Future.value") \ - V(GetCall, "get:call") \ - V(GetLength, "get:length") \ - V(GetRuntimeType, "get:runtimeType") \ - V(GetterPrefix, "get:") \ - V(Get_fieldNames, "get:_fieldNames") \ - V(GreaterEqualOperator, ">=") \ - V(HaveSameRuntimeType, "_haveSameRuntimeType") \ - V(ICData, "ICData") \ - V(Identical, "identical") \ - V(InTypeCast, " in type cast") \ - V(Index, "index") \ - V(IndexToken, "[]") \ - V(InitPrefix, "init:") \ - V(Instructions, "Instructions") \ - V(InstructionsSection, "InstructionsSection") \ - V(InstructionsTable, "InstructionsTable") \ - V(Int, "int") \ - V(Int16List, "Int16List") \ - V(Int32List, "Int32List") \ - V(Int32x4, "Int32x4") \ - V(Int32x4List, "Int32x4List") \ - V(Int64List, "Int64List") \ - V(Int8List, "Int8List") \ - V(IntegerDivisionByZeroException, "IntegerDivisionByZeroException") \ - V(Interpolate, "_interpolate") \ - V(InterpolateSingle, "_interpolateSingle") \ - V(InvocationMirror, "_InvocationMirror") \ - V(IsolateSpawnException, "IsolateSpawnException") \ - V(Iterable, "Iterable") \ - V(Iterator, "iterator") \ - V(KernelProgramInfo, "KernelProgramInfo") \ - V(LanguageError, "LanguageError") \ - V(LateError, "LateError") \ - V(LeftShiftOperator, "<<") \ - V(Length, "length") \ - V(LessEqualOperator, "<=") \ - V(LibraryClass, "Library") \ - V(LibraryPrefix, "LibraryPrefix") \ - V(List, "List") \ - V(ListFactory, "List.") \ - V(ListFilledFactory, "List.filled") \ - V(LoadLibrary, "_loadLibrary") \ - V(LoadingUnit, "LoadingUnit") \ - V(LocalVarDescriptors, "LocalVarDescriptors") \ - V(Map, "Map") \ - V(MapLiteralFactory, "Map._fromLiteral") \ - V(MapKeyValuesFactory, "Map._fromKeyValues") \ - V(MegamorphicCache, "MegamorphicCache") \ - V(MonomorphicSmiableCall, "MonomorphicSmiableCall") \ - V(MoveNext, "moveNext") \ - V(Mutex, "Mutex") \ - V(Namespace, "Namespace") \ - V(Never, "Never") \ - V(NoSuchMethod, "noSuchMethod") \ - V(NoSuchMethodError, "NoSuchMethodError") \ - V(Null, "Null") \ - V(Number, "num") \ - V(Object, "Object") \ - V(ObjectPool, "ObjectPool") \ - V(OneByteString, "_OneByteString") \ - V(OptimizedOut, "") \ - V(OriginalParam, ":original:") \ - V(OutOfMemoryError, "OutOfMemoryError") \ - V(PackageScheme, "package:") \ - V(Patch, "patch") \ - V(PatchClass, "PatchClass") \ - V(PcDescriptors, "PcDescriptors") \ - V(Pragma, "pragma") \ - V(PrependTypeArguments, "_prependTypeArguments") \ - V(QuoteIsNotASubtypeOf, "' is not a subtype of ") \ - V(RangeError, "RangeError") \ - V(Record, "Record") \ - V(RegExp, "RegExp") \ - V(RightShiftOperator, ">>") \ - V(Script, "Script") \ - V(SecondArg, "y") \ - V(SendPort, "SendPort") \ - V(Sentinel, "Sentinel") \ - V(Set, "Set") \ - V(SetterPrefix, "set:") \ - V(SingleTargetCache, "SingleTargetCache") \ - V(SpaceIsFromSpace, " is from ") \ - V(SpaceOfSpace, " of ") \ - V(SpaceWhereNewLine, " where\n") \ - V(StackOverflowError, "StackOverflowError") \ - V(Stream, "Stream") \ - V(StringBase, "_StringBase") \ - V(Struct, "Struct") \ - V(SubtypeTestCache, "SubtypeTestCache") \ - V(SuspendStateVar, ":suspend_state_var") \ - V(SwitchExpr, ":switch_expr") \ - V(Symbol, "Symbol") \ - V(ThrowNew, "_throwNew") \ - V(ThrowNewSource, "_throwNewSource") \ - V(ThrowNewInvocation, "_throwNewInvocation") \ - V(TopLevel, "::") \ - V(TransferableTypedData, "TransferableTypedData") \ - V(TruncDivOperator, "~/") \ - V(TryFinallyReturnValue, ":try_finally_return_value") \ - V(TwoByteString, "_TwoByteString") \ - V(TwoSpaces, " ") \ - V(Type, "Type") \ - V(TypeArguments, "TypeArguments") \ - V(TypeArgumentsParameter, ":type_arguments") \ - V(TypedData, "TypedData") \ - V(TypeError, "_TypeError") \ - V(TypeParameters, "TypeParameters") \ - V(TypeQuote, "type '") \ - V(Uint16List, "Uint16List") \ - V(Uint32List, "Uint32List") \ - V(Uint64List, "Uint64List") \ - V(Uint8ClampedList, "Uint8ClampedList") \ - V(Uint8List, "Uint8List") \ - V(UnaryMinus, "unary-") \ - V(UnhandledException, "UnhandledException") \ - V(Union, "Union") \ - V(UnlinkedCall, "UnlinkedCall") \ - V(UnsafeCast, "unsafeCast") \ - V(UnsignedRightShiftOperator, ">>>") \ - V(UnsupportedError, "UnsupportedError") \ - V(UnwindError, "UnwindError") \ - V(Value, "value") \ - V(Values, "values") \ - V(VarArgs, "VarArgs") \ - V(VariableLength, "variableLength") \ - V(WeakArray, "WeakArray") \ - V(WeakSerializationReference, "WeakSerializationReference") \ - V(_AsyncStarStreamController, "_AsyncStarStreamController") \ - V(_BufferingStreamSubscription, "_BufferingStreamSubscription") \ - V(_ByteBuffer, "_ByteBuffer") \ - V(_ByteBufferDot_New, "_ByteBuffer._New") \ - V(_ByteDataView, "_ByteDataView") \ - V(_Capability, "_Capability") \ - V(_ClassMirror, "_ClassMirror") \ - V(_Closure, "_Closure") \ - V(_ClosureCall, "_Closure.call") \ - V(_CombinatorMirror, "_CombinatorMirror") \ - V(_CompileTimeError, "_CompileTimeError") \ - V(_ConstMap, "_ConstMap") \ - V(_ConstSet, "_ConstSet") \ - V(_ControllerSubscription, "_ControllerSubscription") \ - V(_DeletedEnumPrefix, "Deleted enum value from ") \ - V(_DeletedEnumSentinel, "_deleted_enum_sentinel") \ - V(_Double, "_Double") \ - V(_Enum, "_Enum") \ - V(_ExternalFloat32Array, "_ExternalFloat32Array") \ - V(_ExternalFloat32x4Array, "_ExternalFloat32x4Array") \ - V(_ExternalFloat64Array, "_ExternalFloat64Array") \ - V(_ExternalFloat64x2Array, "_ExternalFloat64x2Array") \ - V(_ExternalInt16Array, "_ExternalInt16Array") \ - V(_ExternalInt32Array, "_ExternalInt32Array") \ - V(_ExternalInt32x4Array, "_ExternalInt32x4Array") \ - V(_ExternalInt64Array, "_ExternalInt64Array") \ - V(_ExternalInt8Array, "_ExternalInt8Array") \ - V(_ExternalUint16Array, "_ExternalUint16Array") \ - V(_ExternalUint32Array, "_ExternalUint32Array") \ - V(_ExternalUint64Array, "_ExternalUint64Array") \ - V(_ExternalUint8Array, "_ExternalUint8Array") \ - V(_ExternalUint8ClampedArray, "_ExternalUint8ClampedArray") \ - V(_FinalizerImpl, "_FinalizerImpl") \ - V(_Float32ArrayFactory, "Float32List.") \ - V(_Float32ArrayView, "_Float32ArrayView") \ - V(_Float32List, "_Float32List") \ - V(_Float32x4, "_Float32x4") \ - V(_Float32x4ArrayFactory, "Float32x4List.") \ - V(_Float32x4ArrayView, "_Float32x4ArrayView") \ - V(_Float32x4List, "_Float32x4List") \ - V(_Float64ArrayFactory, "Float64List.") \ - V(_Float64ArrayView, "_Float64ArrayView") \ - V(_Float64List, "_Float64List") \ - V(_Float64x2, "_Float64x2") \ - V(_Float64x2ArrayFactory, "Float64x2List.") \ - V(_Float64x2ArrayView, "_Float64x2ArrayView") \ - V(_Float64x2List, "_Float64x2List") \ - V(_FunctionType, "_FunctionType") \ - V(_FunctionTypeMirror, "_FunctionTypeMirror") \ - V(_FutureListener, "_FutureListener") \ - V(_GrowableList, "_GrowableList") \ - V(_GrowableListFactory, "_GrowableList.") \ - V(_GrowableListFilledFactory, "_GrowableList.filled") \ - V(_GrowableListGenerateFactory, "_GrowableList.generate") \ - V(_GrowableListLiteralFactory, "_GrowableList._literal") \ - V(_GrowableListWithData, "_GrowableList._withData") \ - V(_ImmutableList, "_ImmutableList") \ - V(_Int16ArrayFactory, "Int16List.") \ - V(_Int16ArrayView, "_Int16ArrayView") \ - V(_Int16List, "_Int16List") \ - V(_Int32ArrayFactory, "Int32List.") \ - V(_Int32ArrayView, "_Int32ArrayView") \ - V(_Int32List, "_Int32List") \ - V(_Int32x4, "_Int32x4") \ - V(_Int32x4ArrayFactory, "Int32x4List.") \ - V(_Int32x4ArrayView, "_Int32x4ArrayView") \ - V(_Int32x4List, "_Int32x4List") \ - V(_Int64ArrayFactory, "Int64List.") \ - V(_Int64ArrayView, "_Int64ArrayView") \ - V(_Int64List, "_Int64List") \ - V(_Int8ArrayFactory, "Int8List.") \ - V(_Int8ArrayView, "_Int8ArrayView") \ - V(_Int8List, "_Int8List") \ - V(_IntegerImplementation, "_IntegerImplementation") \ - V(_IsolateMirror, "_IsolateMirror") \ - V(_LibraryDependencyMirror, "_LibraryDependencyMirror") \ - V(_LibraryMirror, "_LibraryMirror") \ - V(_LibraryPrefix, "_LibraryPrefix") \ - V(_List, "_List") \ - V(_ListFactory, "_List.") \ - V(_ListFilledFactory, "_List.filled") \ - V(_ListGenerateFactory, "_List.generate") \ - V(_Map, "_Map") \ - V(_MethodMirror, "_MethodMirror") \ - V(_Mint, "_Mint") \ - V(_MirrorReference, "_MirrorReference") \ - V(_NativeFinalizer, "_NativeFinalizer") \ - V(_ParameterMirror, "_ParameterMirror") \ - V(_Random, "_Random") \ - V(_RawReceivePort, "_RawReceivePort") \ - V(_Record, "_Record") \ - V(_RecordType, "_RecordType") \ - V(_RegExp, "_RegExp") \ - V(_SendPort, "_SendPort") \ - V(_Set, "_Set") \ - V(_Smi, "_Smi") \ - V(_SourceLocation, "_SourceLocation") \ - V(_SpecialTypeMirror, "_SpecialTypeMirror") \ - V(_StackTrace, "_StackTrace") \ - V(_StreamController, "_StreamController") \ - V(_StreamControllerAddStreamState, "_StreamControllerAddStreamState") \ - V(_StreamIterator, "_StreamIterator") \ - V(_String, "String") \ - V(_SuspendState, "_SuspendState") \ - V(_SyncStarIterator, "_SyncStarIterator") \ - V(_SyncStreamController, "_SyncStreamController") \ - V(_TransferableTypedDataImpl, "_TransferableTypedDataImpl") \ - V(_Type, "_Type") \ - V(_TypeParameter, "_TypeParameter") \ - V(_TypeVariableMirror, "_TypeVariableMirror") \ - V(_TypedList, "_TypedList") \ - V(_TypedListBase, "_TypedListBase") \ - V(_Uint16ArrayFactory, "Uint16List.") \ - V(_Uint16ArrayView, "_Uint16ArrayView") \ - V(_Uint16List, "_Uint16List") \ - V(_Uint32ArrayFactory, "Uint32List.") \ - V(_Uint32ArrayView, "_Uint32ArrayView") \ - V(_Uint32List, "_Uint32List") \ - V(_Uint64ArrayFactory, "Uint64List.") \ - V(_Uint64ArrayView, "_Uint64ArrayView") \ - V(_Uint64List, "_Uint64List") \ - V(_Uint8ArrayFactory, "Uint8List.") \ - V(_Uint8ArrayView, "_Uint8ArrayView") \ - V(_Uint8ClampedArrayFactory, "Uint8ClampedList.") \ - V(_Uint8ClampedArrayView, "_Uint8ClampedArrayView") \ - V(_Uint8ClampedList, "_Uint8ClampedList") \ - V(_Uint8List, "_Uint8List") \ - V(_UnmodifiableByteDataView, "_UnmodifiableByteDataView") \ - V(_UnmodifiableFloat32ArrayView, "_UnmodifiableFloat32ArrayView") \ - V(_UnmodifiableFloat32x4ArrayView, "_UnmodifiableFloat32x4ArrayView") \ - V(_UnmodifiableFloat64ArrayView, "_UnmodifiableFloat64ArrayView") \ - V(_UnmodifiableFloat64x2ArrayView, "_UnmodifiableFloat64x2ArrayView") \ - V(_UnmodifiableInt16ArrayView, "_UnmodifiableInt16ArrayView") \ - V(_UnmodifiableInt32ArrayView, "_UnmodifiableInt32ArrayView") \ - V(_UnmodifiableInt32x4ArrayView, "_UnmodifiableInt32x4ArrayView") \ - V(_UnmodifiableInt64ArrayView, "_UnmodifiableInt64ArrayView") \ - V(_UnmodifiableInt8ArrayView, "_UnmodifiableInt8ArrayView") \ - V(_UnmodifiableUint16ArrayView, "_UnmodifiableUint16ArrayView") \ - V(_UnmodifiableUint32ArrayView, "_UnmodifiableUint32ArrayView") \ - V(_UnmodifiableUint64ArrayView, "_UnmodifiableUint64ArrayView") \ - V(_UnmodifiableUint8ArrayView, "_UnmodifiableUint8ArrayView") \ - V(_UnmodifiableUint8ClampedArrayView, "_UnmodifiableUint8ClampedArrayView") \ - V(_UserTag, "_UserTag") \ - V(_Utf8Decoder, "_Utf8Decoder") \ - V(_VariableMirror, "_VariableMirror") \ - V(_WeakProperty, "_WeakProperty") \ - V(_WeakReference, "_WeakReference") \ - V(_await, "_await") \ - V(_awaitWithTypeCheck, "_awaitWithTypeCheck") \ - V(_checkSetRangeArguments, "_checkSetRangeArguments") \ - V(_current, "_current") \ - V(_ffi_resolver_function, "_ffi_resolver_function") \ - V(future, "future") \ - V(_future, "_future") \ - V(_handleException, "_handleException") \ - V(_handleFinalizerMessage, "_handleFinalizerMessage") \ - V(_handleMessage, "_handleMessage") \ - V(_handleNativeFinalizerMessage, "_handleNativeFinalizerMessage") \ - V(_hasValue, "_hasValue") \ - V(_initAsync, "_initAsync") \ - V(_initAsyncStar, "_initAsyncStar") \ - V(_initSyncStar, "_initSyncStar") \ - V(_instanceOf, "_instanceOf") \ - V(_instantiateClosure, "_instantiateClosure") \ - V(_listGetAt, "_listGetAt") \ - V(_listLength, "_listLength") \ - V(_listSetAt, "_listSetAt") \ - V(_lookupHandler, "_lookupHandler") \ - V(_lookupOpenPorts, "_lookupOpenPorts") \ - V(_mapContainsKey, "_mapContainsKey") \ - V(_mapGet, "_mapGet") \ - V(_mapKeys, "_mapKeys") \ - V(_name, "_name") \ - V(_nextListener, "_nextListener") \ - V(_nativeGetFloat32, "_nativeGetFloat32") \ - V(_nativeSetFloat32, "_nativeSetFloat32") \ - V(_nativeGetFloat64, "_nativeGetFloat64") \ - V(_nativeSetFloat64, "_nativeSetFloat64") \ - V(_nativeGetFloat32x4, "_nativeGetFloat32x4") \ - V(_nativeSetFloat32x4, "_nativeSetFloat32x4") \ - V(_nativeGetInt32x4, "_nativeGetInt32x4") \ - V(_nativeSetInt32x4, "_nativeSetInt32x4") \ - V(_nativeGetFloat64x2, "_nativeGetFloat64x2") \ - V(_nativeSetFloat64x2, "_nativeSetFloat64x2") \ - V(_nativeSetRange, "_nativeSetRange") \ - V(_objectEquals, "_objectEquals") \ - V(_objectHashCode, "_objectHashCode") \ - V(_objectNoSuchMethod, "_objectNoSuchMethod") \ - V(_objectToString, "_objectToString") \ - V(_offsetInBytes, "_offsetInBytes") \ - V(_onData, "_onData") \ - V(_onDone, "_onDone") \ - V(_onError, "_onError") \ - V(_rehashObjects, "_rehashObjects") \ - V(_resultOrListeners, "_resultOrListeners") \ - V(_returnAsync, "_returnAsync") \ - V(_returnAsyncNotFuture, "_returnAsyncNotFuture") \ - V(_returnAsyncStar, "_returnAsyncStar") \ - V(_runExtension, "_runExtension") \ - V(_runPendingImmediateCallback, "_runPendingImmediateCallback") \ - V(_scanFlags, "_scanFlags") \ - V(_simpleInstanceOf, "_simpleInstanceOf") \ - V(_simpleInstanceOfFalse, "_simpleInstanceOfFalse") \ - V(_simpleInstanceOfTrue, "_simpleInstanceOfTrue") \ - V(_stackTrace, "_stackTrace") \ - V(_state, "_state") \ - V(_stateData, "_stateData") \ - V(_suspendSyncStarAtStart, "_suspendSyncStarAtStart") \ - V(_toString, "_toString") \ - V(_typedDataBase, "_typedDataBase") \ - V(_varData, "_varData") \ - V(_yieldAsyncStar, "_yieldAsyncStar") \ - V(_yieldStarIterable, "_yieldStarIterable") \ - V(_yieldSyncStar, "_yieldSyncStar") \ - V(absolute, "absolute") \ - V(add, "add") \ - V(addStream, "addStream") \ - V(addStreamFuture, "addStreamFuture") \ - V(assetId, "assetId") \ - V(asyncStarBody, "asyncStarBody") \ - V(byteOffset, "byteOffset") \ - V(call, "call") \ - V(callback, "callback") \ - V(controller, "controller") \ - V(dynamic_assert_assignable_stc_check, \ - ":dynamic_assert_assignable_stc_check") \ - V(dyn_module_callable, "dyn-module:callable") \ - V(dyn_module_extendable, "dyn-module:extendable") \ - V(dyn_module_implicitly_callable, "dyn-module:implicitly-callable") \ - V(dyn_module_can_be_used_as_type, "dyn-module:can-be-used-as-type") \ - V(executable, "executable") \ - V(get, "get") \ - V(isLeaf, "isLeaf") \ - V(isPaused, "isPaused") \ - V(main, "main") \ - V(name, "name") \ - V(native_assets, "native-assets") \ - V(null, "null") \ - V(options, "options") \ - V(print, "print") \ - V(process, "process") \ - V(relative, "relative") \ - V(result, "result") \ - V(set, "set") \ - V(state, "state") \ - V(symbol, "symbol") \ - V(system, "system") \ - V(vm_always_consider_inlining, "vm:always-consider-inlining") \ - V(vm_awaiter_link, "vm:awaiter-link") \ - V(vm_entry_point, "vm:entry-point") \ - V(vm_exact_result_type, "vm:exact-result-type") \ - V(vm_external_name, "vm:external-name") \ - V(vm_ffi_abi_specific_mapping, "vm:ffi:abi-specific-mapping") \ - V(vm_ffi_call_closure, "vm:ffi:call-closure") \ - V(vm_ffi_native, "vm:ffi:native") \ - V(vm_ffi_native_assets, "vm:ffi:native-assets") \ - V(vm_ffi_struct_fields, "vm:ffi:struct-fields") \ - V(vm_force_optimize, "vm:force-optimize") \ - V(vm_idempotent, "vm:idempotent") \ - V(vm_invisible, "vm:invisible") \ - V(vm_isolate_unsendable, "vm:isolate-unsendable") \ - V(vm_cachable_idempotent, "vm:cachable-idempotent") \ - V(vm_never_inline, "vm:never-inline") \ - V(vm_notify_debugger_on_exception, "vm:notify-debugger-on-exception") \ - V(vm_prefer_inline, "vm:prefer-inline") \ - V(vm_recognized, "vm:recognized") \ - V(vm_shared, "vm:shared") \ - V(vm_testing_print_flow_graph, "vm:testing:print-flow-graph") \ - V(vm_trace_entrypoints, "vm:testing.unsafe.trace-entrypoints-fn") \ - V(vm_unsafe_no_interrupts, "vm:unsafe:no-interrupts") \ - V(vm_align_loops, "vm:align-loops") \ - V(vm_unsafe_no_bounds_checks, "vm:unsafe:no-bounds-checks") - // Contains a list of frequently used strings in a canonicalized form. This // list is kept in the vm_isolate in order to share the copy across isolates // without having to maintain copies in each isolate. @@ -596,93 +42,51 @@ PREDEFINED_SYMBOLS_LIST(DEFINE_SYMBOL_INDEX) static const String& Symbol(intptr_t index) { ASSERT((index >= 0) && (index < kMaxPredefinedId)); - return *(symbol_handles_[index]); + return Roots::symbol_handle(index); } - static void InitSymbol(intptr_t index, String* symbol) { + static void InitSymbol(intptr_t index, StringPtr symbol) { ASSERT((index >= 0) && (index < kMaxPredefinedId)); - symbol_handles_[index] = symbol; + Roots::symbol_handle(index).initRO(symbol); } // Access methods for one byte character symbols stored in the vm isolate. - static const String& Dot() { return *(symbol_handles_[kNullCharId + '.']); } - static const String& Equals() { - return *(symbol_handles_[kNullCharId + '=']); - } - static const String& Plus() { return *(symbol_handles_[kNullCharId + '+']); } - static const String& Minus() { return *(symbol_handles_[kNullCharId + '-']); } - static const String& BitOr() { return *(symbol_handles_[kNullCharId + '|']); } - static const String& BitAnd() { - return *(symbol_handles_[kNullCharId + '&']); - } - static const String& LAngleBracket() { - return *(symbol_handles_[kNullCharId + '<']); - } - static const String& RAngleBracket() { - return *(symbol_handles_[kNullCharId + '>']); - } - static const String& LParen() { - return *(symbol_handles_[kNullCharId + '(']); - } - static const String& RParen() { - return *(symbol_handles_[kNullCharId + ')']); - } - static const String& LBracket() { - return *(symbol_handles_[kNullCharId + '[']); - } - static const String& RBracket() { - return *(symbol_handles_[kNullCharId + ']']); - } - static const String& LBrace() { - return *(symbol_handles_[kNullCharId + '{']); - } - static const String& RBrace() { - return *(symbol_handles_[kNullCharId + '}']); - } - static const String& Blank() { return *(symbol_handles_[kNullCharId + ' ']); } - static const String& Dollar() { - return *(symbol_handles_[kNullCharId + '$']); - } - static const String& NewLine() { - return *(symbol_handles_[kNullCharId + '\n']); - } - static const String& DoubleQuote() { - return *(symbol_handles_[kNullCharId + '"']); - } - static const String& SingleQuote() { - return *(symbol_handles_[kNullCharId + '\'']); - } - static const String& LowercaseR() { - return *(symbol_handles_[kNullCharId + 'r']); - } - static const String& Dash() { return *(symbol_handles_[kNullCharId + '-']); } - static const String& Ampersand() { - return *(symbol_handles_[kNullCharId + '&']); - } - static const String& Backtick() { - return *(symbol_handles_[kNullCharId + '`']); - } - static const String& Slash() { return *(symbol_handles_[kNullCharId + '/']); } - static const String& At() { return *(symbol_handles_[kNullCharId + '@']); } - static const String& HashMark() { - return *(symbol_handles_[kNullCharId + '#']); - } - static const String& Semicolon() { - return *(symbol_handles_[kNullCharId + ';']); - } - static const String& Star() { return *(symbol_handles_[kNullCharId + '*']); } - static const String& Percent() { - return *(symbol_handles_[kNullCharId + '%']); - } - static const String& QuestionMark() { - return *(symbol_handles_[kNullCharId + '?']); - } - static const String& Caret() { return *(symbol_handles_[kNullCharId + '^']); } - static const String& Tilde() { return *(symbol_handles_[kNullCharId + '~']); } + static const String& Dot() { return Symbol(kNullCharId + '.'); } + static const String& Equals() { return Symbol(kNullCharId + '='); } + static const String& Plus() { return Symbol(kNullCharId + '+'); } + static const String& Minus() { return Symbol(kNullCharId + '-'); } + static const String& BitOr() { return Symbol(kNullCharId + '|'); } + static const String& BitAnd() { return Symbol(kNullCharId + '&'); } + static const String& LAngleBracket() { return Symbol(kNullCharId + '<'); } + static const String& RAngleBracket() { return Symbol(kNullCharId + '>'); } + static const String& LParen() { return Symbol(kNullCharId + '('); } + static const String& RParen() { return Symbol(kNullCharId + ')'); } + static const String& LBracket() { return Symbol(kNullCharId + '['); } + static const String& RBracket() { return Symbol(kNullCharId + ']'); } + static const String& LBrace() { return Symbol(kNullCharId + '{'); } + static const String& RBrace() { return Symbol(kNullCharId + '}'); } + static const String& Blank() { return Symbol(kNullCharId + ' '); } + static const String& Dollar() { return Symbol(kNullCharId + '$'); } + static const String& NewLine() { return Symbol(kNullCharId + '\n'); } + static const String& DoubleQuote() { return Symbol(kNullCharId + '"'); } + static const String& SingleQuote() { return Symbol(kNullCharId + '\''); } + static const String& LowercaseR() { return Symbol(kNullCharId + 'r'); } + static const String& Dash() { return Symbol(kNullCharId + '-'); } + static const String& Ampersand() { return Symbol(kNullCharId + '&'); } + static const String& Backtick() { return Symbol(kNullCharId + '`'); } + static const String& Slash() { return Symbol(kNullCharId + '/'); } + static const String& At() { return Symbol(kNullCharId + '@'); } + static const String& HashMark() { return Symbol(kNullCharId + '#'); } + static const String& Semicolon() { return Symbol(kNullCharId + ';'); } + static const String& Star() { return Symbol(kNullCharId + '*'); } + static const String& Percent() { return Symbol(kNullCharId + '%'); } + static const String& QuestionMark() { return Symbol(kNullCharId + '?'); } + static const String& Caret() { return Symbol(kNullCharId + '^'); } + static const String& Tilde() { return Symbol(kNullCharId + '~'); } // Access methods for symbol handles stored in the vm isolate for predefined // symbols. #define DEFINE_SYMBOL_HANDLE_ACCESSOR(symbol, literal) \ - static const String& symbol() { return *(symbol_handles_[k##symbol##Id]); } + static const String& symbol() { return Symbol(k##symbol##Id); } PREDEFINED_SYMBOLS_LIST(DEFINE_SYMBOL_HANDLE_ACCESSOR) #undef DEFINE_SYMBOL_HANDLE_ACCESSOR @@ -741,9 +145,7 @@ PREDEFINED_SYMBOLS_LIST(DEFINE_SYMBOL_INDEX) static StringPtr FromCharCode(Thread* thread, uint16_t char_code); - static StringPtr* PredefinedAddress() { - return reinterpret_cast(&predefined_); - } + static StringPtr* PredefinedAddress() { return Roots::one_char_symbols(); } static void DumpStats(IsolateGroup* isolate_group); static void DumpTable(IsolateGroup* isolate_group); @@ -770,14 +172,6 @@ PREDEFINED_SYMBOLS_LIST(DEFINE_SYMBOL_INDEX) template static StringPtr NewSymbol(Thread* thread, const StringType& str); - // List of Latin1 characters stored in the vm isolate as symbols - // in order to make Symbols::FromCharCode fast. This structure is - // used in generated dart code for direct access to these objects. - static StringPtr predefined_[kNumberOfOneCharCodeSymbols]; - - // List of handles for predefined symbols. - static String* symbol_handles_[kMaxPredefinedId]; - friend class Dart; friend class String; friend class Serializer; diff --git a/runtime/vm/vm_sources.gni b/runtime/vm/vm_sources.gni index 4bad8fbdc5f..2241123e032 100644 --- a/runtime/vm/vm_sources.gni +++ b/runtime/vm/vm_sources.gni @@ -267,6 +267,8 @@ vm_sources = [ "reverse_pc_lookup_cache.cc", "reverse_pc_lookup_cache.h", "ring_buffer.h", + "roots.cc", + "roots.h", "runtime_entry.cc", "runtime_entry.h", "runtime_entry_list.h", @@ -314,6 +316,7 @@ vm_sources = [ "stub_code.cc", "stub_code.h", "stub_code_list.h", + "symbol_list.h", "symbols.cc", "symbols.h", "tags.cc",