• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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