[explicit isolates] Add ReadOnlyRoots

Adds a ReadOnlyRoots class trivially constructable from a Heap* or
Isolate* and which can be obtained from a any HeapObject which provides
access to roots objects that will always be in RO_SPACE. In the longer
term this object will be accessed via a global variable without
requiring an Isolate or using the memory address of a HeapObject to
infer it.

Moves the list macros in heap.h to roots.h and splits some of them into
two parts (read-only and mutable).

Convert cases of heap_object->GetHeap()->root_accessor() to
heap_objects->GetReadOnlyRoots().root_accessor().

Bug: v8:7786
Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng
Change-Id: I14b01052adb2af9a5ec82b970e933d6a423d17a5
Reviewed-on: https://chromium-review.googlesource.com/1122127
Commit-Queue: Dan Elphick <delphick@chromium.org>
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: Hannes Payer <hpayer@chromium.org>
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54160}
This commit is contained in:
Dan Elphick 2018-07-03 09:37:51 +01:00 committed by Commit Bot
parent a8582eb2f1
commit ff32ba8e54
19 changed files with 491 additions and 370 deletions

View File

@ -2275,6 +2275,8 @@ v8_source_set("v8_base") {
"src/register-configuration.cc",
"src/register-configuration.h",
"src/reglist.h",
"src/roots-inl.h",
"src/roots.h",
"src/runtime-profiler.cc",
"src/runtime-profiler.h",
"src/runtime/runtime-array.cc",

View File

@ -9260,7 +9260,8 @@ bool debug::Script::WasCompiled() const {
bool debug::Script::IsEmbedded() const {
i::Handle<i::Script> script = Utils::OpenHandle(this);
return script->context_data() == script->GetHeap()->uninitialized_symbol();
return script->context_data() ==
script->GetReadOnlyRoots().uninitialized_symbol();
}
int debug::Script::Id() const { return Utils::OpenHandle(this)->id(); }

View File

@ -313,7 +313,7 @@ static void CopySmiToDoubleElements(FixedArrayBase* from_base,
if (copy_size == 0) return;
FixedArray* from = FixedArray::cast(from_base);
FixedDoubleArray* to = FixedDoubleArray::cast(to_base);
Object* the_hole = from->GetHeap()->the_hole_value();
Object* the_hole = from->GetReadOnlyRoots().the_hole_value();
for (uint32_t from_end = from_start + static_cast<uint32_t>(copy_size);
from_start < from_end; from_start++, to_start++) {
Object* hole_or_smi = from->get(from_start);
@ -386,7 +386,7 @@ static void CopyObjectToDoubleElements(FixedArrayBase* from_base,
if (copy_size == 0) return;
FixedArray* from = FixedArray::cast(from_base);
FixedDoubleArray* to = FixedDoubleArray::cast(to_base);
Object* the_hole = from->GetHeap()->the_hole_value();
Object* the_hole = from->GetReadOnlyRoots().the_hole_value();
for (uint32_t from_end = from_start + copy_size;
from_start < from_end; from_start++, to_start++) {
Object* hole_or_object = from->get(from_start);
@ -888,7 +888,8 @@ class ElementsAccessorBase : public InternalElementsAccessor {
Handle<FixedArrayBase> from_elements(object->elements(),
object->GetIsolate());
if (object->elements() == object->GetHeap()->empty_fixed_array() ||
if (object->elements() ==
object->GetReadOnlyRoots().empty_fixed_array() ||
IsDoubleElementsKind(from_kind) == IsDoubleElementsKind(to_kind)) {
// No change is needed to the elements() buffer, the transition
// only requires a map change.
@ -3800,7 +3801,8 @@ class SloppyArgumentsElementsAccessor
// SloppyDeleteImpl allocates a new dictionary elements store. For making
// heap verification happy we postpone clearing out the mapped entry.
if (entry < length) {
elements->set_mapped_entry(entry, obj->GetHeap()->the_hole_value());
elements->set_mapped_entry(entry,
obj->GetReadOnlyRoots().the_hole_value());
}
}

View File

@ -24,6 +24,7 @@
#include "src/objects.h"
#include "src/objects/fixed-array.h"
#include "src/objects/string-table.h"
#include "src/roots.h"
#include "src/visitors.h"
namespace v8 {
@ -49,266 +50,6 @@ class JSArrayBuffer;
using v8::MemoryPressureLevel;
// Defines all the roots in Heap.
#define STRONG_ROOT_LIST(V) \
/* Cluster the most popular ones in a few cache lines here at the top. */ \
/* The first 32 entries are most often used in the startup snapshot and */ \
/* can use a shorter representation in the serialization format. */ \
V(Map, free_space_map, FreeSpaceMap) \
V(Map, one_pointer_filler_map, OnePointerFillerMap) \
V(Map, two_pointer_filler_map, TwoPointerFillerMap) \
V(Oddball, uninitialized_value, UninitializedValue) \
V(Oddball, undefined_value, UndefinedValue) \
V(Oddball, the_hole_value, TheHoleValue) \
V(Oddball, null_value, NullValue) \
V(Oddball, true_value, TrueValue) \
V(Oddball, false_value, FalseValue) \
V(String, empty_string, empty_string) \
V(Map, meta_map, MetaMap) \
V(Map, byte_array_map, ByteArrayMap) \
V(Map, fixed_array_map, FixedArrayMap) \
V(Map, fixed_cow_array_map, FixedCOWArrayMap) \
V(Map, hash_table_map, HashTableMap) \
V(Map, symbol_map, SymbolMap) \
V(Map, one_byte_string_map, OneByteStringMap) \
V(Map, one_byte_internalized_string_map, OneByteInternalizedStringMap) \
V(Map, scope_info_map, ScopeInfoMap) \
V(Map, shared_function_info_map, SharedFunctionInfoMap) \
V(Map, code_map, CodeMap) \
V(Map, function_context_map, FunctionContextMap) \
V(Map, cell_map, CellMap) \
V(Map, weak_cell_map, WeakCellMap) \
V(Map, global_property_cell_map, GlobalPropertyCellMap) \
V(Map, foreign_map, ForeignMap) \
V(Map, heap_number_map, HeapNumberMap) \
V(Map, transition_array_map, TransitionArrayMap) \
V(Map, feedback_vector_map, FeedbackVectorMap) \
V(ScopeInfo, empty_scope_info, EmptyScopeInfo) \
V(FixedArray, empty_fixed_array, EmptyFixedArray) \
V(DescriptorArray, empty_descriptor_array, EmptyDescriptorArray) \
/* Entries beyond the first 32 */ \
/* The roots above this line should be boring from a GC point of view. */ \
/* This means they are never in new space and never on a page that is */ \
/* being compacted.*/ \
/* Oddballs */ \
V(Oddball, arguments_marker, ArgumentsMarker) \
V(Oddball, exception, Exception) \
V(Oddball, termination_exception, TerminationException) \
V(Oddball, optimized_out, OptimizedOut) \
V(Oddball, stale_register, StaleRegister) \
/* Context maps */ \
V(Map, native_context_map, NativeContextMap) \
V(Map, module_context_map, ModuleContextMap) \
V(Map, eval_context_map, EvalContextMap) \
V(Map, script_context_map, ScriptContextMap) \
V(Map, block_context_map, BlockContextMap) \
V(Map, catch_context_map, CatchContextMap) \
V(Map, with_context_map, WithContextMap) \
V(Map, debug_evaluate_context_map, DebugEvaluateContextMap) \
V(Map, script_context_table_map, ScriptContextTableMap) \
/* Maps */ \
V(Map, feedback_metadata_map, FeedbackMetadataArrayMap) \
V(Map, array_list_map, ArrayListMap) \
V(Map, bigint_map, BigIntMap) \
V(Map, boilerplate_description_map, BoilerplateDescriptionMap) \
V(Map, bytecode_array_map, BytecodeArrayMap) \
V(Map, code_data_container_map, CodeDataContainerMap) \
V(Map, descriptor_array_map, DescriptorArrayMap) \
V(Map, external_map, ExternalMap) \
V(Map, fixed_double_array_map, FixedDoubleArrayMap) \
V(Map, global_dictionary_map, GlobalDictionaryMap) \
V(Map, many_closures_cell_map, ManyClosuresCellMap) \
V(Map, message_object_map, JSMessageObjectMap) \
V(Map, module_info_map, ModuleInfoMap) \
V(Map, mutable_heap_number_map, MutableHeapNumberMap) \
V(Map, name_dictionary_map, NameDictionaryMap) \
V(Map, no_closures_cell_map, NoClosuresCellMap) \
V(Map, number_dictionary_map, NumberDictionaryMap) \
V(Map, one_closure_cell_map, OneClosureCellMap) \
V(Map, ordered_hash_map_map, OrderedHashMapMap) \
V(Map, ordered_hash_set_map, OrderedHashSetMap) \
V(Map, property_array_map, PropertyArrayMap) \
V(Map, side_effect_call_handler_info_map, SideEffectCallHandlerInfoMap) \
V(Map, side_effect_free_call_handler_info_map, \
SideEffectFreeCallHandlerInfoMap) \
V(Map, next_call_side_effect_free_call_handler_info_map, \
NextCallSideEffectFreeCallHandlerInfoMap) \
V(Map, simple_number_dictionary_map, SimpleNumberDictionaryMap) \
V(Map, sloppy_arguments_elements_map, SloppyArgumentsElementsMap) \
V(Map, small_ordered_hash_map_map, SmallOrderedHashMapMap) \
V(Map, small_ordered_hash_set_map, SmallOrderedHashSetMap) \
V(Map, string_table_map, StringTableMap) \
V(Map, weak_fixed_array_map, WeakFixedArrayMap) \
V(Map, weak_array_list_map, WeakArrayListMap) \
V(Map, ephemeron_hash_table_map, EphemeronHashTableMap) \
/* String maps */ \
V(Map, native_source_string_map, NativeSourceStringMap) \
V(Map, string_map, StringMap) \
V(Map, cons_one_byte_string_map, ConsOneByteStringMap) \
V(Map, cons_string_map, ConsStringMap) \
V(Map, thin_one_byte_string_map, ThinOneByteStringMap) \
V(Map, thin_string_map, ThinStringMap) \
V(Map, sliced_string_map, SlicedStringMap) \
V(Map, sliced_one_byte_string_map, SlicedOneByteStringMap) \
V(Map, external_string_map, ExternalStringMap) \
V(Map, external_string_with_one_byte_data_map, \
ExternalStringWithOneByteDataMap) \
V(Map, external_one_byte_string_map, ExternalOneByteStringMap) \
V(Map, short_external_string_map, ShortExternalStringMap) \
V(Map, short_external_string_with_one_byte_data_map, \
ShortExternalStringWithOneByteDataMap) \
V(Map, internalized_string_map, InternalizedStringMap) \
V(Map, external_internalized_string_map, ExternalInternalizedStringMap) \
V(Map, external_internalized_string_with_one_byte_data_map, \
ExternalInternalizedStringWithOneByteDataMap) \
V(Map, external_one_byte_internalized_string_map, \
ExternalOneByteInternalizedStringMap) \
V(Map, short_external_internalized_string_map, \
ShortExternalInternalizedStringMap) \
V(Map, short_external_internalized_string_with_one_byte_data_map, \
ShortExternalInternalizedStringWithOneByteDataMap) \
V(Map, short_external_one_byte_internalized_string_map, \
ShortExternalOneByteInternalizedStringMap) \
V(Map, short_external_one_byte_string_map, ShortExternalOneByteStringMap) \
/* Array element maps */ \
V(Map, fixed_uint8_array_map, FixedUint8ArrayMap) \
V(Map, fixed_int8_array_map, FixedInt8ArrayMap) \
V(Map, fixed_uint16_array_map, FixedUint16ArrayMap) \
V(Map, fixed_int16_array_map, FixedInt16ArrayMap) \
V(Map, fixed_uint32_array_map, FixedUint32ArrayMap) \
V(Map, fixed_int32_array_map, FixedInt32ArrayMap) \
V(Map, fixed_float32_array_map, FixedFloat32ArrayMap) \
V(Map, fixed_float64_array_map, FixedFloat64ArrayMap) \
V(Map, fixed_uint8_clamped_array_map, FixedUint8ClampedArrayMap) \
V(Map, fixed_biguint64_array_map, FixedBigUint64ArrayMap) \
V(Map, fixed_bigint64_array_map, FixedBigInt64ArrayMap) \
/* Oddball maps */ \
V(Map, undefined_map, UndefinedMap) \
V(Map, the_hole_map, TheHoleMap) \
V(Map, null_map, NullMap) \
V(Map, boolean_map, BooleanMap) \
V(Map, uninitialized_map, UninitializedMap) \
V(Map, arguments_marker_map, ArgumentsMarkerMap) \
V(Map, exception_map, ExceptionMap) \
V(Map, termination_exception_map, TerminationExceptionMap) \
V(Map, optimized_out_map, OptimizedOutMap) \
V(Map, stale_register_map, StaleRegisterMap) \
V(Map, self_reference_marker_map, SelfReferenceMarkerMap) \
/* Canonical empty values */ \
V(EnumCache, empty_enum_cache, EmptyEnumCache) \
V(PropertyArray, empty_property_array, EmptyPropertyArray) \
V(ByteArray, empty_byte_array, EmptyByteArray) \
V(BoilerplateDescription, empty_boilerplate_description, \
EmptyBoilerplateDescription) \
V(FixedTypedArrayBase, empty_fixed_uint8_array, EmptyFixedUint8Array) \
V(FixedTypedArrayBase, empty_fixed_int8_array, EmptyFixedInt8Array) \
V(FixedTypedArrayBase, empty_fixed_uint16_array, EmptyFixedUint16Array) \
V(FixedTypedArrayBase, empty_fixed_int16_array, EmptyFixedInt16Array) \
V(FixedTypedArrayBase, empty_fixed_uint32_array, EmptyFixedUint32Array) \
V(FixedTypedArrayBase, empty_fixed_int32_array, EmptyFixedInt32Array) \
V(FixedTypedArrayBase, empty_fixed_float32_array, EmptyFixedFloat32Array) \
V(FixedTypedArrayBase, empty_fixed_float64_array, EmptyFixedFloat64Array) \
V(FixedTypedArrayBase, empty_fixed_uint8_clamped_array, \
EmptyFixedUint8ClampedArray) \
V(FixedTypedArrayBase, empty_fixed_biguint64_array, \
EmptyFixedBigUint64Array) \
V(FixedTypedArrayBase, empty_fixed_bigint64_array, EmptyFixedBigInt64Array) \
V(Script, empty_script, EmptyScript) \
V(FeedbackCell, many_closures_cell, ManyClosuresCell) \
V(FixedArray, empty_sloppy_arguments_elements, EmptySloppyArgumentsElements) \
V(NumberDictionary, empty_slow_element_dictionary, \
EmptySlowElementDictionary) \
V(FixedArray, empty_ordered_hash_map, EmptyOrderedHashMap) \
V(FixedArray, empty_ordered_hash_set, EmptyOrderedHashSet) \
V(FeedbackMetadata, empty_feedback_metadata, EmptyFeedbackMetadata) \
V(PropertyCell, empty_property_cell, EmptyPropertyCell) \
V(WeakCell, empty_weak_cell, EmptyWeakCell) \
V(Cell, invalid_prototype_validity_cell, InvalidPrototypeValidityCell) \
V(InterceptorInfo, noop_interceptor_info, NoOpInterceptorInfo) \
V(WeakFixedArray, empty_weak_fixed_array, EmptyWeakFixedArray) \
V(WeakArrayList, empty_weak_array_list, EmptyWeakArrayList) \
/* Protectors */ \
V(Cell, array_constructor_protector, ArrayConstructorProtector) \
V(PropertyCell, no_elements_protector, NoElementsProtector) \
V(Cell, is_concat_spreadable_protector, IsConcatSpreadableProtector) \
V(PropertyCell, array_species_protector, ArraySpeciesProtector) \
V(PropertyCell, typed_array_species_protector, TypedArraySpeciesProtector) \
V(PropertyCell, promise_species_protector, PromiseSpeciesProtector) \
V(Cell, string_length_protector, StringLengthProtector) \
V(PropertyCell, array_iterator_protector, ArrayIteratorProtector) \
V(PropertyCell, array_buffer_neutering_protector, \
ArrayBufferNeuteringProtector) \
V(PropertyCell, promise_hook_protector, PromiseHookProtector) \
V(Cell, promise_resolve_protector, PromiseResolveProtector) \
V(PropertyCell, promise_then_protector, PromiseThenProtector) \
/* Special numbers */ \
V(HeapNumber, nan_value, NanValue) \
V(HeapNumber, hole_nan_value, HoleNanValue) \
V(HeapNumber, infinity_value, InfinityValue) \
V(HeapNumber, minus_zero_value, MinusZeroValue) \
V(HeapNumber, minus_infinity_value, MinusInfinityValue) \
/* Marker for self-references during code-generation */ \
V(HeapObject, self_reference_marker, SelfReferenceMarker) \
/* Caches */ \
V(FixedArray, number_string_cache, NumberStringCache) \
V(FixedArray, single_character_string_cache, SingleCharacterStringCache) \
V(FixedArray, string_split_cache, StringSplitCache) \
V(FixedArray, regexp_multiple_cache, RegExpMultipleCache) \
/* Lists and dictionaries */ \
V(NameDictionary, empty_property_dictionary, EmptyPropertyDictionary) \
V(NameDictionary, public_symbol_table, PublicSymbolTable) \
V(NameDictionary, api_symbol_table, ApiSymbolTable) \
V(NameDictionary, api_private_symbol_table, ApiPrivateSymbolTable) \
V(Object, script_list, ScriptList) \
V(SimpleNumberDictionary, code_stubs, CodeStubs) \
V(FixedArray, materialized_objects, MaterializedObjects) \
V(FixedArray, microtask_queue, MicrotaskQueue) \
V(FixedArray, detached_contexts, DetachedContexts) \
V(HeapObject, retaining_path_targets, RetainingPathTargets) \
V(WeakArrayList, retained_maps, RetainedMaps) \
/* Indirection lists for isolate-independent builtins */ \
V(FixedArray, builtins_constants_table, BuiltinsConstantsTable) \
/* Feedback vectors that we need for code coverage or type profile */ \
V(Object, feedback_vectors_for_profiling_tools, \
FeedbackVectorsForProfilingTools) \
V(Object, weak_stack_trace_list, WeakStackTraceList) \
V(Object, noscript_shared_function_infos, NoScriptSharedFunctionInfos) \
V(FixedArray, serialized_objects, SerializedObjects) \
V(FixedArray, serialized_global_proxy_sizes, SerializedGlobalProxySizes) \
V(TemplateList, message_listeners, MessageListeners) \
/* DeserializeLazy handlers for lazy bytecode deserialization */ \
V(Object, deserialize_lazy_handler, DeserializeLazyHandler) \
V(Object, deserialize_lazy_handler_wide, DeserializeLazyHandlerWide) \
V(Object, deserialize_lazy_handler_extra_wide, \
DeserializeLazyHandlerExtraWide) \
/* JS Entries */ \
V(Code, js_entry_code, JsEntryCode) \
V(Code, js_construct_entry_code, JsConstructEntryCode) \
V(Code, js_run_microtasks_entry_code, JsRunMicrotasksEntryCode)
// Entries in this list are limited to Smis and are not visited during GC.
#define SMI_ROOT_LIST(V) \
V(Smi, stack_limit, StackLimit) \
V(Smi, real_stack_limit, RealStackLimit) \
V(Smi, last_script_id, LastScriptId) \
V(Smi, last_debugging_id, LastDebuggingId) \
V(Smi, hash_seed, HashSeed) \
/* To distinguish the function templates, so that we can find them in the */ \
/* function cache of the native context. */ \
V(Smi, next_template_serial_number, NextTemplateSerialNumber) \
V(Smi, arguments_adaptor_deopt_pc_offset, ArgumentsAdaptorDeoptPCOffset) \
V(Smi, construct_stub_create_deopt_pc_offset, \
ConstructStubCreateDeoptPCOffset) \
V(Smi, construct_stub_invoke_deopt_pc_offset, \
ConstructStubInvokeDeoptPCOffset) \
V(Smi, interpreter_entry_return_pc_offset, InterpreterEntryReturnPCOffset)
#define ROOT_LIST(V) \
STRONG_ROOT_LIST(V) \
SMI_ROOT_LIST(V) \
V(StringTable, string_table, StringTable)
// Heap roots that are known to be immortal immovable, for which we can safely
// skip write barriers. This list is not complete and has omissions.
#define IMMORTAL_IMMOVABLE_ROOT_LIST(V) \

View File

@ -428,7 +428,7 @@ bool JSObject::ElementsAreSafeToExamine() {
// If a GC was caused while constructing this object, the elements
// pointer may point to a one pointer filler map.
return reinterpret_cast<Map*>(elements()) !=
GetHeap()->one_pointer_filler_map();
GetReadOnlyRoots().one_pointer_filler_map();
}
namespace {
@ -535,10 +535,10 @@ void JSObject::JSObjectVerify(Isolate* isolate) {
// pointer may point to a one pointer filler map.
if (ElementsAreSafeToExamine()) {
CHECK_EQ((map()->has_fast_smi_or_object_elements() ||
(elements() == GetHeap()->empty_fixed_array()) ||
(elements() == GetReadOnlyRoots().empty_fixed_array()) ||
HasFastStringWrapperElements()),
(elements()->map() == GetHeap()->fixed_array_map() ||
elements()->map() == GetHeap()->fixed_cow_array_map()));
(elements()->map() == GetReadOnlyRoots().fixed_array_map() ||
elements()->map() == GetReadOnlyRoots().fixed_cow_array_map()));
CHECK_EQ(map()->has_fast_object_elements(), HasObjectElements());
VerifyJSObjectElements(isolate, this);
}

View File

@ -41,6 +41,7 @@
#include "src/property-details.h"
#include "src/property.h"
#include "src/prototype.h"
#include "src/roots-inl.h"
#include "src/transitions-inl.h"
#include "src/v8memory.h"
@ -269,7 +270,7 @@ bool HeapObject::IsCallable() const { return map()->is_callable(); }
bool HeapObject::IsConstructor() const { return map()->is_constructor(); }
bool HeapObject::IsModuleInfo() const {
return map() == GetHeap()->module_info_map();
return map() == GetReadOnlyRoots().module_info_map();
}
bool HeapObject::IsTemplateInfo() const {
@ -395,8 +396,8 @@ bool HeapObject::IsEnumCache() const { return IsTuple2(); }
bool HeapObject::IsFrameArray() const { return IsFixedArrayExact(); }
bool HeapObject::IsArrayList() const {
return map() == GetHeap()->array_list_map() ||
this == GetHeap()->empty_fixed_array();
return map() == GetReadOnlyRoots().array_list_map() ||
this == GetReadOnlyRoots().empty_fixed_array();
}
bool HeapObject::IsRegExpMatchInfo() const { return IsFixedArrayExact(); }
@ -987,6 +988,12 @@ void HeapObject::VerifySmiField(int offset) {
}
#endif
ReadOnlyRoots HeapObject::GetReadOnlyRoots() const {
// TODO(v8:7464): When RO_SPACE is embedded, this will access a global
// variable instead.
return ReadOnlyRoots(MemoryChunk::FromHeapObject(this)->heap());
}
Heap* HeapObject::GetHeap() const {
Heap* heap = MemoryChunk::FromAddress(
reinterpret_cast<Address>(const_cast<HeapObject*>(this)))
@ -1147,8 +1154,9 @@ void AllocationSite::Initialize() {
set_nested_site(Smi::kZero);
set_pretenure_data(0);
set_pretenure_create_count(0);
set_dependent_code(DependentCode::cast(GetHeap()->empty_fixed_array()),
SKIP_WRITE_BARRIER);
set_dependent_code(
DependentCode::cast(GetReadOnlyRoots().empty_fixed_array()),
SKIP_WRITE_BARRIER);
}
bool AllocationSite::IsZombie() const {
@ -1305,7 +1313,7 @@ void JSObject::EnsureCanContainElements(Handle<JSObject> object,
DCHECK(mode != ALLOW_COPIED_DOUBLE_ELEMENTS);
bool is_holey = IsHoleyElementsKind(current_kind);
if (current_kind == HOLEY_ELEMENTS) return;
Object* the_hole = object->GetHeap()->the_hole_value();
Object* the_hole = object->GetReadOnlyRoots().the_hole_value();
for (uint32_t i = 0; i < count; ++i) {
Object* current = *objects++;
if (current == the_hole) {
@ -1339,10 +1347,10 @@ void JSObject::EnsureCanContainElements(Handle<JSObject> object,
Handle<FixedArrayBase> elements,
uint32_t length,
EnsureElementsMode mode) {
Heap* heap = object->GetHeap();
if (elements->map() != heap->fixed_double_array_map()) {
DCHECK(elements->map() == heap->fixed_array_map() ||
elements->map() == heap->fixed_cow_array_map());
ReadOnlyRoots roots = object->GetReadOnlyRoots();
if (elements->map() != roots.fixed_double_array_map()) {
DCHECK(elements->map() == roots.fixed_array_map() ||
elements->map() == roots.fixed_cow_array_map());
if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) {
mode = DONT_ALLOW_DOUBLE_ELEMENTS;
}
@ -1374,11 +1382,11 @@ void JSObject::SetMapAndElements(Handle<JSObject> object,
Handle<FixedArrayBase> value) {
JSObject::MigrateToMap(object, new_map);
DCHECK((object->map()->has_fast_smi_or_object_elements() ||
(*value == object->GetHeap()->empty_fixed_array()) ||
(*value == object->GetReadOnlyRoots().empty_fixed_array()) ||
object->map()->has_fast_string_wrapper_elements()) ==
(value->map() == object->GetHeap()->fixed_array_map() ||
value->map() == object->GetHeap()->fixed_cow_array_map()));
DCHECK((*value == object->GetHeap()->empty_fixed_array()) ||
(value->map() == object->GetReadOnlyRoots().fixed_array_map() ||
value->map() == object->GetReadOnlyRoots().fixed_cow_array_map()));
DCHECK((*value == object->GetReadOnlyRoots().empty_fixed_array()) ||
(object->map()->has_fast_double_elements() ==
value->IsFixedDoubleArray()));
object->set_elements(*value);
@ -1458,7 +1466,7 @@ void WeakCell::clear() {
// Either the garbage collector is clearing the cell or we are simply
// initializing the root empty weak cell.
DCHECK(Heap::FromWritableHeapObject(this)->gc_state() == Heap::MARK_COMPACT ||
this == Heap::FromWritableHeapObject(this)->empty_weak_cell());
this == GetReadOnlyRoots().empty_weak_cell());
WRITE_FIELD(this, kValueOffset, Smi::kZero);
}
@ -1696,7 +1704,7 @@ void JSObject::InitializeBody(Map* map, int start_offset,
}
void Struct::InitializeBody(int object_size) {
Object* value = GetHeap()->undefined_value();
Object* value = GetReadOnlyRoots().undefined_value();
for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
WRITE_FIELD(this, offset, value);
}
@ -2753,11 +2761,11 @@ ElementsKind JSObject::GetElementsKind() {
if (ElementsAreSafeToExamine()) {
Map* map = fixed_array->map();
if (IsSmiOrObjectElementsKind(kind)) {
DCHECK(map == GetHeap()->fixed_array_map() ||
map == GetHeap()->fixed_cow_array_map());
DCHECK(map == GetReadOnlyRoots().fixed_array_map() ||
map == GetReadOnlyRoots().fixed_cow_array_map());
} else if (IsDoubleElementsKind(kind)) {
DCHECK(fixed_array->IsFixedDoubleArray() ||
fixed_array == GetHeap()->empty_fixed_array());
fixed_array == GetReadOnlyRoots().empty_fixed_array());
} else if (kind == DICTIONARY_ELEMENTS) {
DCHECK(fixed_array->IsFixedArray());
DCHECK(fixed_array->IsDictionary());
@ -2971,13 +2979,14 @@ MaybeHandle<Object> Object::GetPropertyOrElement(Handle<Object> receiver,
void JSReceiver::initialize_properties() {
DCHECK(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
DCHECK(!GetHeap()->InNewSpace(GetReadOnlyRoots().empty_fixed_array()));
DCHECK(!GetHeap()->InNewSpace(GetHeap()->empty_property_dictionary()));
if (map()->is_dictionary_map()) {
WRITE_FIELD(this, kPropertiesOrHashOffset,
GetHeap()->empty_property_dictionary());
} else {
WRITE_FIELD(this, kPropertiesOrHashOffset, GetHeap()->empty_fixed_array());
WRITE_FIELD(this, kPropertiesOrHashOffset,
GetReadOnlyRoots().empty_fixed_array());
}
}
@ -3006,8 +3015,8 @@ PropertyArray* JSReceiver::property_array() const {
DCHECK(HasFastProperties());
Object* prop = raw_properties_or_hash();
if (prop->IsSmi() || prop == GetHeap()->empty_fixed_array()) {
return GetHeap()->empty_property_array();
if (prop->IsSmi() || prop == GetReadOnlyRoots().empty_fixed_array()) {
return GetReadOnlyRoots().empty_property_array();
}
return PropertyArray::cast(prop);
@ -3139,7 +3148,7 @@ bool AccessorPair::IsJSAccessor(Object* obj) {
template <typename Derived, typename Shape>
void Dictionary<Derived, Shape>::ClearEntry(int entry) {
Object* the_hole = Heap::FromWritableHeapObject(this)->the_hole_value();
Object* the_hole = this->GetReadOnlyRoots().the_hole_value();
PropertyDetails details = PropertyDetails::Empty();
Derived::cast(this)->SetEntry(entry, the_hole, the_hole, details);
}

View File

@ -3595,49 +3595,50 @@ bool HeapObject::IsValidSlot(Map* map, int offset) {
}
String* JSReceiver::class_name() {
if (IsFunction()) return GetHeap()->Function_string();
if (IsJSArgumentsObject()) return GetHeap()->Arguments_string();
if (IsJSArray()) return GetHeap()->Array_string();
ReadOnlyRoots roots = GetReadOnlyRoots();
if (IsFunction()) return roots.Function_string();
if (IsJSArgumentsObject()) return roots.Arguments_string();
if (IsJSArray()) return roots.Array_string();
if (IsJSArrayBuffer()) {
if (JSArrayBuffer::cast(this)->is_shared()) {
return GetHeap()->SharedArrayBuffer_string();
return roots.SharedArrayBuffer_string();
}
return GetHeap()->ArrayBuffer_string();
return roots.ArrayBuffer_string();
}
if (IsJSArrayIterator()) return GetHeap()->ArrayIterator_string();
if (IsJSDate()) return GetHeap()->Date_string();
if (IsJSError()) return GetHeap()->Error_string();
if (IsJSGeneratorObject()) return GetHeap()->Generator_string();
if (IsJSMap()) return GetHeap()->Map_string();
if (IsJSMapIterator()) return GetHeap()->MapIterator_string();
if (IsJSArrayIterator()) return roots.ArrayIterator_string();
if (IsJSDate()) return roots.Date_string();
if (IsJSError()) return roots.Error_string();
if (IsJSGeneratorObject()) return roots.Generator_string();
if (IsJSMap()) return roots.Map_string();
if (IsJSMapIterator()) return roots.MapIterator_string();
if (IsJSProxy()) {
return map()->is_callable() ? GetHeap()->Function_string()
: GetHeap()->Object_string();
return map()->is_callable() ? roots.Function_string()
: roots.Object_string();
}
if (IsJSRegExp()) return GetHeap()->RegExp_string();
if (IsJSSet()) return GetHeap()->Set_string();
if (IsJSSetIterator()) return GetHeap()->SetIterator_string();
if (IsJSRegExp()) return roots.RegExp_string();
if (IsJSSet()) return roots.Set_string();
if (IsJSSetIterator()) return roots.SetIterator_string();
if (IsJSTypedArray()) {
#define SWITCH_KIND(Type, type, TYPE, ctype, size) \
if (map()->elements_kind() == TYPE##_ELEMENTS) { \
return GetHeap()->Type##Array_string(); \
return roots.Type##Array_string(); \
}
TYPED_ARRAYS(SWITCH_KIND)
#undef SWITCH_KIND
}
if (IsJSValue()) {
Object* value = JSValue::cast(this)->value();
if (value->IsBoolean()) return GetHeap()->Boolean_string();
if (value->IsString()) return GetHeap()->String_string();
if (value->IsNumber()) return GetHeap()->Number_string();
if (value->IsBigInt()) return GetHeap()->BigInt_string();
if (value->IsSymbol()) return GetHeap()->Symbol_string();
if (value->IsScript()) return GetHeap()->Script_string();
if (value->IsBoolean()) return roots.Boolean_string();
if (value->IsString()) return roots.String_string();
if (value->IsNumber()) return roots.Number_string();
if (value->IsBigInt()) return roots.BigInt_string();
if (value->IsSymbol()) return roots.Symbol_string();
if (value->IsScript()) return roots.Script_string();
UNREACHABLE();
}
if (IsJSWeakMap()) return GetHeap()->WeakMap_string();
if (IsJSWeakSet()) return GetHeap()->WeakSet_string();
if (IsJSGlobalProxy()) return GetHeap()->global_string();
if (IsJSWeakMap()) return roots.WeakMap_string();
if (IsJSWeakSet()) return roots.WeakSet_string();
if (IsJSGlobalProxy()) return roots.global_string();
Object* maybe_constructor = map()->GetConstructor();
if (maybe_constructor->IsJSFunction()) {
@ -3652,7 +3653,7 @@ String* JSReceiver::class_name() {
if (info->class_name()->IsString()) return String::cast(info->class_name());
}
return GetHeap()->Object_string();
return roots.Object_string();
}
bool HeapObject::CanBeRehashed() const {
@ -6643,7 +6644,7 @@ void JSReceiver::SetIdentityHash(int hash) {
void JSReceiver::SetProperties(HeapObject* properties) {
DCHECK_IMPLIES(properties->IsPropertyArray() &&
PropertyArray::cast(properties)->length() == 0,
properties == GetHeap()->empty_property_array());
properties == GetReadOnlyRoots().empty_property_array());
DisallowHeapAllocation no_gc;
Isolate* isolate = GetIsolate();
int hash = GetIdentityHashHelper(isolate, this);
@ -9150,7 +9151,7 @@ Object* JSObject::SlowReverseLookup(Object* value) {
}
}
}
return GetHeap()->undefined_value();
return GetReadOnlyRoots().undefined_value();
} else if (IsJSGlobalObject()) {
return JSGlobalObject::cast(this)->global_dictionary()->SlowReverseLookup(
value);
@ -10444,7 +10445,7 @@ Handle<ArrayList> ArrayList::EnsureSpace(Handle<ArrayList> array, int length) {
const bool empty = (array->length() == 0);
auto ret = EnsureSpaceInFixedArray(array, kFirstIndex + length);
if (empty) {
ret->set_map_no_write_barrier(array->GetHeap()->array_list_map());
ret->set_map_no_write_barrier(array->GetReadOnlyRoots().array_list_map());
Handle<ArrayList>::cast(ret)->SetLength(0);
}
@ -10552,7 +10553,8 @@ Handle<DescriptorArray> DescriptorArray::Allocate(Isolate* isolate,
}
void DescriptorArray::ClearEnumCache() {
set(kEnumCacheIndex, MaybeObject::FromObject(GetHeap()->empty_enum_cache()));
set(kEnumCacheIndex,
MaybeObject::FromObject(GetReadOnlyRoots().empty_enum_cache()));
}
void DescriptorArray::Replace(int index, Descriptor* descriptor) {
@ -15172,7 +15174,7 @@ void DependentCode::DeoptimizeDependentCodeGroup(
void Code::SetMarkedForDeoptimization(const char* reason) {
set_marked_for_deoptimization(true);
if (FLAG_trace_deopt &&
(deoptimization_data() != GetHeap()->empty_fixed_array())) {
(deoptimization_data() != GetReadOnlyRoots().empty_fixed_array())) {
DeoptimizationData* deopt_data =
DeoptimizationData::cast(deoptimization_data());
CodeTracer::Scope scope(GetHeap()->isolate()->GetCodeTracer());
@ -15755,7 +15757,7 @@ void JSObject::TransitionElementsKind(Handle<JSObject> object,
DCHECK_NE(TERMINAL_FAST_ELEMENTS_KIND, from_kind);
UpdateAllocationSite(object, to_kind);
if (object->elements() == object->GetHeap()->empty_fixed_array() ||
if (object->elements() == object->GetReadOnlyRoots().empty_fixed_array() ||
IsDoubleElementsKind(from_kind) == IsDoubleElementsKind(to_kind)) {
// No change is needed to the elements() buffer, the transition
// only requires a map change.
@ -15793,7 +15795,7 @@ bool JSArray::HasReadOnlyLength(Handle<JSArray> array) {
// configurable, it's guaranteed to be the first in the descriptor array.
if (!map->is_dictionary_map()) {
DCHECK(map->instance_descriptors()->GetKey(0) ==
array->GetHeap()->length_string());
array->GetReadOnlyRoots().length_string());
return map->instance_descriptors()->GetDetails(0).IsReadOnly();
}
@ -15931,7 +15933,7 @@ int FixedArrayBase::GetMaxLengthForNewSpaceAllocation(ElementsKind kind) {
}
bool FixedArrayBase::IsCowArray() const {
return map() == GetHeap()->fixed_cow_array_map();
return map() == GetReadOnlyRoots().fixed_cow_array_map();
}
bool JSObject::WasConstructedFromApiFunction() {
@ -17633,7 +17635,7 @@ Handle<CompilationCacheTable> CompilationCacheTable::PutRegExp(
void CompilationCacheTable::Age() {
DisallowHeapAllocation no_allocation;
Object* the_hole_value = GetHeap()->the_hole_value();
Object* the_hole_value = GetReadOnlyRoots().the_hole_value();
for (int entry = 0, size = Capacity(); entry < size; entry++) {
int entry_index = EntryToIndex(entry);
int value_index = entry_index + 1;
@ -17663,7 +17665,7 @@ void CompilationCacheTable::Age() {
void CompilationCacheTable::Remove(Object* value) {
DisallowHeapAllocation no_allocation;
Object* the_hole_value = GetHeap()->the_hole_value();
Object* the_hole_value = GetReadOnlyRoots().the_hole_value();
for (int entry = 0, size = Capacity(); entry < size; entry++) {
int entry_index = EntryToIndex(entry);
int value_index = entry_index + 1;

View File

@ -21,6 +21,7 @@
#include "src/flags.h"
#include "src/messages.h"
#include "src/property-details.h"
#include "src/roots.h"
#include "src/utils.h"
#if V8_TARGET_ARCH_ARM
@ -1836,6 +1837,13 @@ class HeapObject: public Object {
inline MapWord map_word() const;
inline void set_map_word(MapWord map_word);
// TODO(v8:7464): Once RO_SPACE is shared between isolates, this method can be
// removed as ReadOnlyRoots will be accessible from a global variable. For now
// this method exists to help remove GetIsolate/GetHeap from HeapObject, in a
// way that doesn't require passing Isolate/Heap down huge call chains or to
// places where it might not be safe to access it.
inline ReadOnlyRoots GetReadOnlyRoots() const;
// The Heap the object was allocated in. Used also to access Isolate.
#ifdef DEPRECATE_GET_ISOLATE
[[deprecated("Pass Heap explicitly or use a NeverReadOnlyHeapObject")]]

View File

@ -44,7 +44,7 @@ uint32_t CompilationCacheShape::HashForObject(Isolate* isolate,
if (object->IsNumber()) return static_cast<uint32_t>(object->Number());
FixedArray* val = FixedArray::cast(object);
if (val->map() == isolate->heap()->fixed_cow_array_map()) {
if (val->map() == val->GetReadOnlyRoots().fixed_cow_array_map()) {
DCHECK_EQ(4, val->length());
SharedFunctionInfo* shared = SharedFunctionInfo::cast(val->get(0));
String* source = String::cast(val->get(1));

View File

@ -46,7 +46,7 @@ Object** FixedArray::GetFirstElementAddress() {
}
bool FixedArray::ContainsOnlySmisOrHoles() {
Object* the_hole = GetHeap()->the_hole_value();
Object* the_hole = GetReadOnlyRoots().the_hole_value();
Object** current = GetFirstElementAddress();
for (int i = 0; i < length(); ++i) {
Object* candidate = *current++;
@ -83,7 +83,7 @@ bool FixedArray::is_the_hole(Isolate* isolate, int index) {
}
void FixedArray::set(int index, Smi* value) {
DCHECK_NE(map(), GetHeap()->fixed_cow_array_map());
DCHECK_NE(map(), GetReadOnlyRoots().fixed_cow_array_map());
DCHECK_LT(index, this->length());
DCHECK(reinterpret_cast<Object*>(value)->IsSmi());
int offset = kHeaderSize + index * kPointerSize;
@ -91,7 +91,7 @@ void FixedArray::set(int index, Smi* value) {
}
void FixedArray::set(int index, Object* value) {
DCHECK_NE(GetHeap()->fixed_cow_array_map(), map());
DCHECK_NE(GetReadOnlyRoots().fixed_cow_array_map(), map());
DCHECK(IsFixedArray());
DCHECK_GE(index, 0);
DCHECK_LT(index, this->length());
@ -101,7 +101,7 @@ void FixedArray::set(int index, Object* value) {
}
void FixedArray::set(int index, Object* value, WriteBarrierMode mode) {
DCHECK_NE(map(), GetHeap()->fixed_cow_array_map());
DCHECK_NE(map(), GetReadOnlyRoots().fixed_cow_array_map());
DCHECK_GE(index, 0);
DCHECK_LT(index, this->length());
int offset = kHeaderSize + index * kPointerSize;
@ -111,7 +111,7 @@ void FixedArray::set(int index, Object* value, WriteBarrierMode mode) {
void FixedArray::NoWriteBarrierSet(FixedArray* array, int index,
Object* value) {
DCHECK_NE(array->map(), array->GetHeap()->fixed_cow_array_map());
DCHECK_NE(array->map(), array->GetReadOnlyRoots().fixed_cow_array_map());
DCHECK_GE(index, 0);
DCHECK_LT(index, array->length());
DCHECK(!array->GetHeap()->InNewSpace(value));
@ -155,16 +155,16 @@ Object** FixedArray::RawFieldOfElementAt(int index) {
}
double FixedDoubleArray::get_scalar(int index) {
DCHECK(map() != GetHeap()->fixed_cow_array_map() &&
map() != GetHeap()->fixed_array_map());
DCHECK(map() != GetReadOnlyRoots().fixed_cow_array_map() &&
map() != GetReadOnlyRoots().fixed_array_map());
DCHECK(index >= 0 && index < this->length());
DCHECK(!is_the_hole(index));
return READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
}
uint64_t FixedDoubleArray::get_representation(int index) {
DCHECK(map() != GetHeap()->fixed_cow_array_map() &&
map() != GetHeap()->fixed_array_map());
DCHECK(map() != GetReadOnlyRoots().fixed_cow_array_map() &&
map() != GetReadOnlyRoots().fixed_array_map());
DCHECK(index >= 0 && index < this->length());
int offset = kHeaderSize + index * kDoubleSize;
return READ_UINT64_FIELD(this, offset);
@ -180,8 +180,8 @@ Handle<Object> FixedDoubleArray::get(FixedDoubleArray* array, int index,
}
void FixedDoubleArray::set(int index, double value) {
DCHECK(map() != GetHeap()->fixed_cow_array_map() &&
map() != GetHeap()->fixed_array_map());
DCHECK(map() != GetReadOnlyRoots().fixed_cow_array_map() &&
map() != GetReadOnlyRoots().fixed_array_map());
int offset = kHeaderSize + index * kDoubleSize;
if (std::isnan(value)) {
WRITE_DOUBLE_FIELD(this, offset, std::numeric_limits<double>::quiet_NaN());
@ -196,8 +196,8 @@ void FixedDoubleArray::set_the_hole(Isolate* isolate, int index) {
}
void FixedDoubleArray::set_the_hole(int index) {
DCHECK(map() != GetHeap()->fixed_cow_array_map() &&
map() != GetHeap()->fixed_array_map());
DCHECK(map() != GetReadOnlyRoots().fixed_cow_array_map() &&
map() != GetReadOnlyRoots().fixed_array_map());
int offset = kHeaderSize + index * kDoubleSize;
WRITE_UINT64_FIELD(this, offset, kHoleNanInt64);
}

View File

@ -47,12 +47,13 @@ void JSArray::SetContent(Handle<JSArray> array,
EnsureCanContainElements(array, storage, storage->length(),
ALLOW_COPIED_DOUBLE_ELEMENTS);
DCHECK((storage->map() == array->GetHeap()->fixed_double_array_map() &&
IsDoubleElementsKind(array->GetElementsKind())) ||
((storage->map() != array->GetHeap()->fixed_double_array_map()) &&
(IsObjectElementsKind(array->GetElementsKind()) ||
(IsSmiElementsKind(array->GetElementsKind()) &&
Handle<FixedArray>::cast(storage)->ContainsOnlySmisOrHoles()))));
DCHECK(
(storage->map() == array->GetReadOnlyRoots().fixed_double_array_map() &&
IsDoubleElementsKind(array->GetElementsKind())) ||
((storage->map() != array->GetReadOnlyRoots().fixed_double_array_map()) &&
(IsObjectElementsKind(array->GetElementsKind()) ||
(IsSmiElementsKind(array->GetElementsKind()) &&
Handle<FixedArray>::cast(storage)->ContainsOnlySmisOrHoles()))));
array->set_elements(*storage);
array->set_length(Smi::FromInt(storage->length()));
}

View File

@ -180,13 +180,13 @@ void Map::SetEnumLength(int length) {
FixedArrayBase* Map::GetInitialElements() const {
FixedArrayBase* result = nullptr;
if (has_fast_elements() || has_fast_string_wrapper_elements()) {
result = GetHeap()->empty_fixed_array();
result = GetReadOnlyRoots().empty_fixed_array();
} else if (has_fast_sloppy_arguments_elements()) {
result = GetHeap()->empty_sloppy_arguments_elements();
result = GetReadOnlyRoots().empty_sloppy_arguments_elements();
} else if (has_fixed_typed_array_elements()) {
result = GetHeap()->EmptyFixedTypedArrayForMap(this);
} else if (has_dictionary_elements()) {
result = GetHeap()->empty_slow_element_dictionary();
result = GetReadOnlyRoots().empty_slow_element_dictionary();
} else {
UNREACHABLE();
}
@ -499,7 +499,9 @@ bool Map::CanTransition() const {
return IsJSObject(instance_type());
}
bool Map::IsBooleanMap() const { return this == GetHeap()->boolean_map(); }
bool Map::IsBooleanMap() const {
return this == GetReadOnlyRoots().boolean_map();
}
bool Map::IsPrimitiveMap() const {
return instance_type() <= LAST_PRIMITIVE_TYPE;
}
@ -639,7 +641,7 @@ Object* Map::GetBackPointer() const {
Map* Map::ElementsTransitionMap() {
DisallowHeapAllocation no_gc;
return TransitionsAccessor(GetIsolate(), this, &no_gc)
.SearchSpecial(GetHeap()->elements_transition_symbol());
.SearchSpecial(GetReadOnlyRoots().elements_transition_symbol());
}
Object* Map::prototype_info() const {

View File

@ -591,7 +591,7 @@ String* ScopeInfo::FunctionDebugName() const {
name = InferredFunctionName();
if (name->IsString()) return String::cast(name);
}
return GetHeap()->empty_string();
return GetReadOnlyRoots().empty_string();
}
int ScopeInfo::StartPosition() const {
@ -674,7 +674,7 @@ bool ScopeInfo::VariableIsSynthetic(String* name) {
// with user declarations, the current temporaries like .generator_object and
// .result start with a dot, so we can use that as a flag. It's a hack!
return name->length() == 0 || name->Get(0) == '.' ||
name->Equals(name->GetHeap()->this_string());
name->Equals(name->GetReadOnlyRoots().this_string());
}
int ScopeInfo::ModuleIndex(Handle<String> name, VariableMode* mode,

View File

@ -68,13 +68,13 @@ bool SharedFunctionInfo::HasSharedName() const {
}
String* SharedFunctionInfo::Name() const {
if (!HasSharedName()) return GetHeap()->empty_string();
if (!HasSharedName()) return GetReadOnlyRoots().empty_string();
Object* value = name_or_scope_info();
if (value->IsScopeInfo()) {
if (ScopeInfo::cast(value)->HasFunctionName()) {
return String::cast(ScopeInfo::cast(value)->FunctionName());
}
return GetHeap()->empty_string();
return GetReadOnlyRoots().empty_string();
}
return String::cast(value);
}
@ -580,7 +580,7 @@ String* SharedFunctionInfo::inferred_name() {
return String::cast(function_identifier());
}
DCHECK(function_identifier()->IsUndefined() || HasBuiltinFunctionId());
return GetHeap()->empty_string();
return GetReadOnlyRoots().empty_string();
}
void SharedFunctionInfo::set_inferred_name(String* inferred_name) {

41
src/roots-inl.h Normal file
View File

@ -0,0 +1,41 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_ROOTS_INL_H_
#define V8_ROOTS_INL_H_
#include "src/roots.h"
#include "src/heap/heap-inl.h"
namespace v8 {
namespace internal {
#define ROOT_ACCESSOR(type, name, camel_name) \
type* ReadOnlyRoots::name() { return heap_->name(); }
STRONG_READ_ONLY_ROOT_LIST(ROOT_ACCESSOR)
#undef ROOT_ACCESSOR
#define STRING_ACCESSOR(name, str) \
String* ReadOnlyRoots::name() { return heap_->name(); }
INTERNALIZED_STRING_LIST(STRING_ACCESSOR)
#undef STRING_ACCESSOR
#define SYMBOL_ACCESSOR(name) \
Symbol* ReadOnlyRoots::name() { return heap_->name(); }
PRIVATE_SYMBOL_LIST(SYMBOL_ACCESSOR)
#undef SYMBOL_ACCESSOR
#define SYMBOL_ACCESSOR(name, description) \
Symbol* ReadOnlyRoots::name() { return heap_->name(); }
PUBLIC_SYMBOL_LIST(SYMBOL_ACCESSOR)
WELL_KNOWN_SYMBOL_LIST(SYMBOL_ACCESSOR)
#undef SYMBOL_ACCESSOR
} // namespace internal
} // namespace v8
#endif // V8_ROOTS_INL_H_

311
src/roots.h Normal file
View File

@ -0,0 +1,311 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_ROOTS_H_
#define V8_ROOTS_H_
#include "src/heap-symbols.h"
namespace v8 {
namespace internal {
// Defines all the read-only roots in Heap.
#define STRONG_READ_ONLY_ROOT_LIST(V) \
/* Cluster the most popular ones in a few cache lines here at the top. */ \
/* The first 32 entries are most often used in the startup snapshot and */ \
/* can use a shorter representation in the serialization format. */ \
V(Map, free_space_map, FreeSpaceMap) \
V(Map, one_pointer_filler_map, OnePointerFillerMap) \
V(Map, two_pointer_filler_map, TwoPointerFillerMap) \
V(Oddball, uninitialized_value, UninitializedValue) \
V(Oddball, undefined_value, UndefinedValue) \
V(Oddball, the_hole_value, TheHoleValue) \
V(Oddball, null_value, NullValue) \
V(Oddball, true_value, TrueValue) \
V(Oddball, false_value, FalseValue) \
V(String, empty_string, empty_string) \
V(Map, meta_map, MetaMap) \
V(Map, byte_array_map, ByteArrayMap) \
V(Map, fixed_array_map, FixedArrayMap) \
V(Map, fixed_cow_array_map, FixedCOWArrayMap) \
V(Map, hash_table_map, HashTableMap) \
V(Map, symbol_map, SymbolMap) \
V(Map, one_byte_string_map, OneByteStringMap) \
V(Map, one_byte_internalized_string_map, OneByteInternalizedStringMap) \
V(Map, scope_info_map, ScopeInfoMap) \
V(Map, shared_function_info_map, SharedFunctionInfoMap) \
V(Map, code_map, CodeMap) \
V(Map, function_context_map, FunctionContextMap) \
V(Map, cell_map, CellMap) \
V(Map, weak_cell_map, WeakCellMap) \
V(Map, global_property_cell_map, GlobalPropertyCellMap) \
V(Map, foreign_map, ForeignMap) \
V(Map, heap_number_map, HeapNumberMap) \
V(Map, transition_array_map, TransitionArrayMap) \
V(Map, feedback_vector_map, FeedbackVectorMap) \
V(ScopeInfo, empty_scope_info, EmptyScopeInfo) \
V(FixedArray, empty_fixed_array, EmptyFixedArray) \
V(DescriptorArray, empty_descriptor_array, EmptyDescriptorArray) \
/* Entries beyond the first 32 */ \
/* The roots above this line should be boring from a GC point of view. */ \
/* This means they are never in new space and never on a page that is */ \
/* being compacted.*/ \
/* Oddballs */ \
V(Oddball, arguments_marker, ArgumentsMarker) \
V(Oddball, exception, Exception) \
V(Oddball, termination_exception, TerminationException) \
V(Oddball, optimized_out, OptimizedOut) \
V(Oddball, stale_register, StaleRegister) \
/* Context maps */ \
V(Map, native_context_map, NativeContextMap) \
V(Map, module_context_map, ModuleContextMap) \
V(Map, eval_context_map, EvalContextMap) \
V(Map, script_context_map, ScriptContextMap) \
V(Map, block_context_map, BlockContextMap) \
V(Map, catch_context_map, CatchContextMap) \
V(Map, with_context_map, WithContextMap) \
V(Map, debug_evaluate_context_map, DebugEvaluateContextMap) \
V(Map, script_context_table_map, ScriptContextTableMap) \
/* Maps */ \
V(Map, feedback_metadata_map, FeedbackMetadataArrayMap) \
V(Map, array_list_map, ArrayListMap) \
V(Map, bigint_map, BigIntMap) \
V(Map, boilerplate_description_map, BoilerplateDescriptionMap) \
V(Map, bytecode_array_map, BytecodeArrayMap) \
V(Map, code_data_container_map, CodeDataContainerMap) \
V(Map, descriptor_array_map, DescriptorArrayMap) \
V(Map, external_map, ExternalMap) \
V(Map, fixed_double_array_map, FixedDoubleArrayMap) \
V(Map, global_dictionary_map, GlobalDictionaryMap) \
V(Map, many_closures_cell_map, ManyClosuresCellMap) \
V(Map, message_object_map, JSMessageObjectMap) \
V(Map, module_info_map, ModuleInfoMap) \
V(Map, mutable_heap_number_map, MutableHeapNumberMap) \
V(Map, name_dictionary_map, NameDictionaryMap) \
V(Map, no_closures_cell_map, NoClosuresCellMap) \
V(Map, number_dictionary_map, NumberDictionaryMap) \
V(Map, one_closure_cell_map, OneClosureCellMap) \
V(Map, ordered_hash_map_map, OrderedHashMapMap) \
V(Map, ordered_hash_set_map, OrderedHashSetMap) \
V(Map, property_array_map, PropertyArrayMap) \
V(Map, side_effect_call_handler_info_map, SideEffectCallHandlerInfoMap) \
V(Map, side_effect_free_call_handler_info_map, \
SideEffectFreeCallHandlerInfoMap) \
V(Map, next_call_side_effect_free_call_handler_info_map, \
NextCallSideEffectFreeCallHandlerInfoMap) \
V(Map, simple_number_dictionary_map, SimpleNumberDictionaryMap) \
V(Map, sloppy_arguments_elements_map, SloppyArgumentsElementsMap) \
V(Map, small_ordered_hash_map_map, SmallOrderedHashMapMap) \
V(Map, small_ordered_hash_set_map, SmallOrderedHashSetMap) \
V(Map, string_table_map, StringTableMap) \
V(Map, weak_fixed_array_map, WeakFixedArrayMap) \
V(Map, weak_array_list_map, WeakArrayListMap) \
V(Map, ephemeron_hash_table_map, EphemeronHashTableMap) \
/* String maps */ \
V(Map, native_source_string_map, NativeSourceStringMap) \
V(Map, string_map, StringMap) \
V(Map, cons_one_byte_string_map, ConsOneByteStringMap) \
V(Map, cons_string_map, ConsStringMap) \
V(Map, thin_one_byte_string_map, ThinOneByteStringMap) \
V(Map, thin_string_map, ThinStringMap) \
V(Map, sliced_string_map, SlicedStringMap) \
V(Map, sliced_one_byte_string_map, SlicedOneByteStringMap) \
V(Map, external_string_map, ExternalStringMap) \
V(Map, external_string_with_one_byte_data_map, \
ExternalStringWithOneByteDataMap) \
V(Map, external_one_byte_string_map, ExternalOneByteStringMap) \
V(Map, short_external_string_map, ShortExternalStringMap) \
V(Map, short_external_string_with_one_byte_data_map, \
ShortExternalStringWithOneByteDataMap) \
V(Map, internalized_string_map, InternalizedStringMap) \
V(Map, external_internalized_string_map, ExternalInternalizedStringMap) \
V(Map, external_internalized_string_with_one_byte_data_map, \
ExternalInternalizedStringWithOneByteDataMap) \
V(Map, external_one_byte_internalized_string_map, \
ExternalOneByteInternalizedStringMap) \
V(Map, short_external_internalized_string_map, \
ShortExternalInternalizedStringMap) \
V(Map, short_external_internalized_string_with_one_byte_data_map, \
ShortExternalInternalizedStringWithOneByteDataMap) \
V(Map, short_external_one_byte_internalized_string_map, \
ShortExternalOneByteInternalizedStringMap) \
V(Map, short_external_one_byte_string_map, ShortExternalOneByteStringMap) \
/* Array element maps */ \
V(Map, fixed_uint8_array_map, FixedUint8ArrayMap) \
V(Map, fixed_int8_array_map, FixedInt8ArrayMap) \
V(Map, fixed_uint16_array_map, FixedUint16ArrayMap) \
V(Map, fixed_int16_array_map, FixedInt16ArrayMap) \
V(Map, fixed_uint32_array_map, FixedUint32ArrayMap) \
V(Map, fixed_int32_array_map, FixedInt32ArrayMap) \
V(Map, fixed_float32_array_map, FixedFloat32ArrayMap) \
V(Map, fixed_float64_array_map, FixedFloat64ArrayMap) \
V(Map, fixed_uint8_clamped_array_map, FixedUint8ClampedArrayMap) \
V(Map, fixed_biguint64_array_map, FixedBigUint64ArrayMap) \
V(Map, fixed_bigint64_array_map, FixedBigInt64ArrayMap) \
/* Oddball maps */ \
V(Map, undefined_map, UndefinedMap) \
V(Map, the_hole_map, TheHoleMap) \
V(Map, null_map, NullMap) \
V(Map, boolean_map, BooleanMap) \
V(Map, uninitialized_map, UninitializedMap) \
V(Map, arguments_marker_map, ArgumentsMarkerMap) \
V(Map, exception_map, ExceptionMap) \
V(Map, termination_exception_map, TerminationExceptionMap) \
V(Map, optimized_out_map, OptimizedOutMap) \
V(Map, stale_register_map, StaleRegisterMap) \
V(Map, self_reference_marker_map, SelfReferenceMarkerMap) \
/* Canonical empty values */ \
V(EnumCache, empty_enum_cache, EmptyEnumCache) \
V(PropertyArray, empty_property_array, EmptyPropertyArray) \
V(ByteArray, empty_byte_array, EmptyByteArray) \
V(BoilerplateDescription, empty_boilerplate_description, \
EmptyBoilerplateDescription) \
V(FixedTypedArrayBase, empty_fixed_uint8_array, EmptyFixedUint8Array) \
V(FixedTypedArrayBase, empty_fixed_int8_array, EmptyFixedInt8Array) \
V(FixedTypedArrayBase, empty_fixed_uint16_array, EmptyFixedUint16Array) \
V(FixedTypedArrayBase, empty_fixed_int16_array, EmptyFixedInt16Array) \
V(FixedTypedArrayBase, empty_fixed_uint32_array, EmptyFixedUint32Array) \
V(FixedTypedArrayBase, empty_fixed_int32_array, EmptyFixedInt32Array) \
V(FixedTypedArrayBase, empty_fixed_float32_array, EmptyFixedFloat32Array) \
V(FixedTypedArrayBase, empty_fixed_float64_array, EmptyFixedFloat64Array) \
V(FixedTypedArrayBase, empty_fixed_uint8_clamped_array, \
EmptyFixedUint8ClampedArray) \
V(FixedTypedArrayBase, empty_fixed_biguint64_array, \
EmptyFixedBigUint64Array) \
V(FixedTypedArrayBase, empty_fixed_bigint64_array, EmptyFixedBigInt64Array) \
V(Script, empty_script, EmptyScript) \
V(FeedbackCell, many_closures_cell, ManyClosuresCell) \
V(FixedArray, empty_sloppy_arguments_elements, EmptySloppyArgumentsElements) \
V(NumberDictionary, empty_slow_element_dictionary, \
EmptySlowElementDictionary) \
V(FixedArray, empty_ordered_hash_map, EmptyOrderedHashMap) \
V(FixedArray, empty_ordered_hash_set, EmptyOrderedHashSet) \
V(FeedbackMetadata, empty_feedback_metadata, EmptyFeedbackMetadata) \
V(PropertyCell, empty_property_cell, EmptyPropertyCell) \
V(WeakCell, empty_weak_cell, EmptyWeakCell) \
V(Cell, invalid_prototype_validity_cell, InvalidPrototypeValidityCell) \
V(InterceptorInfo, noop_interceptor_info, NoOpInterceptorInfo) \
V(WeakFixedArray, empty_weak_fixed_array, EmptyWeakFixedArray) \
V(WeakArrayList, empty_weak_array_list, EmptyWeakArrayList) \
/* Special numbers */ \
V(HeapNumber, nan_value, NanValue) \
V(HeapNumber, hole_nan_value, HoleNanValue) \
V(HeapNumber, infinity_value, InfinityValue) \
V(HeapNumber, minus_zero_value, MinusZeroValue) \
V(HeapNumber, minus_infinity_value, MinusInfinityValue) \
/* Marker for self-references during code-generation */ \
V(HeapObject, self_reference_marker, SelfReferenceMarker) \
/* Indirection lists for isolate-independent builtins */ \
V(FixedArray, builtins_constants_table, BuiltinsConstantsTable)
#define STRONG_MUTABLE_ROOT_LIST(V) \
/* Protectors */ \
V(Cell, array_constructor_protector, ArrayConstructorProtector) \
V(PropertyCell, no_elements_protector, NoElementsProtector) \
V(Cell, is_concat_spreadable_protector, IsConcatSpreadableProtector) \
V(PropertyCell, array_species_protector, ArraySpeciesProtector) \
V(PropertyCell, typed_array_species_protector, TypedArraySpeciesProtector) \
V(PropertyCell, promise_species_protector, PromiseSpeciesProtector) \
V(Cell, string_length_protector, StringLengthProtector) \
V(PropertyCell, array_iterator_protector, ArrayIteratorProtector) \
V(PropertyCell, array_buffer_neutering_protector, \
ArrayBufferNeuteringProtector) \
V(PropertyCell, promise_hook_protector, PromiseHookProtector) \
V(Cell, promise_resolve_protector, PromiseResolveProtector) \
V(PropertyCell, promise_then_protector, PromiseThenProtector) \
/* Caches */ \
V(FixedArray, number_string_cache, NumberStringCache) \
V(FixedArray, single_character_string_cache, SingleCharacterStringCache) \
V(FixedArray, string_split_cache, StringSplitCache) \
V(FixedArray, regexp_multiple_cache, RegExpMultipleCache) \
/* Lists and dictionaries */ \
V(NameDictionary, empty_property_dictionary, EmptyPropertyDictionary) \
V(NameDictionary, public_symbol_table, PublicSymbolTable) \
V(NameDictionary, api_symbol_table, ApiSymbolTable) \
V(NameDictionary, api_private_symbol_table, ApiPrivateSymbolTable) \
V(Object, script_list, ScriptList) \
V(SimpleNumberDictionary, code_stubs, CodeStubs) \
V(FixedArray, materialized_objects, MaterializedObjects) \
V(FixedArray, microtask_queue, MicrotaskQueue) \
V(FixedArray, detached_contexts, DetachedContexts) \
V(HeapObject, retaining_path_targets, RetainingPathTargets) \
V(WeakArrayList, retained_maps, RetainedMaps) \
/* Feedback vectors that we need for code coverage or type profile */ \
V(Object, feedback_vectors_for_profiling_tools, \
FeedbackVectorsForProfilingTools) \
V(Object, weak_stack_trace_list, WeakStackTraceList) \
V(Object, noscript_shared_function_infos, NoScriptSharedFunctionInfos) \
V(FixedArray, serialized_objects, SerializedObjects) \
V(FixedArray, serialized_global_proxy_sizes, SerializedGlobalProxySizes) \
V(TemplateList, message_listeners, MessageListeners) \
/* DeserializeLazy handlers for lazy bytecode deserialization */ \
V(Object, deserialize_lazy_handler, DeserializeLazyHandler) \
V(Object, deserialize_lazy_handler_wide, DeserializeLazyHandlerWide) \
V(Object, deserialize_lazy_handler_extra_wide, \
DeserializeLazyHandlerExtraWide) \
/* JS Entries */ \
V(Code, js_entry_code, JsEntryCode) \
V(Code, js_construct_entry_code, JsConstructEntryCode) \
V(Code, js_run_microtasks_entry_code, JsRunMicrotasksEntryCode)
#define STRONG_ROOT_LIST(V) \
STRONG_READ_ONLY_ROOT_LIST(V) \
STRONG_MUTABLE_ROOT_LIST(V)
// Entries in this list are limited to Smis and are not visited during GC.
#define SMI_ROOT_LIST(V) \
V(Smi, stack_limit, StackLimit) \
V(Smi, real_stack_limit, RealStackLimit) \
V(Smi, last_script_id, LastScriptId) \
V(Smi, last_debugging_id, LastDebuggingId) \
V(Smi, hash_seed, HashSeed) \
/* To distinguish the function templates, so that we can find them in the */ \
/* function cache of the native context. */ \
V(Smi, next_template_serial_number, NextTemplateSerialNumber) \
V(Smi, arguments_adaptor_deopt_pc_offset, ArgumentsAdaptorDeoptPCOffset) \
V(Smi, construct_stub_create_deopt_pc_offset, \
ConstructStubCreateDeoptPCOffset) \
V(Smi, construct_stub_invoke_deopt_pc_offset, \
ConstructStubInvokeDeoptPCOffset) \
V(Smi, interpreter_entry_return_pc_offset, InterpreterEntryReturnPCOffset)
#define ROOT_LIST(V) \
STRONG_ROOT_LIST(V) \
SMI_ROOT_LIST(V) \
V(StringTable, string_table, StringTable)
class Heap;
class String;
class Symbol;
class ReadOnlyRoots {
public:
explicit ReadOnlyRoots(Heap* heap) : heap_(heap) {}
#define ROOT_ACCESSOR(type, name, camel_name) inline class type* name();
STRONG_READ_ONLY_ROOT_LIST(ROOT_ACCESSOR)
#undef ROOT_ACCESSOR
#define STRING_ACCESSOR(name, str) inline String* name();
INTERNALIZED_STRING_LIST(STRING_ACCESSOR)
#undef STRING_ACCESSOR
#define SYMBOL_ACCESSOR(name) inline Symbol* name();
PRIVATE_SYMBOL_LIST(SYMBOL_ACCESSOR)
#undef SYMBOL_ACCESSOR
#define SYMBOL_ACCESSOR(name, description) inline Symbol* name();
PUBLIC_SYMBOL_LIST(SYMBOL_ACCESSOR)
WELL_KNOWN_SYMBOL_LIST(SYMBOL_ACCESSOR)
#undef SYMBOL_ACCESSOR
private:
Heap* heap_;
};
} // namespace internal
} // namespace v8
#endif // V8_ROOTS_H_

View File

@ -67,7 +67,8 @@ const wasm::WasmModule* WasmModuleObject::module() const {
return native_module()->module();
}
void WasmModuleObject::reset_breakpoint_infos() {
WRITE_FIELD(this, kBreakPointInfosOffset, GetHeap()->undefined_value());
WRITE_FIELD(this, kBreakPointInfosOffset,
GetReadOnlyRoots().undefined_value());
}
bool WasmModuleObject::is_asm_js() {
bool asm_js = module()->origin == wasm::kAsmJsOrigin;

View File

@ -1141,7 +1141,7 @@ void ImportedFunctionEntry::set_wasm_to_wasm(WasmInstanceObject* instance,
*instance_, index_, instance, call_target);
instance_->imported_function_instances()->set(index_, instance);
instance_->imported_function_callables()->set(
index_, instance_->GetHeap()->undefined_value());
index_, instance_->GetReadOnlyRoots().undefined_value());
instance_->imported_function_targets()[index_] = call_target;
}

View File

@ -345,14 +345,14 @@ KNOWN_OBJECTS = {
("RO_SPACE", 0x054f1): "SelfReferenceMarker",
("OLD_SPACE", 0x02211): "EmptyScript",
("OLD_SPACE", 0x02299): "ManyClosuresCell",
("OLD_SPACE", 0x022b9): "NoElementsProtector",
("OLD_SPACE", 0x022e1): "IsConcatSpreadableProtector",
("OLD_SPACE", 0x022f1): "ArraySpeciesProtector",
("OLD_SPACE", 0x02319): "TypedArraySpeciesProtector",
("OLD_SPACE", 0x02341): "PromiseSpeciesProtector",
("OLD_SPACE", 0x02369): "StringLengthProtector",
("OLD_SPACE", 0x02379): "ArrayIteratorProtector",
("OLD_SPACE", 0x023a1): "ArrayBufferNeuteringProtector",
("OLD_SPACE", 0x02919): "NoElementsProtector",
("OLD_SPACE", 0x02941): "IsConcatSpreadableProtector",
("OLD_SPACE", 0x02951): "ArraySpeciesProtector",
("OLD_SPACE", 0x02979): "TypedArraySpeciesProtector",
("OLD_SPACE", 0x029a1): "PromiseSpeciesProtector",
("OLD_SPACE", 0x029c9): "StringLengthProtector",
("OLD_SPACE", 0x029d9): "ArrayIteratorProtector",
("OLD_SPACE", 0x02a01): "ArrayBufferNeuteringProtector",
}
# List of known V8 Frame Markers.