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, mega_dom_handler_map, MegaDomHandlerMap) \ 92 V(Map, module_info_map, ModuleInfoMap) \ 93 V(Map, name_dictionary_map, NameDictionaryMap) \ 94 V(Map, no_closures_cell_map, NoClosuresCellMap) \ 95 V(Map, number_dictionary_map, NumberDictionaryMap) \ 96 V(Map, one_closure_cell_map, OneClosureCellMap) \ 97 V(Map, ordered_hash_map_map, OrderedHashMapMap) \ 98 V(Map, ordered_hash_set_map, OrderedHashSetMap) \ 99 V(Map, name_to_index_hash_table_map, NameToIndexHashTableMap) \ 100 V(Map, registered_symbol_table_map, RegisteredSymbolTableMap) \ 101 V(Map, ordered_name_dictionary_map, OrderedNameDictionaryMap) \ 102 V(Map, preparse_data_map, PreparseDataMap) \ 103 V(Map, property_array_map, PropertyArrayMap) \ 104 V(Map, side_effect_call_handler_info_map, SideEffectCallHandlerInfoMap) \ 105 V(Map, side_effect_free_call_handler_info_map, \ 106 SideEffectFreeCallHandlerInfoMap) \ 107 V(Map, next_call_side_effect_free_call_handler_info_map, \ 108 NextCallSideEffectFreeCallHandlerInfoMap) \ 109 V(Map, simple_number_dictionary_map, SimpleNumberDictionaryMap) \ 110 V(Map, small_ordered_hash_map_map, SmallOrderedHashMapMap) \ 111 V(Map, small_ordered_hash_set_map, SmallOrderedHashSetMap) \ 112 V(Map, small_ordered_name_dictionary_map, SmallOrderedNameDictionaryMap) \ 113 V(Map, source_text_module_map, SourceTextModuleMap) \ 114 V(Map, swiss_name_dictionary_map, SwissNameDictionaryMap) \ 115 V(Map, synthetic_module_map, SyntheticModuleMap) \ 116 IF_WASM(V, Map, wasm_api_function_ref_map, WasmApiFunctionRefMap) \ 117 IF_WASM(V, Map, wasm_capi_function_data_map, WasmCapiFunctionDataMap) \ 118 IF_WASM(V, Map, wasm_exported_function_data_map, \ 119 WasmExportedFunctionDataMap) \ 120 IF_WASM(V, Map, wasm_internal_function_map, WasmInternalFunctionMap) \ 121 IF_WASM(V, Map, wasm_js_function_data_map, WasmJSFunctionDataMap) \ 122 IF_WASM(V, Map, wasm_onfulfilled_data_map, WasmOnFulfilledDataMap) \ 123 IF_WASM(V, Map, wasm_type_info_map, WasmTypeInfoMap) \ 124 V(Map, weak_fixed_array_map, WeakFixedArrayMap) \ 125 V(Map, weak_array_list_map, WeakArrayListMap) \ 126 V(Map, ephemeron_hash_table_map, EphemeronHashTableMap) \ 127 V(Map, embedder_data_array_map, EmbedderDataArrayMap) \ 128 V(Map, weak_cell_map, WeakCellMap) \ 129 /* String maps */ \ 130 V(Map, string_map, StringMap) \ 131 V(Map, cons_one_byte_string_map, ConsOneByteStringMap) \ 132 V(Map, cons_string_map, ConsStringMap) \ 133 V(Map, thin_string_map, ThinStringMap) \ 134 V(Map, sliced_string_map, SlicedStringMap) \ 135 V(Map, sliced_one_byte_string_map, SlicedOneByteStringMap) \ 136 V(Map, external_string_map, ExternalStringMap) \ 137 V(Map, external_one_byte_string_map, ExternalOneByteStringMap) \ 138 V(Map, uncached_external_string_map, UncachedExternalStringMap) \ 139 V(Map, internalized_string_map, InternalizedStringMap) \ 140 V(Map, external_internalized_string_map, ExternalInternalizedStringMap) \ 141 V(Map, external_one_byte_internalized_string_map, \ 142 ExternalOneByteInternalizedStringMap) \ 143 V(Map, uncached_external_internalized_string_map, \ 144 UncachedExternalInternalizedStringMap) \ 145 V(Map, uncached_external_one_byte_internalized_string_map, \ 146 UncachedExternalOneByteInternalizedStringMap) \ 147 V(Map, uncached_external_one_byte_string_map, \ 148 UncachedExternalOneByteStringMap) \ 149 V(Map, shared_one_byte_string_map, SharedOneByteStringMap) \ 150 V(Map, shared_string_map, SharedStringMap) \ 151 V(Map, shared_thin_one_byte_string_map, SharedThinOneByteStringMap) \ 152 V(Map, shared_thin_string_map, SharedThinStringMap) \ 153 V(Map, seq_string_migration_sentinel_map, \ 154 TwoByteSeqStringMigrationSentinelMap) \ 155 V(Map, one_byte_seq_string_migration_sentinel_map, \ 156 OneByteSeqStringMigrationSentinelMap) \ 157 /* Oddball maps */ \ 158 V(Map, undefined_map, UndefinedMap) \ 159 V(Map, the_hole_map, TheHoleMap) \ 160 V(Map, null_map, NullMap) \ 161 V(Map, boolean_map, BooleanMap) \ 162 V(Map, uninitialized_map, UninitializedMap) \ 163 V(Map, arguments_marker_map, ArgumentsMarkerMap) \ 164 V(Map, exception_map, ExceptionMap) \ 165 V(Map, termination_exception_map, TerminationExceptionMap) \ 166 V(Map, optimized_out_map, OptimizedOutMap) \ 167 V(Map, stale_register_map, StaleRegisterMap) \ 168 V(Map, self_reference_marker_map, SelfReferenceMarkerMap) \ 169 V(Map, basic_block_counters_marker_map, BasicBlockCountersMarkerMap) \ 170 /* Canonical empty values */ \ 171 V(EnumCache, empty_enum_cache, EmptyEnumCache) \ 172 V(PropertyArray, empty_property_array, EmptyPropertyArray) \ 173 V(ByteArray, empty_byte_array, EmptyByteArray) \ 174 V(ObjectBoilerplateDescription, empty_object_boilerplate_description, \ 175 EmptyObjectBoilerplateDescription) \ 176 V(ArrayBoilerplateDescription, empty_array_boilerplate_description, \ 177 EmptyArrayBoilerplateDescription) \ 178 V(ClosureFeedbackCellArray, empty_closure_feedback_cell_array, \ 179 EmptyClosureFeedbackCellArray) \ 180 V(NumberDictionary, empty_slow_element_dictionary, \ 181 EmptySlowElementDictionary) \ 182 V(OrderedHashMap, empty_ordered_hash_map, EmptyOrderedHashMap) \ 183 V(OrderedHashSet, empty_ordered_hash_set, EmptyOrderedHashSet) \ 184 V(FeedbackMetadata, empty_feedback_metadata, EmptyFeedbackMetadata) \ 185 V(NameDictionary, empty_property_dictionary, EmptyPropertyDictionary) \ 186 V(OrderedNameDictionary, empty_ordered_property_dictionary, \ 187 EmptyOrderedPropertyDictionary) \ 188 V(SwissNameDictionary, empty_swiss_property_dictionary, \ 189 EmptySwissPropertyDictionary) \ 190 V(InterceptorInfo, noop_interceptor_info, NoOpInterceptorInfo) \ 191 V(ArrayList, empty_array_list, EmptyArrayList) \ 192 V(WeakFixedArray, empty_weak_fixed_array, EmptyWeakFixedArray) \ 193 V(WeakArrayList, empty_weak_array_list, EmptyWeakArrayList) \ 194 /* Special numbers */ \ 195 V(HeapNumber, nan_value, NanValue) \ 196 V(HeapNumber, hole_nan_value, HoleNanValue) \ 197 V(HeapNumber, infinity_value, InfinityValue) \ 198 V(HeapNumber, minus_zero_value, MinusZeroValue) \ 199 V(HeapNumber, minus_infinity_value, MinusInfinityValue) \ 200 /* Marker for self-references during code-generation */ \ 201 V(HeapObject, self_reference_marker, SelfReferenceMarker) \ 202 /* Marker for basic-block usage counters array during code-generation */ \ 203 V(Oddball, basic_block_counters_marker, BasicBlockCountersMarker) \ 204 /* Canonical off-heap trampoline data */ \ 205 V(ByteArray, off_heap_trampoline_relocation_info, \ 206 OffHeapTrampolineRelocationInfo) \ 207 V(HeapObject, trampoline_trivial_code_data_container, \ 208 TrampolineTrivialCodeDataContainer) \ 209 V(HeapObject, trampoline_promise_rejection_code_data_container, \ 210 TrampolinePromiseRejectionCodeDataContainer) \ 211 /* Canonical scope infos */ \ 212 V(ScopeInfo, global_this_binding_scope_info, GlobalThisBindingScopeInfo) \ 213 V(ScopeInfo, empty_function_scope_info, EmptyFunctionScopeInfo) \ 214 V(ScopeInfo, native_scope_info, NativeScopeInfo) \ 215 /* Hash seed */ \ 216 V(ByteArray, hash_seed, HashSeed) 217 218 // Mutable roots that are known to be immortal immovable, for which we can 219 // safely skip write barriers. 220 #define STRONG_MUTABLE_IMMOVABLE_ROOT_LIST(V) \ 221 ACCESSOR_INFO_ROOT_LIST(V) \ 222 /* Maps */ \ 223 V(Map, external_map, ExternalMap) \ 224 V(Map, message_object_map, JSMessageObjectMap) \ 225 /* Canonical empty values */ \ 226 V(Script, empty_script, EmptyScript) \ 227 V(FeedbackCell, many_closures_cell, ManyClosuresCell) \ 228 V(Cell, invalid_prototype_validity_cell, InvalidPrototypeValidityCell) \ 229 /* Protectors */ \ 230 V(PropertyCell, array_constructor_protector, ArrayConstructorProtector) \ 231 V(PropertyCell, no_elements_protector, NoElementsProtector) \ 232 V(PropertyCell, mega_dom_protector, MegaDOMProtector) \ 233 V(PropertyCell, is_concat_spreadable_protector, IsConcatSpreadableProtector) \ 234 V(PropertyCell, array_species_protector, ArraySpeciesProtector) \ 235 V(PropertyCell, typed_array_species_protector, TypedArraySpeciesProtector) \ 236 V(PropertyCell, promise_species_protector, PromiseSpeciesProtector) \ 237 V(PropertyCell, regexp_species_protector, RegExpSpeciesProtector) \ 238 V(PropertyCell, string_length_protector, StringLengthProtector) \ 239 V(PropertyCell, array_iterator_protector, ArrayIteratorProtector) \ 240 V(PropertyCell, array_buffer_detaching_protector, \ 241 ArrayBufferDetachingProtector) \ 242 V(PropertyCell, promise_hook_protector, PromiseHookProtector) \ 243 V(PropertyCell, promise_resolve_protector, PromiseResolveProtector) \ 244 V(PropertyCell, map_iterator_protector, MapIteratorProtector) \ 245 V(PropertyCell, promise_then_protector, PromiseThenProtector) \ 246 V(PropertyCell, set_iterator_protector, SetIteratorProtector) \ 247 V(PropertyCell, string_iterator_protector, StringIteratorProtector) \ 248 /* Caches */ \ 249 V(FixedArray, single_character_string_cache, SingleCharacterStringCache) \ 250 V(FixedArray, string_split_cache, StringSplitCache) \ 251 V(FixedArray, regexp_multiple_cache, RegExpMultipleCache) \ 252 /* Indirection lists for isolate-independent builtins */ \ 253 V(FixedArray, builtins_constants_table, BuiltinsConstantsTable) \ 254 /* Internal SharedFunctionInfos */ \ 255 V(SharedFunctionInfo, async_function_await_reject_shared_fun, \ 256 AsyncFunctionAwaitRejectSharedFun) \ 257 V(SharedFunctionInfo, async_function_await_resolve_shared_fun, \ 258 AsyncFunctionAwaitResolveSharedFun) \ 259 V(SharedFunctionInfo, async_generator_await_reject_shared_fun, \ 260 AsyncGeneratorAwaitRejectSharedFun) \ 261 V(SharedFunctionInfo, async_generator_await_resolve_shared_fun, \ 262 AsyncGeneratorAwaitResolveSharedFun) \ 263 V(SharedFunctionInfo, async_generator_yield_resolve_shared_fun, \ 264 AsyncGeneratorYieldResolveSharedFun) \ 265 V(SharedFunctionInfo, async_generator_return_resolve_shared_fun, \ 266 AsyncGeneratorReturnResolveSharedFun) \ 267 V(SharedFunctionInfo, async_generator_return_closed_reject_shared_fun, \ 268 AsyncGeneratorReturnClosedRejectSharedFun) \ 269 V(SharedFunctionInfo, async_generator_return_closed_resolve_shared_fun, \ 270 AsyncGeneratorReturnClosedResolveSharedFun) \ 271 V(SharedFunctionInfo, async_iterator_value_unwrap_shared_fun, \ 272 AsyncIteratorValueUnwrapSharedFun) \ 273 V(SharedFunctionInfo, promise_all_resolve_element_shared_fun, \ 274 PromiseAllResolveElementSharedFun) \ 275 V(SharedFunctionInfo, promise_all_settled_resolve_element_shared_fun, \ 276 PromiseAllSettledResolveElementSharedFun) \ 277 V(SharedFunctionInfo, promise_all_settled_reject_element_shared_fun, \ 278 PromiseAllSettledRejectElementSharedFun) \ 279 V(SharedFunctionInfo, promise_any_reject_element_shared_fun, \ 280 PromiseAnyRejectElementSharedFun) \ 281 V(SharedFunctionInfo, promise_capability_default_reject_shared_fun, \ 282 PromiseCapabilityDefaultRejectSharedFun) \ 283 V(SharedFunctionInfo, promise_capability_default_resolve_shared_fun, \ 284 PromiseCapabilityDefaultResolveSharedFun) \ 285 V(SharedFunctionInfo, promise_catch_finally_shared_fun, \ 286 PromiseCatchFinallySharedFun) \ 287 V(SharedFunctionInfo, promise_get_capabilities_executor_shared_fun, \ 288 PromiseGetCapabilitiesExecutorSharedFun) \ 289 V(SharedFunctionInfo, promise_then_finally_shared_fun, \ 290 PromiseThenFinallySharedFun) \ 291 V(SharedFunctionInfo, promise_thrower_finally_shared_fun, \ 292 PromiseThrowerFinallySharedFun) \ 293 V(SharedFunctionInfo, promise_value_thunk_finally_shared_fun, \ 294 PromiseValueThunkFinallySharedFun) \ 295 V(SharedFunctionInfo, proxy_revoke_shared_fun, ProxyRevokeSharedFun) 296 297 // These root references can be updated by the mutator. 298 #define STRONG_MUTABLE_MOVABLE_ROOT_LIST(V) \ 299 /* Caches */ \ 300 V(FixedArray, number_string_cache, NumberStringCache) \ 301 /* Lists and dictionaries */ \ 302 V(RegisteredSymbolTable, public_symbol_table, PublicSymbolTable) \ 303 V(RegisteredSymbolTable, api_symbol_table, ApiSymbolTable) \ 304 V(RegisteredSymbolTable, api_private_symbol_table, ApiPrivateSymbolTable) \ 305 V(WeakArrayList, script_list, ScriptList) \ 306 V(FixedArray, materialized_objects, MaterializedObjects) \ 307 V(WeakArrayList, detached_contexts, DetachedContexts) \ 308 V(WeakArrayList, retaining_path_targets, RetainingPathTargets) \ 309 /* Feedback vectors that we need for code coverage or type profile */ \ 310 V(Object, feedback_vectors_for_profiling_tools, \ 311 FeedbackVectorsForProfilingTools) \ 312 V(FixedArray, serialized_objects, SerializedObjects) \ 313 V(FixedArray, serialized_global_proxy_sizes, SerializedGlobalProxySizes) \ 314 V(TemplateList, message_listeners, MessageListeners) \ 315 /* Support for async stack traces */ \ 316 V(HeapObject, current_microtask, CurrentMicrotask) \ 317 /* KeepDuringJob set for JS WeakRefs */ \ 318 V(HeapObject, weak_refs_keep_during_job, WeakRefsKeepDuringJob) \ 319 V(HeapObject, interpreter_entry_trampoline_for_profiling, \ 320 InterpreterEntryTrampolineForProfiling) \ 321 V(Object, pending_optimize_for_test_bytecode, \ 322 PendingOptimizeForTestBytecode) \ 323 V(ArrayList, basic_block_profiling_data, BasicBlockProfilingData) \ 324 V(WeakArrayList, shared_wasm_memories, SharedWasmMemories) \ 325 IF_WASM(V, HeapObject, active_continuation, ActiveContinuation) \ 326 IF_WASM(V, HeapObject, active_suspender, ActiveSuspender) \ 327 IF_WASM(V, WeakArrayList, wasm_canonical_rtts, WasmCanonicalRtts) 328 329 // Entries in this list are limited to Smis and are not visited during GC. 330 #define SMI_ROOT_LIST(V) \ 331 V(Smi, last_script_id, LastScriptId) \ 332 V(Smi, last_debugging_id, LastDebuggingId) \ 333 /* To distinguish the function templates, so that we can find them in the */ \ 334 /* function cache of the native context. */ \ 335 V(Smi, next_template_serial_number, NextTemplateSerialNumber) \ 336 V(Smi, construct_stub_create_deopt_pc_offset, \ 337 ConstructStubCreateDeoptPCOffset) \ 338 V(Smi, construct_stub_invoke_deopt_pc_offset, \ 339 ConstructStubInvokeDeoptPCOffset) \ 340 V(Smi, interpreter_entry_return_pc_offset, InterpreterEntryReturnPCOffset) 341 342 // Adapts one INTERNALIZED_STRING_LIST_GENERATOR entry to 343 // the ROOT_LIST-compatible entry 344 #define INTERNALIZED_STRING_LIST_ADAPTER(V, name, ...) V(String, name, name) 345 346 // Produces (String, name, CamelCase) entries 347 #define INTERNALIZED_STRING_ROOT_LIST(V) \ 348 INTERNALIZED_STRING_LIST_GENERATOR(INTERNALIZED_STRING_LIST_ADAPTER, V) 349 350 // Adapts one XXX_SYMBOL_LIST_GENERATOR entry to the ROOT_LIST-compatible entry 351 #define SYMBOL_ROOT_LIST_ADAPTER(V, name, ...) V(Symbol, name, name) 352 353 // Produces (Symbol, name, CamelCase) entries 354 #define PRIVATE_SYMBOL_ROOT_LIST(V) \ 355 PRIVATE_SYMBOL_LIST_GENERATOR(SYMBOL_ROOT_LIST_ADAPTER, V) 356 #define PUBLIC_SYMBOL_ROOT_LIST(V) \ 357 PUBLIC_SYMBOL_LIST_GENERATOR(SYMBOL_ROOT_LIST_ADAPTER, V) 358 #define WELL_KNOWN_SYMBOL_ROOT_LIST(V) \ 359 WELL_KNOWN_SYMBOL_LIST_GENERATOR(SYMBOL_ROOT_LIST_ADAPTER, V) 360 361 // Adapts one ACCESSOR_INFO_LIST_GENERATOR entry to the ROOT_LIST-compatible 362 // entry 363 #define ACCESSOR_INFO_ROOT_LIST_ADAPTER(V, name, CamelName, ...) \ 364 V(AccessorInfo, name##_accessor, CamelName##Accessor) 365 366 // Produces (AccessorInfo, name, CamelCase) entries 367 #define ACCESSOR_INFO_ROOT_LIST(V) \ 368 ACCESSOR_INFO_LIST_GENERATOR(ACCESSOR_INFO_ROOT_LIST_ADAPTER, V) 369 370 #define READ_ONLY_ROOT_LIST(V) \ 371 STRONG_READ_ONLY_ROOT_LIST(V) \ 372 INTERNALIZED_STRING_ROOT_LIST(V) \ 373 PRIVATE_SYMBOL_ROOT_LIST(V) \ 374 PUBLIC_SYMBOL_ROOT_LIST(V) \ 375 WELL_KNOWN_SYMBOL_ROOT_LIST(V) \ 376 STRUCT_MAPS_LIST(V) \ 377 TORQUE_DEFINED_MAP_ROOT_LIST(V) \ 378 ALLOCATION_SITE_MAPS_LIST(V) \ 379 DATA_HANDLER_MAPS_LIST(V) 380 381 #define MUTABLE_ROOT_LIST(V) \ 382 STRONG_MUTABLE_IMMOVABLE_ROOT_LIST(V) \ 383 STRONG_MUTABLE_MOVABLE_ROOT_LIST(V) \ 384 SMI_ROOT_LIST(V) 385 386 #define ROOT_LIST(V) \ 387 READ_ONLY_ROOT_LIST(V) \ 388 MUTABLE_ROOT_LIST(V) 389 390 // Declare all the root indices. This defines the root list order. 391 // clang-format off 392 enum class RootIndex : uint16_t { 393 #define DECL(type, name, CamelName) k##CamelName, 394 ROOT_LIST(DECL) 395 #undef DECL 396 397 kRootListLength, 398 399 // Helper aliases for inclusive regions of root indices. 400 kFirstRoot = 0, 401 kLastRoot = kRootListLength - 1, 402 403 #define ROOT(...) +1 404 kReadOnlyRootsCount = 0 READ_ONLY_ROOT_LIST(ROOT), 405 kImmortalImmovableRootsCount = 406 kReadOnlyRootsCount STRONG_MUTABLE_IMMOVABLE_ROOT_LIST(ROOT), 407 #undef ROOT 408 kFirstReadOnlyRoot = kFirstRoot, 409 kLastReadOnlyRoot = kFirstReadOnlyRoot + kReadOnlyRootsCount - 1, 410 411 // The strong roots visited by the garbage collector (not including read-only 412 // roots). 413 #define ROOT(...) +1 414 kMutableRootsCount = 0 415 STRONG_MUTABLE_IMMOVABLE_ROOT_LIST(ROOT) 416 STRONG_MUTABLE_MOVABLE_ROOT_LIST(ROOT), 417 #undef ROOT 418 kFirstStrongRoot = kLastReadOnlyRoot + 1, 419 kLastStrongRoot = kFirstStrongRoot + kMutableRootsCount - 1, 420 421 // All of the strong roots plus the read-only roots. 422 kFirstStrongOrReadOnlyRoot = kFirstRoot, 423 kLastStrongOrReadOnlyRoot = kLastStrongRoot, 424 425 // All immortal immovable roots including read only ones. 426 kFirstImmortalImmovableRoot = kFirstReadOnlyRoot, 427 kLastImmortalImmovableRoot = 428 kFirstImmortalImmovableRoot + kImmortalImmovableRootsCount - 1, 429 430 kFirstSmiRoot = kLastStrongRoot + 1, 431 kLastSmiRoot = kLastRoot 432 }; 433 // clang-format on 434 435 // Represents a storage of V8 heap roots. 436 class RootsTable { 437 public: 438 static constexpr size_t kEntriesCount = 439 static_cast<size_t>(RootIndex::kRootListLength); 440 RootsTable()441 RootsTable() : roots_{} {} 442 443 inline bool IsRootHandleLocation(Address* handle_location, 444 RootIndex* index) const; 445 446 template <typename T> 447 bool IsRootHandle(Handle<T> handle, RootIndex* index) const; 448 449 Address const& operator[](RootIndex root_index) const { 450 size_t index = static_cast<size_t>(root_index); 451 DCHECK_LT(index, kEntriesCount); 452 return roots_[index]; 453 } 454 slot(RootIndex root_index)455 FullObjectSlot slot(RootIndex root_index) { 456 size_t index = static_cast<size_t>(root_index); 457 DCHECK_LT(index, kEntriesCount); 458 return FullObjectSlot(&roots_[index]); 459 } 460 name(RootIndex root_index)461 static const char* name(RootIndex root_index) { 462 size_t index = static_cast<size_t>(root_index); 463 DCHECK_LT(index, kEntriesCount); 464 return root_names_[index]; 465 } 466 offset_of(RootIndex root_index)467 static constexpr int offset_of(RootIndex root_index) { 468 return static_cast<int>(root_index) * kSystemPointerSize; 469 } 470 471 // Immortal immovable root objects are allocated in OLD space and GC never 472 // moves them and the root table entries are guaranteed to not be modified 473 // after initialization. Note, however, that contents of those root objects 474 // that are allocated in writable space can still be modified after 475 // initialization. 476 // Generated code can treat direct references to these roots as constants. IsImmortalImmovable(RootIndex root_index)477 static constexpr bool IsImmortalImmovable(RootIndex root_index) { 478 STATIC_ASSERT(static_cast<int>(RootIndex::kFirstImmortalImmovableRoot) == 479 0); 480 return static_cast<unsigned>(root_index) <= 481 static_cast<unsigned>(RootIndex::kLastImmortalImmovableRoot); 482 } 483 484 private: begin()485 FullObjectSlot begin() { 486 return FullObjectSlot(&roots_[static_cast<size_t>(RootIndex::kFirstRoot)]); 487 } end()488 FullObjectSlot end() { 489 return FullObjectSlot( 490 &roots_[static_cast<size_t>(RootIndex::kLastRoot) + 1]); 491 } 492 493 // Used for iterating over all of the read-only and mutable strong roots. strong_or_read_only_roots_begin()494 FullObjectSlot strong_or_read_only_roots_begin() const { 495 STATIC_ASSERT(static_cast<size_t>(RootIndex::kLastReadOnlyRoot) == 496 static_cast<size_t>(RootIndex::kFirstStrongRoot) - 1); 497 return FullObjectSlot( 498 &roots_[static_cast<size_t>(RootIndex::kFirstStrongOrReadOnlyRoot)]); 499 } strong_or_read_only_roots_end()500 FullObjectSlot strong_or_read_only_roots_end() const { 501 return FullObjectSlot( 502 &roots_[static_cast<size_t>(RootIndex::kLastStrongOrReadOnlyRoot) + 1]); 503 } 504 505 // The read-only, strong and Smi roots as defined by these accessors are all 506 // disjoint. read_only_roots_begin()507 FullObjectSlot read_only_roots_begin() const { 508 return FullObjectSlot( 509 &roots_[static_cast<size_t>(RootIndex::kFirstReadOnlyRoot)]); 510 } read_only_roots_end()511 FullObjectSlot read_only_roots_end() const { 512 return FullObjectSlot( 513 &roots_[static_cast<size_t>(RootIndex::kLastReadOnlyRoot) + 1]); 514 } 515 strong_roots_begin()516 FullObjectSlot strong_roots_begin() const { 517 return FullObjectSlot( 518 &roots_[static_cast<size_t>(RootIndex::kFirstStrongRoot)]); 519 } strong_roots_end()520 FullObjectSlot strong_roots_end() const { 521 return FullObjectSlot( 522 &roots_[static_cast<size_t>(RootIndex::kLastStrongRoot) + 1]); 523 } 524 smi_roots_begin()525 FullObjectSlot smi_roots_begin() const { 526 return FullObjectSlot( 527 &roots_[static_cast<size_t>(RootIndex::kFirstSmiRoot)]); 528 } smi_roots_end()529 FullObjectSlot smi_roots_end() const { 530 return FullObjectSlot( 531 &roots_[static_cast<size_t>(RootIndex::kLastSmiRoot) + 1]); 532 } 533 534 Address& operator[](RootIndex root_index) { 535 size_t index = static_cast<size_t>(root_index); 536 DCHECK_LT(index, kEntriesCount); 537 return roots_[index]; 538 } 539 540 Address roots_[kEntriesCount]; 541 static const char* root_names_[kEntriesCount]; 542 543 friend class Isolate; 544 friend class Heap; 545 friend class Factory; 546 friend class PointerCompressedReadOnlyArtifacts; 547 friend class ReadOnlyHeap; 548 friend class ReadOnlyRoots; 549 friend class RootsSerializer; 550 friend class SoleReadOnlyHeap; 551 }; 552 553 class ReadOnlyRoots { 554 public: 555 static constexpr size_t kEntriesCount = 556 static_cast<size_t>(RootIndex::kReadOnlyRootsCount); 557 558 V8_INLINE explicit ReadOnlyRoots(Heap* heap); 559 V8_INLINE explicit ReadOnlyRoots(Isolate* isolate); 560 V8_INLINE explicit ReadOnlyRoots(LocalIsolate* isolate); 561 562 // For `v8_enable_map_packing=true`, this will return a packed (also untagged) 563 // map-word instead of a tagged heap pointer. 564 MapWord one_pointer_filler_map_word(); 565 566 #define ROOT_ACCESSOR(Type, name, CamelName) \ 567 V8_INLINE class Type name() const; \ 568 V8_INLINE class Type unchecked_##name() const; \ 569 V8_INLINE Handle<Type> name##_handle() const; 570 571 READ_ONLY_ROOT_LIST(ROOT_ACCESSOR) 572 #undef ROOT_ACCESSOR 573 574 // Get the address of a given read-only root index, without type checks. 575 V8_INLINE Address at(RootIndex root_index) const; 576 577 // Iterate over all the read-only roots. This is not necessary for garbage 578 // collection and is usually only performed as part of (de)serialization or 579 // heap verification. 580 void Iterate(RootVisitor* visitor); 581 582 private: 583 #ifdef DEBUG 584 #define ROOT_TYPE_CHECK(Type, name, CamelName) \ 585 V8_EXPORT_PRIVATE bool CheckType_##name() const; 586 READ_ONLY_ROOT_LIST(ROOT_TYPE_CHECK)587 READ_ONLY_ROOT_LIST(ROOT_TYPE_CHECK) 588 #undef ROOT_TYPE_CHECK 589 #endif 590 591 V8_INLINE explicit ReadOnlyRoots(Address* ro_roots) 592 : read_only_roots_(ro_roots) {} 593 594 V8_INLINE Address* GetLocation(RootIndex root_index) const; 595 596 Address* read_only_roots_; 597 598 friend class ReadOnlyHeap; 599 friend class DeserializerAllocator; 600 }; 601 602 } // namespace internal 603 } // namespace v8 604 605 #endif // V8_ROOTS_ROOTS_H_ 606