1 // Copyright 2018 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_ROOTS_ROOTS_H_ 6 #define V8_ROOTS_ROOTS_H_ 7 8 #include "src/base/macros.h" 9 #include "src/builtins/accessors.h" 10 #include "src/common/globals.h" 11 #include "src/handles/handles.h" 12 #include "src/init/heap-symbols.h" 13 #include "src/objects/objects-definitions.h" 14 #include "src/objects/objects.h" 15 #include "src/objects/slots.h" 16 17 namespace v8 { 18 namespace internal { 19 20 // Forward declarations. 21 enum ElementsKind : uint8_t; 22 template <typename T> 23 class Handle; 24 class Heap; 25 class Isolate; 26 class Map; 27 class PropertyCell; 28 class ReadOnlyHeap; 29 class RootVisitor; 30 class String; 31 class Symbol; 32 33 // Defines all the read-only roots in Heap. 34 #define STRONG_READ_ONLY_ROOT_LIST(V) \ 35 /* Cluster the most popular ones in a few cache lines here at the top. */ \ 36 /* The first 32 entries are most often used in the startup snapshot and */ \ 37 /* can use a shorter representation in the serialization format. */ \ 38 V(Map, free_space_map, FreeSpaceMap) \ 39 V(Map, one_pointer_filler_map, OnePointerFillerMap) \ 40 V(Map, two_pointer_filler_map, TwoPointerFillerMap) \ 41 V(Oddball, uninitialized_value, UninitializedValue) \ 42 V(Oddball, undefined_value, UndefinedValue) \ 43 V(Oddball, the_hole_value, TheHoleValue) \ 44 V(Oddball, null_value, NullValue) \ 45 V(Oddball, true_value, TrueValue) \ 46 V(Oddball, false_value, FalseValue) \ 47 V(String, empty_string, empty_string) \ 48 V(Map, meta_map, MetaMap) \ 49 V(Map, byte_array_map, ByteArrayMap) \ 50 V(Map, fixed_array_map, FixedArrayMap) \ 51 V(Map, fixed_cow_array_map, FixedCOWArrayMap) \ 52 V(Map, hash_table_map, HashTableMap) \ 53 V(Map, symbol_map, SymbolMap) \ 54 V(Map, one_byte_string_map, OneByteStringMap) \ 55 V(Map, one_byte_internalized_string_map, OneByteInternalizedStringMap) \ 56 V(Map, scope_info_map, ScopeInfoMap) \ 57 V(Map, shared_function_info_map, SharedFunctionInfoMap) \ 58 V(Map, code_map, CodeMap) \ 59 V(Map, cell_map, CellMap) \ 60 V(Map, global_property_cell_map, GlobalPropertyCellMap) \ 61 V(Map, foreign_map, ForeignMap) \ 62 V(Map, heap_number_map, HeapNumberMap) \ 63 V(Map, transition_array_map, TransitionArrayMap) \ 64 V(Map, thin_one_byte_string_map, ThinOneByteStringMap) \ 65 /* TODO(mythria): Once lazy feedback lands, check if feedback vector map */ \ 66 /* is still a popular map */ \ 67 V(Map, feedback_vector_map, FeedbackVectorMap) \ 68 V(ScopeInfo, empty_scope_info, EmptyScopeInfo) \ 69 V(FixedArray, empty_fixed_array, EmptyFixedArray) \ 70 V(DescriptorArray, empty_descriptor_array, EmptyDescriptorArray) \ 71 /* Entries beyond the first 32 */ \ 72 /* Oddballs */ \ 73 V(Oddball, arguments_marker, ArgumentsMarker) \ 74 V(Oddball, exception, Exception) \ 75 V(Oddball, termination_exception, TerminationException) \ 76 V(Oddball, optimized_out, OptimizedOut) \ 77 V(Oddball, stale_register, StaleRegister) \ 78 /* Maps */ \ 79 V(Map, script_context_table_map, ScriptContextTableMap) \ 80 V(Map, closure_feedback_cell_array_map, ClosureFeedbackCellArrayMap) \ 81 V(Map, feedback_metadata_map, FeedbackMetadataArrayMap) \ 82 V(Map, array_list_map, ArrayListMap) \ 83 V(Map, bigint_map, BigIntMap) \ 84 V(Map, object_boilerplate_description_map, ObjectBoilerplateDescriptionMap) \ 85 V(Map, bytecode_array_map, BytecodeArrayMap) \ 86 V(Map, code_data_container_map, CodeDataContainerMap) \ 87 V(Map, coverage_info_map, CoverageInfoMap) \ 88 V(Map, fixed_double_array_map, FixedDoubleArrayMap) \ 89 V(Map, global_dictionary_map, GlobalDictionaryMap) \ 90 V(Map, many_closures_cell_map, ManyClosuresCellMap) \ 91 V(Map, module_info_map, ModuleInfoMap) \ 92 V(Map, name_dictionary_map, NameDictionaryMap) \ 93 V(Map, no_closures_cell_map, NoClosuresCellMap) \ 94 V(Map, number_dictionary_map, NumberDictionaryMap) \ 95 V(Map, one_closure_cell_map, OneClosureCellMap) \ 96 V(Map, ordered_hash_map_map, OrderedHashMapMap) \ 97 V(Map, ordered_hash_set_map, OrderedHashSetMap) \ 98 V(Map, ordered_name_dictionary_map, OrderedNameDictionaryMap) \ 99 V(Map, preparse_data_map, PreparseDataMap) \ 100 V(Map, property_array_map, PropertyArrayMap) \ 101 V(Map, side_effect_call_handler_info_map, SideEffectCallHandlerInfoMap) \ 102 V(Map, side_effect_free_call_handler_info_map, \ 103 SideEffectFreeCallHandlerInfoMap) \ 104 V(Map, next_call_side_effect_free_call_handler_info_map, \ 105 NextCallSideEffectFreeCallHandlerInfoMap) \ 106 V(Map, simple_number_dictionary_map, SimpleNumberDictionaryMap) \ 107 V(Map, small_ordered_hash_map_map, SmallOrderedHashMapMap) \ 108 V(Map, small_ordered_hash_set_map, SmallOrderedHashSetMap) \ 109 V(Map, small_ordered_name_dictionary_map, SmallOrderedNameDictionaryMap) \ 110 V(Map, source_text_module_map, SourceTextModuleMap) \ 111 V(Map, synthetic_module_map, SyntheticModuleMap) \ 112 V(Map, uncompiled_data_without_preparse_data_map, \ 113 UncompiledDataWithoutPreparseDataMap) \ 114 V(Map, uncompiled_data_with_preparse_data_map, \ 115 UncompiledDataWithPreparseDataMap) \ 116 V(Map, wasm_type_info_map, WasmTypeInfoMap) \ 117 V(Map, weak_fixed_array_map, WeakFixedArrayMap) \ 118 V(Map, weak_array_list_map, WeakArrayListMap) \ 119 V(Map, ephemeron_hash_table_map, EphemeronHashTableMap) \ 120 V(Map, embedder_data_array_map, EmbedderDataArrayMap) \ 121 V(Map, weak_cell_map, WeakCellMap) \ 122 /* String maps */ \ 123 V(Map, string_map, StringMap) \ 124 V(Map, cons_one_byte_string_map, ConsOneByteStringMap) \ 125 V(Map, cons_string_map, ConsStringMap) \ 126 V(Map, thin_string_map, ThinStringMap) \ 127 V(Map, sliced_string_map, SlicedStringMap) \ 128 V(Map, sliced_one_byte_string_map, SlicedOneByteStringMap) \ 129 V(Map, external_string_map, ExternalStringMap) \ 130 V(Map, external_one_byte_string_map, ExternalOneByteStringMap) \ 131 V(Map, uncached_external_string_map, UncachedExternalStringMap) \ 132 V(Map, internalized_string_map, InternalizedStringMap) \ 133 V(Map, external_internalized_string_map, ExternalInternalizedStringMap) \ 134 V(Map, external_one_byte_internalized_string_map, \ 135 ExternalOneByteInternalizedStringMap) \ 136 V(Map, uncached_external_internalized_string_map, \ 137 UncachedExternalInternalizedStringMap) \ 138 V(Map, uncached_external_one_byte_internalized_string_map, \ 139 UncachedExternalOneByteInternalizedStringMap) \ 140 V(Map, uncached_external_one_byte_string_map, \ 141 UncachedExternalOneByteStringMap) \ 142 /* Oddball maps */ \ 143 V(Map, undefined_map, UndefinedMap) \ 144 V(Map, the_hole_map, TheHoleMap) \ 145 V(Map, null_map, NullMap) \ 146 V(Map, boolean_map, BooleanMap) \ 147 V(Map, uninitialized_map, UninitializedMap) \ 148 V(Map, arguments_marker_map, ArgumentsMarkerMap) \ 149 V(Map, exception_map, ExceptionMap) \ 150 V(Map, termination_exception_map, TerminationExceptionMap) \ 151 V(Map, optimized_out_map, OptimizedOutMap) \ 152 V(Map, stale_register_map, StaleRegisterMap) \ 153 V(Map, self_reference_marker_map, SelfReferenceMarkerMap) \ 154 V(Map, basic_block_counters_marker_map, BasicBlockCountersMarkerMap) \ 155 /* Canonical empty values */ \ 156 V(EnumCache, empty_enum_cache, EmptyEnumCache) \ 157 V(PropertyArray, empty_property_array, EmptyPropertyArray) \ 158 V(ByteArray, empty_byte_array, EmptyByteArray) \ 159 V(ObjectBoilerplateDescription, empty_object_boilerplate_description, \ 160 EmptyObjectBoilerplateDescription) \ 161 V(ArrayBoilerplateDescription, empty_array_boilerplate_description, \ 162 EmptyArrayBoilerplateDescription) \ 163 V(ClosureFeedbackCellArray, empty_closure_feedback_cell_array, \ 164 EmptyClosureFeedbackCellArray) \ 165 V(NumberDictionary, empty_slow_element_dictionary, \ 166 EmptySlowElementDictionary) \ 167 V(OrderedHashMap, empty_ordered_hash_map, EmptyOrderedHashMap) \ 168 V(OrderedHashSet, empty_ordered_hash_set, EmptyOrderedHashSet) \ 169 V(FeedbackMetadata, empty_feedback_metadata, EmptyFeedbackMetadata) \ 170 V(PropertyCell, empty_property_cell, EmptyPropertyCell) \ 171 V(NameDictionary, empty_property_dictionary, EmptyPropertyDictionary) \ 172 V(OrderedNameDictionary, empty_ordered_property_dictionary, \ 173 EmptyOrderedPropertyDictionary) \ 174 V(InterceptorInfo, noop_interceptor_info, NoOpInterceptorInfo) \ 175 V(WeakFixedArray, empty_weak_fixed_array, EmptyWeakFixedArray) \ 176 V(WeakArrayList, empty_weak_array_list, EmptyWeakArrayList) \ 177 /* Special numbers */ \ 178 V(HeapNumber, nan_value, NanValue) \ 179 V(HeapNumber, hole_nan_value, HoleNanValue) \ 180 V(HeapNumber, infinity_value, InfinityValue) \ 181 V(HeapNumber, minus_zero_value, MinusZeroValue) \ 182 V(HeapNumber, minus_infinity_value, MinusInfinityValue) \ 183 /* Marker for self-references during code-generation */ \ 184 V(HeapObject, self_reference_marker, SelfReferenceMarker) \ 185 /* Marker for basic-block usage counters array during code-generation */ \ 186 V(Oddball, basic_block_counters_marker, BasicBlockCountersMarker) \ 187 /* Canonical off-heap trampoline data */ \ 188 V(ByteArray, off_heap_trampoline_relocation_info, \ 189 OffHeapTrampolineRelocationInfo) \ 190 V(CodeDataContainer, trampoline_trivial_code_data_container, \ 191 TrampolineTrivialCodeDataContainer) \ 192 V(CodeDataContainer, trampoline_promise_rejection_code_data_container, \ 193 TrampolinePromiseRejectionCodeDataContainer) \ 194 /* Canonical scope infos */ \ 195 V(ScopeInfo, global_this_binding_scope_info, GlobalThisBindingScopeInfo) \ 196 V(ScopeInfo, empty_function_scope_info, EmptyFunctionScopeInfo) \ 197 V(ScopeInfo, native_scope_info, NativeScopeInfo) \ 198 /* Hash seed */ \ 199 V(ByteArray, hash_seed, HashSeed) 200 201 // Mutable roots that are known to be immortal immovable, for which we can 202 // safely skip write barriers. 203 #define STRONG_MUTABLE_IMMOVABLE_ROOT_LIST(V) \ 204 ACCESSOR_INFO_ROOT_LIST(V) \ 205 /* Maps */ \ 206 V(Map, external_map, ExternalMap) \ 207 V(Map, message_object_map, JSMessageObjectMap) \ 208 V(Map, wasm_rttcanon_eqref_map, WasmRttEqrefMap) \ 209 V(Map, wasm_rttcanon_externref_map, WasmRttExternrefMap) \ 210 V(Map, wasm_rttcanon_funcref_map, WasmRttFuncrefMap) \ 211 V(Map, wasm_rttcanon_i31ref_map, WasmRttI31refMap) \ 212 /* Canonical empty values */ \ 213 V(Script, empty_script, EmptyScript) \ 214 V(FeedbackCell, many_closures_cell, ManyClosuresCell) \ 215 V(Cell, invalid_prototype_validity_cell, InvalidPrototypeValidityCell) \ 216 /* Protectors */ \ 217 V(PropertyCell, array_constructor_protector, ArrayConstructorProtector) \ 218 V(PropertyCell, no_elements_protector, NoElementsProtector) \ 219 V(PropertyCell, is_concat_spreadable_protector, IsConcatSpreadableProtector) \ 220 V(PropertyCell, array_species_protector, ArraySpeciesProtector) \ 221 V(PropertyCell, typed_array_species_protector, TypedArraySpeciesProtector) \ 222 V(PropertyCell, promise_species_protector, PromiseSpeciesProtector) \ 223 V(PropertyCell, regexp_species_protector, RegExpSpeciesProtector) \ 224 V(PropertyCell, string_length_protector, StringLengthProtector) \ 225 V(PropertyCell, array_iterator_protector, ArrayIteratorProtector) \ 226 V(PropertyCell, array_buffer_detaching_protector, \ 227 ArrayBufferDetachingProtector) \ 228 V(PropertyCell, promise_hook_protector, PromiseHookProtector) \ 229 V(PropertyCell, promise_resolve_protector, PromiseResolveProtector) \ 230 V(PropertyCell, map_iterator_protector, MapIteratorProtector) \ 231 V(PropertyCell, promise_then_protector, PromiseThenProtector) \ 232 V(PropertyCell, set_iterator_protector, SetIteratorProtector) \ 233 V(PropertyCell, string_iterator_protector, StringIteratorProtector) \ 234 /* Caches */ \ 235 V(FixedArray, single_character_string_cache, SingleCharacterStringCache) \ 236 V(FixedArray, string_split_cache, StringSplitCache) \ 237 V(FixedArray, regexp_multiple_cache, RegExpMultipleCache) \ 238 /* Indirection lists for isolate-independent builtins */ \ 239 V(FixedArray, builtins_constants_table, BuiltinsConstantsTable) \ 240 /* Internal SharedFunctionInfos */ \ 241 V(SharedFunctionInfo, async_function_await_reject_shared_fun, \ 242 AsyncFunctionAwaitRejectSharedFun) \ 243 V(SharedFunctionInfo, async_function_await_resolve_shared_fun, \ 244 AsyncFunctionAwaitResolveSharedFun) \ 245 V(SharedFunctionInfo, async_generator_await_reject_shared_fun, \ 246 AsyncGeneratorAwaitRejectSharedFun) \ 247 V(SharedFunctionInfo, async_generator_await_resolve_shared_fun, \ 248 AsyncGeneratorAwaitResolveSharedFun) \ 249 V(SharedFunctionInfo, async_generator_yield_resolve_shared_fun, \ 250 AsyncGeneratorYieldResolveSharedFun) \ 251 V(SharedFunctionInfo, async_generator_return_resolve_shared_fun, \ 252 AsyncGeneratorReturnResolveSharedFun) \ 253 V(SharedFunctionInfo, async_generator_return_closed_reject_shared_fun, \ 254 AsyncGeneratorReturnClosedRejectSharedFun) \ 255 V(SharedFunctionInfo, async_generator_return_closed_resolve_shared_fun, \ 256 AsyncGeneratorReturnClosedResolveSharedFun) \ 257 V(SharedFunctionInfo, async_iterator_value_unwrap_shared_fun, \ 258 AsyncIteratorValueUnwrapSharedFun) \ 259 V(SharedFunctionInfo, promise_all_resolve_element_shared_fun, \ 260 PromiseAllResolveElementSharedFun) \ 261 V(SharedFunctionInfo, promise_all_settled_resolve_element_shared_fun, \ 262 PromiseAllSettledResolveElementSharedFun) \ 263 V(SharedFunctionInfo, promise_all_settled_reject_element_shared_fun, \ 264 PromiseAllSettledRejectElementSharedFun) \ 265 V(SharedFunctionInfo, promise_any_reject_element_shared_fun, \ 266 PromiseAnyRejectElementSharedFun) \ 267 V(SharedFunctionInfo, promise_capability_default_reject_shared_fun, \ 268 PromiseCapabilityDefaultRejectSharedFun) \ 269 V(SharedFunctionInfo, promise_capability_default_resolve_shared_fun, \ 270 PromiseCapabilityDefaultResolveSharedFun) \ 271 V(SharedFunctionInfo, promise_catch_finally_shared_fun, \ 272 PromiseCatchFinallySharedFun) \ 273 V(SharedFunctionInfo, promise_get_capabilities_executor_shared_fun, \ 274 PromiseGetCapabilitiesExecutorSharedFun) \ 275 V(SharedFunctionInfo, promise_then_finally_shared_fun, \ 276 PromiseThenFinallySharedFun) \ 277 V(SharedFunctionInfo, promise_thrower_finally_shared_fun, \ 278 PromiseThrowerFinallySharedFun) \ 279 V(SharedFunctionInfo, promise_value_thunk_finally_shared_fun, \ 280 PromiseValueThunkFinallySharedFun) \ 281 V(SharedFunctionInfo, proxy_revoke_shared_fun, ProxyRevokeSharedFun) 282 283 // These root references can be updated by the mutator. 284 #define STRONG_MUTABLE_MOVABLE_ROOT_LIST(V) \ 285 /* Caches */ \ 286 V(FixedArray, number_string_cache, NumberStringCache) \ 287 /* Lists and dictionaries */ \ 288 V(NameDictionary, public_symbol_table, PublicSymbolTable) \ 289 V(NameDictionary, api_symbol_table, ApiSymbolTable) \ 290 V(NameDictionary, api_private_symbol_table, ApiPrivateSymbolTable) \ 291 V(WeakArrayList, script_list, ScriptList) \ 292 V(FixedArray, materialized_objects, MaterializedObjects) \ 293 V(WeakArrayList, detached_contexts, DetachedContexts) \ 294 V(WeakArrayList, retaining_path_targets, RetainingPathTargets) \ 295 /* Feedback vectors that we need for code coverage or type profile */ \ 296 V(Object, feedback_vectors_for_profiling_tools, \ 297 FeedbackVectorsForProfilingTools) \ 298 V(FixedArray, serialized_objects, SerializedObjects) \ 299 V(FixedArray, serialized_global_proxy_sizes, SerializedGlobalProxySizes) \ 300 V(TemplateList, message_listeners, MessageListeners) \ 301 /* Support for async stack traces */ \ 302 V(HeapObject, current_microtask, CurrentMicrotask) \ 303 /* KeepDuringJob set for JS WeakRefs */ \ 304 V(HeapObject, weak_refs_keep_during_job, WeakRefsKeepDuringJob) \ 305 V(HeapObject, interpreter_entry_trampoline_for_profiling, \ 306 InterpreterEntryTrampolineForProfiling) \ 307 V(Object, pending_optimize_for_test_bytecode, \ 308 PendingOptimizeForTestBytecode) \ 309 V(ArrayList, basic_block_profiling_data, BasicBlockProfilingData) \ 310 V(WeakArrayList, shared_wasm_memories, SharedWasmMemories) 311 312 // Entries in this list are limited to Smis and are not visited during GC. 313 #define SMI_ROOT_LIST(V) \ 314 V(Smi, last_script_id, LastScriptId) \ 315 V(Smi, last_debugging_id, LastDebuggingId) \ 316 /* To distinguish the function templates, so that we can find them in the */ \ 317 /* function cache of the native context. */ \ 318 V(Smi, next_template_serial_number, NextTemplateSerialNumber) \ 319 V(Smi, arguments_adaptor_deopt_pc_offset, ArgumentsAdaptorDeoptPCOffset) \ 320 V(Smi, construct_stub_create_deopt_pc_offset, \ 321 ConstructStubCreateDeoptPCOffset) \ 322 V(Smi, construct_stub_invoke_deopt_pc_offset, \ 323 ConstructStubInvokeDeoptPCOffset) \ 324 V(Smi, interpreter_entry_return_pc_offset, InterpreterEntryReturnPCOffset) 325 326 // Adapts one INTERNALIZED_STRING_LIST_GENERATOR entry to 327 // the ROOT_LIST-compatible entry 328 #define INTERNALIZED_STRING_LIST_ADAPTER(V, name, ...) V(String, name, name) 329 330 // Produces (String, name, CamelCase) entries 331 #define INTERNALIZED_STRING_ROOT_LIST(V) \ 332 INTERNALIZED_STRING_LIST_GENERATOR(INTERNALIZED_STRING_LIST_ADAPTER, V) 333 334 // Adapts one XXX_SYMBOL_LIST_GENERATOR entry to the ROOT_LIST-compatible entry 335 #define SYMBOL_ROOT_LIST_ADAPTER(V, name, ...) V(Symbol, name, name) 336 337 // Produces (Symbol, name, CamelCase) entries 338 #define PRIVATE_SYMBOL_ROOT_LIST(V) \ 339 PRIVATE_SYMBOL_LIST_GENERATOR(SYMBOL_ROOT_LIST_ADAPTER, V) 340 #define PUBLIC_SYMBOL_ROOT_LIST(V) \ 341 PUBLIC_SYMBOL_LIST_GENERATOR(SYMBOL_ROOT_LIST_ADAPTER, V) 342 #define WELL_KNOWN_SYMBOL_ROOT_LIST(V) \ 343 WELL_KNOWN_SYMBOL_LIST_GENERATOR(SYMBOL_ROOT_LIST_ADAPTER, V) 344 345 // Adapts one ACCESSOR_INFO_LIST_GENERATOR entry to the ROOT_LIST-compatible 346 // entry 347 #define ACCESSOR_INFO_ROOT_LIST_ADAPTER(V, name, CamelName, ...) \ 348 V(AccessorInfo, name##_accessor, CamelName##Accessor) 349 350 // Produces (AccessorInfo, name, CamelCase) entries 351 #define ACCESSOR_INFO_ROOT_LIST(V) \ 352 ACCESSOR_INFO_LIST_GENERATOR(ACCESSOR_INFO_ROOT_LIST_ADAPTER, V) 353 354 #define READ_ONLY_ROOT_LIST(V) \ 355 STRONG_READ_ONLY_ROOT_LIST(V) \ 356 INTERNALIZED_STRING_ROOT_LIST(V) \ 357 PRIVATE_SYMBOL_ROOT_LIST(V) \ 358 PUBLIC_SYMBOL_ROOT_LIST(V) \ 359 WELL_KNOWN_SYMBOL_ROOT_LIST(V) \ 360 STRUCT_MAPS_LIST(V) \ 361 TORQUE_DEFINED_MAP_ROOT_LIST(V) \ 362 ALLOCATION_SITE_MAPS_LIST(V) \ 363 DATA_HANDLER_MAPS_LIST(V) 364 365 #define MUTABLE_ROOT_LIST(V) \ 366 STRONG_MUTABLE_IMMOVABLE_ROOT_LIST(V) \ 367 STRONG_MUTABLE_MOVABLE_ROOT_LIST(V) \ 368 SMI_ROOT_LIST(V) 369 370 #define ROOT_LIST(V) \ 371 READ_ONLY_ROOT_LIST(V) \ 372 MUTABLE_ROOT_LIST(V) 373 374 // Declare all the root indices. This defines the root list order. 375 // clang-format off 376 enum class RootIndex : uint16_t { 377 #define DECL(type, name, CamelName) k##CamelName, 378 ROOT_LIST(DECL) 379 #undef DECL 380 381 kRootListLength, 382 383 // Helper aliases for inclusive regions of root indices. 384 kFirstRoot = 0, 385 kLastRoot = kRootListLength - 1, 386 387 #define ROOT(...) +1 388 kReadOnlyRootsCount = 0 READ_ONLY_ROOT_LIST(ROOT), 389 kImmortalImmovableRootsCount = 390 kReadOnlyRootsCount STRONG_MUTABLE_IMMOVABLE_ROOT_LIST(ROOT), 391 #undef ROOT 392 kFirstReadOnlyRoot = kFirstRoot, 393 kLastReadOnlyRoot = kFirstReadOnlyRoot + kReadOnlyRootsCount - 1, 394 395 // The strong roots visited by the garbage collector (not including read-only 396 // roots). 397 #define ROOT(...) +1 398 kMutableRootsCount = 0 399 STRONG_MUTABLE_IMMOVABLE_ROOT_LIST(ROOT) 400 STRONG_MUTABLE_MOVABLE_ROOT_LIST(ROOT), 401 #undef ROOT 402 kFirstStrongRoot = kLastReadOnlyRoot + 1, 403 kLastStrongRoot = kFirstStrongRoot + kMutableRootsCount - 1, 404 405 // All of the strong roots plus the read-only roots. 406 kFirstStrongOrReadOnlyRoot = kFirstRoot, 407 kLastStrongOrReadOnlyRoot = kLastStrongRoot, 408 409 // All immortal immovable roots including read only ones. 410 kFirstImmortalImmovableRoot = kFirstReadOnlyRoot, 411 kLastImmortalImmovableRoot = 412 kFirstImmortalImmovableRoot + kImmortalImmovableRootsCount - 1, 413 414 kFirstSmiRoot = kLastStrongRoot + 1, 415 kLastSmiRoot = kLastRoot 416 }; 417 // clang-format on 418 419 // Represents a storage of V8 heap roots. 420 class RootsTable { 421 public: 422 static constexpr size_t kEntriesCount = 423 static_cast<size_t>(RootIndex::kRootListLength); 424 RootsTable()425 RootsTable() : roots_{} {} 426 427 inline bool IsRootHandleLocation(Address* handle_location, 428 RootIndex* index) const; 429 430 template <typename T> 431 bool IsRootHandle(Handle<T> handle, RootIndex* index) const; 432 433 Address const& operator[](RootIndex root_index) const { 434 size_t index = static_cast<size_t>(root_index); 435 DCHECK_LT(index, kEntriesCount); 436 return roots_[index]; 437 } 438 slot(RootIndex root_index)439 FullObjectSlot slot(RootIndex root_index) { 440 size_t index = static_cast<size_t>(root_index); 441 DCHECK_LT(index, kEntriesCount); 442 return FullObjectSlot(&roots_[index]); 443 } 444 name(RootIndex root_index)445 static const char* name(RootIndex root_index) { 446 size_t index = static_cast<size_t>(root_index); 447 DCHECK_LT(index, kEntriesCount); 448 return root_names_[index]; 449 } 450 offset_of(RootIndex root_index)451 static constexpr int offset_of(RootIndex root_index) { 452 return static_cast<int>(root_index) * kSystemPointerSize; 453 } 454 455 // Immortal immovable root objects are allocated in OLD space and GC never 456 // moves them and the root table entries are guaranteed to not be modified 457 // after initialization. Note, however, that contents of those root objects 458 // that are allocated in writable space can still be modified after 459 // initialization. 460 // Generated code can treat direct references to these roots as constants. IsImmortalImmovable(RootIndex root_index)461 static constexpr bool IsImmortalImmovable(RootIndex root_index) { 462 STATIC_ASSERT(static_cast<int>(RootIndex::kFirstImmortalImmovableRoot) == 463 0); 464 return static_cast<unsigned>(root_index) <= 465 static_cast<unsigned>(RootIndex::kLastImmortalImmovableRoot); 466 } 467 468 private: begin()469 FullObjectSlot begin() { 470 return FullObjectSlot(&roots_[static_cast<size_t>(RootIndex::kFirstRoot)]); 471 } end()472 FullObjectSlot end() { 473 return FullObjectSlot( 474 &roots_[static_cast<size_t>(RootIndex::kLastRoot) + 1]); 475 } 476 477 // Used for iterating over all of the read-only and mutable strong roots. strong_or_read_only_roots_begin()478 FullObjectSlot strong_or_read_only_roots_begin() const { 479 STATIC_ASSERT(static_cast<size_t>(RootIndex::kLastReadOnlyRoot) == 480 static_cast<size_t>(RootIndex::kFirstStrongRoot) - 1); 481 return FullObjectSlot( 482 &roots_[static_cast<size_t>(RootIndex::kFirstStrongOrReadOnlyRoot)]); 483 } strong_or_read_only_roots_end()484 FullObjectSlot strong_or_read_only_roots_end() const { 485 return FullObjectSlot( 486 &roots_[static_cast<size_t>(RootIndex::kLastStrongOrReadOnlyRoot) + 1]); 487 } 488 489 // The read-only, strong and Smi roots as defined by these accessors are all 490 // disjoint. read_only_roots_begin()491 FullObjectSlot read_only_roots_begin() const { 492 return FullObjectSlot( 493 &roots_[static_cast<size_t>(RootIndex::kFirstReadOnlyRoot)]); 494 } read_only_roots_end()495 FullObjectSlot read_only_roots_end() const { 496 return FullObjectSlot( 497 &roots_[static_cast<size_t>(RootIndex::kLastReadOnlyRoot) + 1]); 498 } 499 strong_roots_begin()500 FullObjectSlot strong_roots_begin() const { 501 return FullObjectSlot( 502 &roots_[static_cast<size_t>(RootIndex::kFirstStrongRoot)]); 503 } strong_roots_end()504 FullObjectSlot strong_roots_end() const { 505 return FullObjectSlot( 506 &roots_[static_cast<size_t>(RootIndex::kLastStrongRoot) + 1]); 507 } 508 smi_roots_begin()509 FullObjectSlot smi_roots_begin() const { 510 return FullObjectSlot( 511 &roots_[static_cast<size_t>(RootIndex::kFirstSmiRoot)]); 512 } smi_roots_end()513 FullObjectSlot smi_roots_end() const { 514 return FullObjectSlot( 515 &roots_[static_cast<size_t>(RootIndex::kLastSmiRoot) + 1]); 516 } 517 518 Address& operator[](RootIndex root_index) { 519 size_t index = static_cast<size_t>(root_index); 520 DCHECK_LT(index, kEntriesCount); 521 return roots_[index]; 522 } 523 524 Address roots_[kEntriesCount]; 525 static const char* root_names_[kEntriesCount]; 526 527 friend class Isolate; 528 friend class Heap; 529 friend class Factory; 530 friend class PointerCompressedReadOnlyArtifacts; 531 friend class ReadOnlyHeap; 532 friend class ReadOnlyRoots; 533 friend class RootsSerializer; 534 friend class SoleReadOnlyHeap; 535 }; 536 537 class ReadOnlyRoots { 538 public: 539 static constexpr size_t kEntriesCount = 540 static_cast<size_t>(RootIndex::kReadOnlyRootsCount); 541 542 V8_INLINE explicit ReadOnlyRoots(Heap* heap); 543 V8_INLINE explicit ReadOnlyRoots(Isolate* isolate); 544 V8_INLINE explicit ReadOnlyRoots(LocalIsolate* isolate); 545 546 #define ROOT_ACCESSOR(Type, name, CamelName) \ 547 V8_INLINE class Type name() const; \ 548 V8_INLINE class Type unchecked_##name() const; \ 549 V8_INLINE Handle<Type> name##_handle() const; 550 551 READ_ONLY_ROOT_LIST(ROOT_ACCESSOR) 552 #undef ROOT_ACCESSOR 553 554 // Get the address of a given read-only root index, without type checks. 555 V8_INLINE Address at(RootIndex root_index) const; 556 557 // Iterate over all the read-only roots. This is not necessary for garbage 558 // collection and is usually only performed as part of (de)serialization or 559 // heap verification. 560 void Iterate(RootVisitor* visitor); 561 562 private: 563 #ifdef DEBUG 564 #define ROOT_TYPE_CHECK(Type, name, CamelName) \ 565 V8_EXPORT_PRIVATE bool CheckType_##name() const; 566 READ_ONLY_ROOT_LIST(ROOT_TYPE_CHECK)567 READ_ONLY_ROOT_LIST(ROOT_TYPE_CHECK) 568 #undef ROOT_TYPE_CHECK 569 #endif 570 571 V8_INLINE explicit ReadOnlyRoots(Address* ro_roots) 572 : read_only_roots_(ro_roots) {} 573 574 V8_INLINE Address* GetLocation(RootIndex root_index) const; 575 576 Address* read_only_roots_; 577 578 friend class ReadOnlyHeap; 579 friend class DeserializerAllocator; 580 }; 581 582 } // namespace internal 583 } // namespace v8 584 585 #endif // V8_ROOTS_ROOTS_H_ 586