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
15namespace v8 {
16namespace internal {
17
18// Forward declarations.
19enum ElementsKind : uint8_t;
20class FixedTypedArrayBase;
21template <typename T>
22class Handle;
23class Heap;
24class Isolate;
25class Map;
26class PropertyCell;
27class String;
28class Symbol;
29class 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
358enum 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.
398class 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
511class 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