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