[in-place weak refs] Replace WeakCells in DescriptorArray.
BUG=v8:7308 Change-Id: Ib0ad52916d6f5b65e7612981b467b491d832f505 Reviewed-on: https://chromium-review.googlesource.com/1075053 Commit-Queue: Marja Hölttä <marja@chromium.org> Reviewed-by: Tobias Tebbi <tebbi@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Reviewed-by: Igor Sheludko <ishell@chromium.org> Cr-Commit-Position: refs/heads/master@{#53473}
This commit is contained in:
parent
c6d5b6968f
commit
0f23ceddfb
@ -4974,7 +4974,7 @@ bool Genesis::InstallNatives(GlobalContextType context_type) {
|
||||
isolate(), *length, array_function->initial_map());
|
||||
DCHECK_NE(old, DescriptorArray::kNotFound);
|
||||
Descriptor d = Descriptor::AccessorConstant(
|
||||
length, handle(array_descriptors->GetValue(old), isolate()),
|
||||
length, handle(array_descriptors->GetStrongValue(old), isolate()),
|
||||
array_descriptors->GetDetails(old).attributes());
|
||||
initial_map->AppendDescriptor(&d);
|
||||
}
|
||||
@ -5379,7 +5379,7 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
|
||||
DCHECK(!FLAG_track_constant_fields);
|
||||
HandleScope inner(isolate());
|
||||
Handle<Name> key = Handle<Name>(descs->GetKey(i));
|
||||
Handle<Object> value(descs->GetValue(i), isolate());
|
||||
Handle<Object> value(descs->GetStrongValue(i), isolate());
|
||||
JSObject::AddProperty(to, key, value, details.attributes());
|
||||
|
||||
} else {
|
||||
@ -5392,7 +5392,7 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
|
||||
HandleScope inner(isolate());
|
||||
DCHECK(!to->HasFastProperties());
|
||||
// Add to dictionary.
|
||||
Handle<Object> value(descs->GetValue(i), isolate());
|
||||
Handle<Object> value(descs->GetStrongValue(i), isolate());
|
||||
PropertyDetails d(kAccessor, details.attributes(),
|
||||
PropertyCellType::kMutable);
|
||||
JSObject::SetNormalizedProperty(to, key, value, d);
|
||||
|
@ -49,7 +49,7 @@ TF_BUILTIN(FastFunctionPrototypeBind, CodeStubAssembler) {
|
||||
// Minimum descriptor array length required for fast path.
|
||||
const int min_descriptors_length = DescriptorArray::LengthFor(Max(
|
||||
JSFunction::kLengthDescriptorIndex, JSFunction::kNameDescriptorIndex));
|
||||
TNode<Smi> descriptors_length = LoadFixedArrayBaseLength(descriptors);
|
||||
TNode<Smi> descriptors_length = LoadWeakFixedArrayLength(descriptors);
|
||||
GotoIf(SmiLessThanOrEqual(descriptors_length,
|
||||
SmiConstant(min_descriptors_length)),
|
||||
&slow);
|
||||
@ -60,25 +60,25 @@ TF_BUILTIN(FastFunctionPrototypeBind, CodeStubAssembler) {
|
||||
Comment("Check name and length properties");
|
||||
{
|
||||
const int length_index = JSFunction::kLengthDescriptorIndex;
|
||||
TNode<Name> maybe_length = CAST(LoadFixedArrayElement(
|
||||
TNode<Name> maybe_length = CAST(LoadWeakFixedArrayElement(
|
||||
descriptors, DescriptorArray::ToKeyIndex(length_index)));
|
||||
GotoIf(WordNotEqual(maybe_length, LoadRoot(Heap::klength_stringRootIndex)),
|
||||
&slow);
|
||||
|
||||
TNode<Object> maybe_length_accessor = LoadFixedArrayElement(
|
||||
descriptors, DescriptorArray::ToValueIndex(length_index));
|
||||
TNode<Object> maybe_length_accessor = CAST(LoadWeakFixedArrayElement(
|
||||
descriptors, DescriptorArray::ToValueIndex(length_index)));
|
||||
GotoIf(TaggedIsSmi(maybe_length_accessor), &slow);
|
||||
Node* length_value_map = LoadMap(CAST(maybe_length_accessor));
|
||||
GotoIfNot(IsAccessorInfoMap(length_value_map), &slow);
|
||||
|
||||
const int name_index = JSFunction::kNameDescriptorIndex;
|
||||
TNode<Name> maybe_name = CAST(LoadFixedArrayElement(
|
||||
TNode<Name> maybe_name = CAST(LoadWeakFixedArrayElement(
|
||||
descriptors, DescriptorArray::ToKeyIndex(name_index)));
|
||||
GotoIf(WordNotEqual(maybe_name, LoadRoot(Heap::kname_stringRootIndex)),
|
||||
&slow);
|
||||
|
||||
TNode<Object> maybe_name_accessor = LoadFixedArrayElement(
|
||||
descriptors, DescriptorArray::ToValueIndex(name_index));
|
||||
TNode<Object> maybe_name_accessor = CAST(LoadWeakFixedArrayElement(
|
||||
descriptors, DescriptorArray::ToValueIndex(name_index)));
|
||||
GotoIf(TaggedIsSmi(maybe_name_accessor), &slow);
|
||||
TNode<Map> name_value_map = LoadMap(CAST(maybe_name_accessor));
|
||||
GotoIfNot(IsAccessorInfoMap(name_value_map), &slow);
|
||||
|
@ -581,8 +581,8 @@ void ObjectBuiltinsAssembler::ObjectAssignFast(TNode<Context> context,
|
||||
DescriptorArrayForEach(
|
||||
list, Unsigned(Int32Constant(0)), nof_descriptors,
|
||||
[=, &var_stable](TNode<UintPtrT> descriptor_key_index) {
|
||||
TNode<Name> next_key =
|
||||
CAST(LoadFixedArrayElement(from_descriptors, descriptor_key_index));
|
||||
TNode<Name> next_key = CAST(
|
||||
LoadWeakFixedArrayElement(from_descriptors, descriptor_key_index));
|
||||
|
||||
TVARIABLE(Object, var_value, SmiConstant(0));
|
||||
Label do_store(this), next_iteration(this);
|
||||
@ -620,7 +620,7 @@ void ObjectBuiltinsAssembler::ObjectAssignFast(TNode<Context> context,
|
||||
|
||||
BIND(&if_found_fast);
|
||||
{
|
||||
Node* descriptors = var_meta_storage.value();
|
||||
TNode<DescriptorArray> descriptors = CAST(var_meta_storage.value());
|
||||
Node* name_index = var_entry.value();
|
||||
|
||||
// Skip non-enumerable properties.
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "src/frames-inl.h"
|
||||
#include "src/frames.h"
|
||||
#include "src/objects/api-callbacks.h"
|
||||
#include "src/objects/descriptor-array.h"
|
||||
#include "src/objects/ordered-hash-table-inl.h"
|
||||
|
||||
namespace v8 {
|
||||
@ -2513,14 +2514,14 @@ void CodeStubAssembler::EnsureArrayLengthWritable(TNode<Map> map,
|
||||
|
||||
int length_index = JSArray::kLengthDescriptorIndex;
|
||||
#ifdef DEBUG
|
||||
TNode<Name> maybe_length = CAST(LoadFixedArrayElement(
|
||||
TNode<Name> maybe_length = CAST(LoadWeakFixedArrayElement(
|
||||
descriptors, DescriptorArray::ToKeyIndex(length_index)));
|
||||
CSA_ASSERT(this,
|
||||
WordEqual(maybe_length, LoadRoot(Heap::klength_stringRootIndex)));
|
||||
#endif
|
||||
|
||||
TNode<Int32T> details = LoadAndUntagToWord32FixedArrayElement(
|
||||
descriptors, DescriptorArray::ToDetailsIndex(length_index));
|
||||
TNode<Uint32T> details = LoadDetailsByKeyIndex(
|
||||
descriptors, IntPtrConstant(DescriptorArray::ToKeyIndex(length_index)));
|
||||
GotoIf(IsSetWord32(details, PropertyDetails::kAttributesReadOnlyMask),
|
||||
bailout);
|
||||
}
|
||||
@ -6958,6 +6959,32 @@ TNode<IntPtrT> CodeStubAssembler::EntryToIndex(TNode<IntPtrT> entry,
|
||||
field_index));
|
||||
}
|
||||
|
||||
TNode<Uint32T> CodeStubAssembler::LoadDetailsByKeyIndex(
|
||||
TNode<DescriptorArray> container, TNode<IntPtrT> key_index) {
|
||||
const int kKeyToDetailsOffset =
|
||||
(DescriptorArray::kEntryDetailsIndex - DescriptorArray::kEntryKeyIndex) *
|
||||
kPointerSize;
|
||||
return Unsigned(LoadAndUntagToWord32ArrayElement(
|
||||
container, WeakFixedArray::kHeaderSize, key_index, kKeyToDetailsOffset));
|
||||
}
|
||||
|
||||
TNode<Object> CodeStubAssembler::LoadValueByKeyIndex(
|
||||
TNode<DescriptorArray> container, TNode<IntPtrT> key_index) {
|
||||
const int kKeyToValueOffset =
|
||||
(DescriptorArray::kEntryValueIndex - DescriptorArray::kEntryKeyIndex) *
|
||||
kPointerSize;
|
||||
return CAST(
|
||||
LoadWeakFixedArrayElement(container, key_index, kKeyToValueOffset));
|
||||
}
|
||||
|
||||
TNode<MaybeObject> CodeStubAssembler::LoadFieldTypeByKeyIndex(
|
||||
TNode<DescriptorArray> container, TNode<IntPtrT> key_index) {
|
||||
const int kKeyToValueOffset =
|
||||
(DescriptorArray::kEntryValueIndex - DescriptorArray::kEntryKeyIndex) *
|
||||
kPointerSize;
|
||||
return LoadWeakFixedArrayElement(container, key_index, kKeyToValueOffset);
|
||||
}
|
||||
|
||||
template TNode<IntPtrT> CodeStubAssembler::EntryToIndex<NameDictionary>(
|
||||
TNode<IntPtrT>, int);
|
||||
template TNode<IntPtrT> CodeStubAssembler::EntryToIndex<GlobalDictionary>(
|
||||
@ -7281,8 +7308,8 @@ void CodeStubAssembler::LookupLinear(TNode<Name> unique_name,
|
||||
TVariable<IntPtrT>* var_name_index,
|
||||
Label* if_not_found) {
|
||||
static_assert(std::is_base_of<FixedArray, Array>::value ||
|
||||
std::is_base_of<TransitionArray, Array>::value,
|
||||
"T must be a descendant of FixedArray or a TransitionArray");
|
||||
std::is_base_of<WeakFixedArray, Array>::value,
|
||||
"T must be a descendant of FixedArray or a WeakFixedArray");
|
||||
Comment("LookupLinear");
|
||||
TNode<IntPtrT> first_inclusive = IntPtrConstant(Array::ToKeyIndex(0));
|
||||
TNode<IntPtrT> factor = IntPtrConstant(Array::kEntrySize);
|
||||
@ -7305,8 +7332,9 @@ void CodeStubAssembler::LookupLinear(TNode<Name> unique_name,
|
||||
template <>
|
||||
TNode<Uint32T> CodeStubAssembler::NumberOfEntries<DescriptorArray>(
|
||||
TNode<DescriptorArray> descriptors) {
|
||||
return Unsigned(LoadAndUntagToWord32FixedArrayElement(
|
||||
descriptors, IntPtrConstant(DescriptorArray::kDescriptorLengthIndex)));
|
||||
return Unsigned(LoadAndUntagToWord32ArrayElement(
|
||||
descriptors, WeakFixedArray::kHeaderSize,
|
||||
IntPtrConstant(DescriptorArray::kDescriptorLengthIndex)));
|
||||
}
|
||||
|
||||
template <>
|
||||
@ -7360,7 +7388,7 @@ template <typename Array>
|
||||
TNode<Name> CodeStubAssembler::GetKey(TNode<Array> array,
|
||||
TNode<Uint32T> entry_index) {
|
||||
static_assert(std::is_base_of<FixedArray, Array>::value ||
|
||||
std::is_base_of<TransitionArray, Array>::value,
|
||||
std::is_base_of<WeakFixedArray, Array>::value,
|
||||
"T must be a descendant of FixedArray or a TransitionArray");
|
||||
const int key_offset = Array::ToKeyIndex(0) * kPointerSize;
|
||||
TNode<MaybeObject> element =
|
||||
@ -7377,9 +7405,9 @@ template TNode<Name> CodeStubAssembler::GetKey<TransitionArray>(
|
||||
TNode<Uint32T> CodeStubAssembler::DescriptorArrayGetDetails(
|
||||
TNode<DescriptorArray> descriptors, TNode<Uint32T> descriptor_number) {
|
||||
const int details_offset = DescriptorArray::ToDetailsIndex(0) * kPointerSize;
|
||||
return Unsigned(LoadAndUntagToWord32FixedArrayElement(
|
||||
descriptors, EntryIndexToIndex<DescriptorArray>(descriptor_number),
|
||||
details_offset));
|
||||
return Unsigned(LoadAndUntagToWord32ArrayElement(
|
||||
descriptors, WeakFixedArray::kHeaderSize,
|
||||
EntryIndexToIndex<DescriptorArray>(descriptor_number), details_offset));
|
||||
}
|
||||
|
||||
template <typename Array>
|
||||
@ -7632,27 +7660,23 @@ Node* CodeStubAssembler::GetMethod(Node* context, Node* object,
|
||||
return method;
|
||||
}
|
||||
|
||||
void CodeStubAssembler::LoadPropertyFromFastObject(Node* object, Node* map,
|
||||
Node* descriptors,
|
||||
Node* name_index,
|
||||
Variable* var_details,
|
||||
Variable* var_value) {
|
||||
void CodeStubAssembler::LoadPropertyFromFastObject(
|
||||
Node* object, Node* map, TNode<DescriptorArray> descriptors,
|
||||
Node* name_index, Variable* var_details, Variable* var_value) {
|
||||
DCHECK_EQ(MachineRepresentation::kWord32, var_details->rep());
|
||||
DCHECK_EQ(MachineRepresentation::kTagged, var_value->rep());
|
||||
|
||||
Node* details =
|
||||
LoadDetailsByKeyIndex<DescriptorArray>(descriptors, name_index);
|
||||
LoadDetailsByKeyIndex(descriptors, UncheckedCast<IntPtrT>(name_index));
|
||||
var_details->Bind(details);
|
||||
|
||||
LoadPropertyFromFastObject(object, map, descriptors, name_index, details,
|
||||
var_value);
|
||||
}
|
||||
|
||||
void CodeStubAssembler::LoadPropertyFromFastObject(Node* object, Node* map,
|
||||
Node* descriptors,
|
||||
Node* name_index,
|
||||
Node* details,
|
||||
Variable* var_value) {
|
||||
void CodeStubAssembler::LoadPropertyFromFastObject(
|
||||
Node* object, Node* map, TNode<DescriptorArray> descriptors,
|
||||
Node* name_index, Node* details, Variable* var_value) {
|
||||
Comment("[ LoadPropertyFromFastObject");
|
||||
|
||||
Node* location = DecodeWord32<PropertyDetails::LocationField>(details);
|
||||
@ -7735,7 +7759,7 @@ void CodeStubAssembler::LoadPropertyFromFastObject(Node* object, Node* map,
|
||||
BIND(&if_in_descriptor);
|
||||
{
|
||||
var_value->Bind(
|
||||
LoadValueByKeyIndex<DescriptorArray>(descriptors, name_index));
|
||||
LoadValueByKeyIndex(descriptors, UncheckedCast<IntPtrT>(name_index)));
|
||||
Goto(&done);
|
||||
}
|
||||
BIND(&done);
|
||||
@ -7919,7 +7943,7 @@ void CodeStubAssembler::TryGetOwnProperty(
|
||||
&var_entry, if_not_found, if_bailout);
|
||||
BIND(&if_found_fast);
|
||||
{
|
||||
Node* descriptors = var_meta_storage.value();
|
||||
TNode<DescriptorArray> descriptors = CAST(var_meta_storage.value());
|
||||
Node* name_index = var_entry.value();
|
||||
|
||||
LoadPropertyFromFastObject(object, map, descriptors, name_index,
|
||||
|
@ -1804,6 +1804,13 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
||||
LoadFixedArrayElement(container, key_index, kKeyToValueOffset));
|
||||
}
|
||||
|
||||
TNode<Uint32T> LoadDetailsByKeyIndex(TNode<DescriptorArray> container,
|
||||
TNode<IntPtrT> key_index);
|
||||
TNode<Object> LoadValueByKeyIndex(TNode<DescriptorArray> container,
|
||||
TNode<IntPtrT> key_index);
|
||||
TNode<MaybeObject> LoadFieldTypeByKeyIndex(TNode<DescriptorArray> container,
|
||||
TNode<IntPtrT> key_index);
|
||||
|
||||
// Stores the details for the entry with the given key_index.
|
||||
// |details| must be a Smi.
|
||||
template <class ContainerType>
|
||||
@ -1970,11 +1977,13 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
||||
TailCallStub(Builtins::CallableFor(isolate(), id), context, args...));
|
||||
}
|
||||
|
||||
void LoadPropertyFromFastObject(Node* object, Node* map, Node* descriptors,
|
||||
void LoadPropertyFromFastObject(Node* object, Node* map,
|
||||
TNode<DescriptorArray> descriptors,
|
||||
Node* name_index, Variable* var_details,
|
||||
Variable* var_value);
|
||||
|
||||
void LoadPropertyFromFastObject(Node* object, Node* map, Node* descriptors,
|
||||
void LoadPropertyFromFastObject(Node* object, Node* map,
|
||||
TNode<DescriptorArray> descriptors,
|
||||
Node* name_index, Node* details,
|
||||
Variable* var_value);
|
||||
|
||||
|
@ -419,7 +419,7 @@ bool AccessInfoFactory::ComputePropertyAccessInfo(
|
||||
DCHECK(!FLAG_track_constant_fields);
|
||||
*access_info = PropertyAccessInfo::DataConstant(
|
||||
MapHandles{receiver_map},
|
||||
handle(descriptors->GetValue(number), isolate()), holder);
|
||||
handle(descriptors->GetStrongValue(number), isolate()), holder);
|
||||
return true;
|
||||
} else {
|
||||
DCHECK_EQ(kAccessor, details.kind());
|
||||
@ -444,7 +444,8 @@ bool AccessInfoFactory::ComputePropertyAccessInfo(
|
||||
MapHandles{receiver_map}, cell);
|
||||
return true;
|
||||
}
|
||||
Handle<Object> accessors(descriptors->GetValue(number), isolate());
|
||||
Handle<Object> accessors(descriptors->GetStrongValue(number),
|
||||
isolate());
|
||||
if (!accessors->IsAccessorPair()) return false;
|
||||
Handle<Object> accessor(
|
||||
access_mode == AccessMode::kLoad
|
||||
|
@ -430,7 +430,7 @@ Reduction JSCallReducer::ReduceFunctionPrototypeBind(Node* node) {
|
||||
isolate()->heap()->length_string()) {
|
||||
return NoChange();
|
||||
}
|
||||
if (!descriptors->GetValue(JSFunction::kLengthDescriptorIndex)
|
||||
if (!descriptors->GetStrongValue(JSFunction::kLengthDescriptorIndex)
|
||||
->IsAccessorInfo()) {
|
||||
return NoChange();
|
||||
}
|
||||
@ -438,7 +438,7 @@ Reduction JSCallReducer::ReduceFunctionPrototypeBind(Node* node) {
|
||||
isolate()->heap()->name_string()) {
|
||||
return NoChange();
|
||||
}
|
||||
if (!descriptors->GetValue(JSFunction::kNameDescriptorIndex)
|
||||
if (!descriptors->GetStrongValue(JSFunction::kNameDescriptorIndex)
|
||||
->IsAccessorInfo()) {
|
||||
return NoChange();
|
||||
}
|
||||
|
@ -334,6 +334,10 @@ Handle<T> Factory::NewWeakFixedArrayWithMap(Heap::RootListIndex map_root_index,
|
||||
template Handle<FixedArray> Factory::NewFixedArrayWithMap<FixedArray>(
|
||||
Heap::RootListIndex, int, PretenureFlag);
|
||||
|
||||
template Handle<DescriptorArray>
|
||||
Factory::NewWeakFixedArrayWithMap<DescriptorArray>(Heap::RootListIndex, int,
|
||||
PretenureFlag);
|
||||
|
||||
Handle<FixedArray> Factory::NewFixedArray(int length, PretenureFlag pretenure) {
|
||||
DCHECK_LE(0, length);
|
||||
if (length == 0) return empty_fixed_array();
|
||||
@ -2710,7 +2714,7 @@ Handle<JSGlobalObject> Factory::NewJSGlobalObject(
|
||||
PropertyCellType::kMutable);
|
||||
Handle<Name> name(descs->GetKey(i));
|
||||
Handle<PropertyCell> cell = NewPropertyCell(name);
|
||||
cell->set_value(descs->GetValue(i));
|
||||
cell->set_value(descs->GetStrongValue(i));
|
||||
// |dictionary| already contains enough space for all properties.
|
||||
USE(GlobalDictionary::Add(dictionary, name, cell, d));
|
||||
}
|
||||
|
@ -1816,8 +1816,8 @@ void MarkCompactCollector::TrimDescriptorArray(Map* map,
|
||||
int number_of_descriptors = descriptors->number_of_descriptors_storage();
|
||||
int to_trim = number_of_descriptors - number_of_own_descriptors;
|
||||
if (to_trim > 0) {
|
||||
heap_->RightTrimFixedArray(descriptors,
|
||||
to_trim * DescriptorArray::kEntrySize);
|
||||
heap_->RightTrimWeakFixedArray(descriptors,
|
||||
to_trim * DescriptorArray::kEntrySize);
|
||||
descriptors->SetNumberOfDescriptors(number_of_own_descriptors);
|
||||
|
||||
TrimEnumCache(map, descriptors);
|
||||
|
@ -311,16 +311,15 @@ bool Heap::CreateInitialMaps() {
|
||||
{
|
||||
STATIC_ASSERT(DescriptorArray::kFirstIndex != 0);
|
||||
int length = DescriptorArray::kFirstIndex;
|
||||
int size = FixedArray::SizeFor(length);
|
||||
int size = WeakFixedArray::SizeFor(length);
|
||||
if (!AllocateRaw(size, RO_SPACE).To(&obj)) return false;
|
||||
obj->set_map_after_allocation(descriptor_array_map(), SKIP_WRITE_BARRIER);
|
||||
DescriptorArray::cast(obj)->set_length(length);
|
||||
}
|
||||
set_empty_descriptor_array(DescriptorArray::cast(obj));
|
||||
DescriptorArray::cast(obj)->set(DescriptorArray::kDescriptorLengthIndex,
|
||||
Smi::kZero);
|
||||
DescriptorArray::cast(obj)->set(DescriptorArray::kEnumCacheIndex,
|
||||
empty_enum_cache());
|
||||
DescriptorArray::cast(obj)->SetNumberOfDescriptors(0);
|
||||
WeakFixedArray::cast(obj)->Set(DescriptorArray::kEnumCacheIndex,
|
||||
MaybeObject::FromObject(empty_enum_cache()));
|
||||
|
||||
// Fix the instance_descriptors for the existing maps.
|
||||
FinalizePartialMap(meta_map());
|
||||
|
@ -251,16 +251,22 @@ void AccessorAssembler::HandleLoadField(Node* holder, Node* handler_word,
|
||||
}
|
||||
}
|
||||
|
||||
Node* AccessorAssembler::LoadDescriptorValue(Node* map, Node* descriptor) {
|
||||
Node* descriptors = LoadMapDescriptors(map);
|
||||
TNode<Object> AccessorAssembler::LoadDescriptorValue(Node* map,
|
||||
Node* descriptor) {
|
||||
return CAST(LoadDescriptorValueOrFieldType(map, descriptor));
|
||||
}
|
||||
|
||||
TNode<MaybeObject> AccessorAssembler::LoadDescriptorValueOrFieldType(
|
||||
Node* map, Node* descriptor) {
|
||||
TNode<DescriptorArray> descriptors = LoadMapDescriptors(map);
|
||||
Node* scaled_descriptor =
|
||||
IntPtrMul(descriptor, IntPtrConstant(DescriptorArray::kEntrySize));
|
||||
Node* value_index = IntPtrAdd(
|
||||
scaled_descriptor, IntPtrConstant(DescriptorArray::kFirstIndex +
|
||||
DescriptorArray::kEntryValueIndex));
|
||||
CSA_ASSERT(this, UintPtrLessThan(descriptor, LoadAndUntagFixedArrayBaseLength(
|
||||
CSA_ASSERT(this, UintPtrLessThan(descriptor, LoadAndUntagWeakFixedArrayLength(
|
||||
descriptors)));
|
||||
return LoadFixedArrayElement(descriptors, value_index);
|
||||
return LoadWeakFixedArrayElement(descriptors, value_index);
|
||||
}
|
||||
|
||||
void AccessorAssembler::HandleLoadICSmiHandlerCase(
|
||||
@ -924,21 +930,21 @@ void AccessorAssembler::HandleStoreICTransitionMapHandlerCase(
|
||||
// Load last descriptor details.
|
||||
Node* nof = DecodeWordFromWord32<Map::NumberOfOwnDescriptorsBits>(bitfield3);
|
||||
CSA_ASSERT(this, WordNotEqual(nof, IntPtrConstant(0)));
|
||||
Node* descriptors = LoadMapDescriptors(transition_map);
|
||||
TNode<DescriptorArray> descriptors = LoadMapDescriptors(transition_map);
|
||||
|
||||
Node* factor = IntPtrConstant(DescriptorArray::kEntrySize);
|
||||
Node* last_key_index = IntPtrAdd(
|
||||
IntPtrConstant(DescriptorArray::ToKeyIndex(-1)), IntPtrMul(nof, factor));
|
||||
TNode<IntPtrT> last_key_index = UncheckedCast<IntPtrT>(IntPtrAdd(
|
||||
IntPtrConstant(DescriptorArray::ToKeyIndex(-1)), IntPtrMul(nof, factor)));
|
||||
if (validate_transition_handler) {
|
||||
Node* key = LoadFixedArrayElement(descriptors, last_key_index);
|
||||
Node* key = LoadWeakFixedArrayElement(descriptors, last_key_index);
|
||||
GotoIf(WordNotEqual(key, p->name), miss);
|
||||
} else {
|
||||
CSA_ASSERT(
|
||||
this,
|
||||
WordEqual(LoadFixedArrayElement(descriptors, last_key_index), p->name));
|
||||
CSA_ASSERT(this,
|
||||
WordEqual(BitcastMaybeObjectToWord(LoadWeakFixedArrayElement(
|
||||
descriptors, last_key_index)),
|
||||
p->name));
|
||||
}
|
||||
Node* details =
|
||||
LoadDetailsByKeyIndex<DescriptorArray>(descriptors, last_key_index);
|
||||
Node* details = LoadDetailsByKeyIndex(descriptors, last_key_index);
|
||||
if (validate_transition_handler) {
|
||||
// Follow transitions only in the following cases:
|
||||
// 1) name is a non-private symbol and attributes equal to NONE,
|
||||
@ -964,9 +970,9 @@ void AccessorAssembler::HandleStoreICTransitionMapHandlerCase(
|
||||
true);
|
||||
}
|
||||
|
||||
void AccessorAssembler::CheckFieldType(Node* descriptors, Node* name_index,
|
||||
Node* representation, Node* value,
|
||||
Label* bailout) {
|
||||
void AccessorAssembler::CheckFieldType(TNode<DescriptorArray> descriptors,
|
||||
Node* name_index, Node* representation,
|
||||
Node* value, Label* bailout) {
|
||||
Label r_smi(this), r_double(this), r_heapobject(this), all_fine(this);
|
||||
// Ignore FLAG_track_fields etc. and always emit code for all checks,
|
||||
// because this builtin is part of the snapshot and therefore should
|
||||
@ -1002,20 +1008,25 @@ void AccessorAssembler::CheckFieldType(Node* descriptors, Node* name_index,
|
||||
BIND(&r_heapobject);
|
||||
{
|
||||
GotoIf(TaggedIsSmi(value), bailout);
|
||||
Node* field_type =
|
||||
LoadValueByKeyIndex<DescriptorArray>(descriptors, name_index);
|
||||
TNode<MaybeObject> field_type = LoadFieldTypeByKeyIndex(
|
||||
descriptors, UncheckedCast<IntPtrT>(name_index));
|
||||
intptr_t kNoneType = reinterpret_cast<intptr_t>(FieldType::None());
|
||||
intptr_t kAnyType = reinterpret_cast<intptr_t>(FieldType::Any());
|
||||
DCHECK_NE(kNoneType, kClearedWeakHeapObject);
|
||||
DCHECK_NE(kAnyType, kClearedWeakHeapObject);
|
||||
// FieldType::None can't hold any value.
|
||||
GotoIf(WordEqual(field_type, IntPtrConstant(kNoneType)), bailout);
|
||||
GotoIf(WordEqual(BitcastMaybeObjectToWord(field_type),
|
||||
IntPtrConstant(kNoneType)),
|
||||
bailout);
|
||||
// FieldType::Any can hold any value.
|
||||
GotoIf(WordEqual(field_type, IntPtrConstant(kAnyType)), &all_fine);
|
||||
CSA_ASSERT(this, IsWeakCell(field_type));
|
||||
// Cleared WeakCells count as FieldType::None, which can't hold any value.
|
||||
field_type = LoadWeakCellValue(field_type, bailout);
|
||||
GotoIf(WordEqual(BitcastMaybeObjectToWord(field_type),
|
||||
IntPtrConstant(kAnyType)),
|
||||
&all_fine);
|
||||
// Cleared weak references count as FieldType::None, which can't hold any
|
||||
// value.
|
||||
TNode<Map> field_type_map = CAST(ToWeakHeapObject(field_type, bailout));
|
||||
// FieldType::Class(...) performs a map check.
|
||||
CSA_ASSERT(this, IsMap(field_type));
|
||||
Branch(WordEqual(LoadMap(value), field_type), &all_fine, bailout);
|
||||
Branch(WordEqual(LoadMap(value), field_type_map), &all_fine, bailout);
|
||||
}
|
||||
|
||||
BIND(&all_fine);
|
||||
@ -1049,8 +1060,8 @@ void AccessorAssembler::OverwriteExistingFastDataProperty(
|
||||
Node* representation =
|
||||
DecodeWord32<PropertyDetails::RepresentationField>(details);
|
||||
|
||||
CheckFieldType(descriptors, descriptor_name_index, representation, value,
|
||||
slow);
|
||||
CheckFieldType(CAST(descriptors), descriptor_name_index, representation,
|
||||
value, slow);
|
||||
|
||||
Node* field_index =
|
||||
DecodeWordFromWord32<PropertyDetails::FieldIndexField>(details);
|
||||
@ -1160,8 +1171,8 @@ void AccessorAssembler::OverwriteExistingFastDataProperty(
|
||||
BIND(&if_descriptor);
|
||||
{
|
||||
// Check that constant matches value.
|
||||
Node* constant = LoadValueByKeyIndex<DescriptorArray>(
|
||||
descriptors, descriptor_name_index);
|
||||
Node* constant = LoadValueByKeyIndex(
|
||||
CAST(descriptors), UncheckedCast<IntPtrT>(descriptor_name_index));
|
||||
GotoIf(WordNotEqual(value, constant), slow);
|
||||
|
||||
if (do_transitioning_store) {
|
||||
@ -1517,12 +1528,13 @@ Node* AccessorAssembler::PrepareValueForStore(Node* handler_word, Node* holder,
|
||||
&done);
|
||||
}
|
||||
Node* descriptor = DecodeWord<StoreHandler::DescriptorBits>(handler_word);
|
||||
Node* maybe_field_type = LoadDescriptorValue(LoadMap(holder), descriptor);
|
||||
TNode<MaybeObject> maybe_field_type =
|
||||
LoadDescriptorValueOrFieldType(LoadMap(holder), descriptor);
|
||||
|
||||
GotoIf(TaggedIsSmi(maybe_field_type), &done);
|
||||
// Check that value type matches the field type.
|
||||
{
|
||||
Node* field_type = LoadWeakCellValue(maybe_field_type, bailout);
|
||||
Node* field_type = ToWeakHeapObject(maybe_field_type, bailout);
|
||||
Branch(WordEqual(LoadMap(value), field_type), &done, bailout);
|
||||
}
|
||||
BIND(&done);
|
||||
@ -2070,7 +2082,7 @@ void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map,
|
||||
|
||||
// Try looking up the property on the receiver; if unsuccessful, look
|
||||
// for a handler in the stub cache.
|
||||
Node* descriptors = LoadMapDescriptors(receiver_map);
|
||||
TNode<DescriptorArray> descriptors = LoadMapDescriptors(receiver_map);
|
||||
|
||||
Label if_descriptor_found(this), stub_cache(this);
|
||||
TVARIABLE(IntPtrT, var_name_index);
|
||||
|
@ -123,8 +123,8 @@ class AccessorAssembler : public CodeStubAssembler {
|
||||
Label* slow,
|
||||
bool do_transitioning_store);
|
||||
|
||||
void CheckFieldType(Node* descriptors, Node* name_index, Node* representation,
|
||||
Node* value, Label* bailout);
|
||||
void CheckFieldType(TNode<DescriptorArray> descriptors, Node* name_index,
|
||||
Node* representation, Node* value, Label* bailout);
|
||||
|
||||
private:
|
||||
// Stub generation entry points.
|
||||
@ -137,7 +137,9 @@ class AccessorAssembler : public CodeStubAssembler {
|
||||
TVariable<MaybeObject>* var_handler, Label* if_handler,
|
||||
Label* miss, ExitPoint* exit_point);
|
||||
|
||||
Node* LoadDescriptorValue(Node* map, Node* descriptor);
|
||||
TNode<Object> LoadDescriptorValue(Node* map, Node* descriptor);
|
||||
TNode<MaybeObject> LoadDescriptorValueOrFieldType(Node* map,
|
||||
Node* descriptor);
|
||||
|
||||
void LoadIC_Uninitialized(const LoadICParameters* p);
|
||||
|
||||
|
@ -262,8 +262,8 @@ void KeyedStoreGenericAssembler::StoreElementWithCapacity(
|
||||
// The length property is non-configurable, so it's guaranteed to always
|
||||
// be the first property.
|
||||
TNode<DescriptorArray> descriptors = LoadMapDescriptors(receiver_map);
|
||||
TNode<Int32T> details = LoadAndUntagToWord32FixedArrayElement(
|
||||
descriptors, DescriptorArray::ToDetailsIndex(0));
|
||||
TNode<Uint32T> details = LoadDetailsByKeyIndex(
|
||||
descriptors, IntPtrConstant(DescriptorArray::ToKeyIndex(0)));
|
||||
GotoIf(IsSetWord32(details, PropertyDetails::kAttributesReadOnlyMask),
|
||||
slow);
|
||||
}
|
||||
@ -573,10 +573,9 @@ void KeyedStoreGenericAssembler::LookupPropertyOnPrototypeChain(
|
||||
&var_entry, &next_proto, bailout);
|
||||
BIND(&found_fast);
|
||||
{
|
||||
Node* descriptors = var_meta_storage.value();
|
||||
Node* name_index = var_entry.value();
|
||||
Node* details =
|
||||
LoadDetailsByKeyIndex<DescriptorArray>(descriptors, name_index);
|
||||
TNode<DescriptorArray> descriptors = CAST(var_meta_storage.value());
|
||||
TNode<IntPtrT> name_index = var_entry.value();
|
||||
Node* details = LoadDetailsByKeyIndex(descriptors, name_index);
|
||||
JumpIfDataProperty(details, &ok_to_write, readonly);
|
||||
|
||||
// Accessor case.
|
||||
@ -651,7 +650,7 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore(
|
||||
BIND(&fast_properties);
|
||||
{
|
||||
Comment("fast property store");
|
||||
Node* descriptors = LoadMapDescriptors(receiver_map);
|
||||
TNode<DescriptorArray> descriptors = LoadMapDescriptors(receiver_map);
|
||||
Label descriptor_found(this), lookup_transition(this);
|
||||
TVARIABLE(IntPtrT, var_name_index);
|
||||
DescriptorLookup(p->name, descriptors, bitfield3, &descriptor_found,
|
||||
@ -659,9 +658,8 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore(
|
||||
|
||||
BIND(&descriptor_found);
|
||||
{
|
||||
Node* name_index = var_name_index.value();
|
||||
Node* details =
|
||||
LoadDetailsByKeyIndex<DescriptorArray>(descriptors, name_index);
|
||||
TNode<IntPtrT> name_index = var_name_index.value();
|
||||
Node* details = LoadDetailsByKeyIndex(descriptors, name_index);
|
||||
Label data_property(this);
|
||||
JumpIfDataProperty(details, &data_property, &readonly);
|
||||
|
||||
|
@ -591,7 +591,7 @@ int CollectOwnPropertyNamesInternal(Handle<JSObject> object,
|
||||
|
||||
if (filter & ONLY_ALL_CAN_READ) {
|
||||
if (details.kind() != kAccessor) continue;
|
||||
Object* accessors = descs->GetValue(i);
|
||||
Object* accessors = descs->GetStrongValue(i);
|
||||
if (!accessors->IsAccessorInfo()) continue;
|
||||
if (!AccessorInfo::cast(accessors)->all_can_read()) continue;
|
||||
}
|
||||
|
@ -834,7 +834,7 @@ Handle<Object> LookupIterator::FetchValue() const {
|
||||
return JSObject::FastPropertyAt(holder, property_details_.representation(),
|
||||
field_index);
|
||||
} else {
|
||||
result = holder_->map()->instance_descriptors()->GetValue(number_);
|
||||
result = holder_->map()->instance_descriptors()->GetStrongValue(number_);
|
||||
}
|
||||
return handle(result, isolate_);
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ Object* MapUpdater::GetValue(int descriptor) const {
|
||||
return *new_value_;
|
||||
}
|
||||
DCHECK_EQ(kDescriptor, GetDetails(descriptor).location());
|
||||
return old_descriptors_->GetValue(descriptor);
|
||||
return old_descriptors_->GetStrongValue(descriptor);
|
||||
}
|
||||
|
||||
FieldType* MapUpdater::GetFieldType(int descriptor) const {
|
||||
@ -78,7 +78,7 @@ Handle<FieldType> MapUpdater::GetOrComputeFieldType(
|
||||
if (location == kField) {
|
||||
return handle(descriptors->GetFieldType(descriptor), isolate_);
|
||||
} else {
|
||||
return descriptors->GetValue(descriptor)
|
||||
return descriptors->GetStrongValue(descriptor)
|
||||
->OptimalType(isolate_, representation);
|
||||
}
|
||||
}
|
||||
@ -321,7 +321,8 @@ MapUpdater::State MapUpdater::FindTargetMap() {
|
||||
DCHECK_EQ(old_details.kind(), tmp_details.kind());
|
||||
DCHECK_EQ(old_details.attributes(), tmp_details.attributes());
|
||||
if (old_details.kind() == kAccessor &&
|
||||
!EqualImmutableValues(GetValue(i), tmp_descriptors->GetValue(i))) {
|
||||
!EqualImmutableValues(GetValue(i),
|
||||
tmp_descriptors->GetStrongValue(i))) {
|
||||
// TODO(ishell): mutable accessors are not implemented yet.
|
||||
return CopyGeneralizeAllFields("GenAll_Incompatible");
|
||||
}
|
||||
@ -347,7 +348,8 @@ MapUpdater::State MapUpdater::FindTargetMap() {
|
||||
old_field_type);
|
||||
} else {
|
||||
// kDescriptor: Check that the value matches.
|
||||
if (!EqualImmutableValues(GetValue(i), tmp_descriptors->GetValue(i))) {
|
||||
if (!EqualImmutableValues(GetValue(i),
|
||||
tmp_descriptors->GetStrongValue(i))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -374,8 +376,9 @@ MapUpdater::State MapUpdater::FindTargetMap() {
|
||||
target_descriptors->GetFieldType(modified_descriptor_)));
|
||||
} else {
|
||||
DCHECK(details.location() == kField ||
|
||||
EqualImmutableValues(*new_value_, target_descriptors->GetValue(
|
||||
modified_descriptor_)));
|
||||
EqualImmutableValues(
|
||||
*new_value_,
|
||||
target_descriptors->GetStrongValue(modified_descriptor_)));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -404,7 +407,8 @@ MapUpdater::State MapUpdater::FindTargetMap() {
|
||||
DCHECK_EQ(old_details.attributes(), tmp_details.attributes());
|
||||
#endif
|
||||
if (old_details.kind() == kAccessor &&
|
||||
!EqualImmutableValues(GetValue(i), tmp_descriptors->GetValue(i))) {
|
||||
!EqualImmutableValues(GetValue(i),
|
||||
tmp_descriptors->GetStrongValue(i))) {
|
||||
return CopyGeneralizeAllFields("GenAll_Incompatible");
|
||||
}
|
||||
DCHECK(!tmp_map->is_deprecated());
|
||||
@ -447,7 +451,8 @@ Handle<DescriptorArray> MapUpdater::BuildDescriptorArray() {
|
||||
current_offset += old_details.field_width_in_words();
|
||||
}
|
||||
Descriptor d(handle(GetKey(i), isolate_),
|
||||
handle(old_descriptors_->GetValue(i), isolate_), old_details);
|
||||
MaybeObjectHandle(old_descriptors_->GetValue(i), isolate_),
|
||||
old_details);
|
||||
new_descriptors->Set(i, &d);
|
||||
}
|
||||
|
||||
@ -471,7 +476,7 @@ Handle<DescriptorArray> MapUpdater::BuildDescriptorArray() {
|
||||
PropertyLocation next_location =
|
||||
old_details.location() == kField ||
|
||||
target_details.location() == kField ||
|
||||
!EqualImmutableValues(target_descriptors->GetValue(i),
|
||||
!EqualImmutableValues(target_descriptors->GetStrongValue(i),
|
||||
GetValue(i))
|
||||
? kField
|
||||
: kDescriptor;
|
||||
@ -503,7 +508,7 @@ Handle<DescriptorArray> MapUpdater::BuildDescriptorArray() {
|
||||
isolate_, instance_type, &next_constness, &next_representation,
|
||||
&next_field_type);
|
||||
|
||||
Handle<Object> wrapped_type(Map::WrapFieldType(next_field_type));
|
||||
MaybeObjectHandle wrapped_type(Map::WrapFieldType(next_field_type));
|
||||
Descriptor d;
|
||||
if (next_kind == kData) {
|
||||
d = Descriptor::DataField(key, current_offset, next_attributes,
|
||||
@ -556,7 +561,7 @@ Handle<DescriptorArray> MapUpdater::BuildDescriptorArray() {
|
||||
!Map::IsInplaceGeneralizableField(
|
||||
next_constness, next_representation, *next_field_type));
|
||||
|
||||
Handle<Object> wrapped_type(Map::WrapFieldType(next_field_type));
|
||||
MaybeObjectHandle wrapped_type(Map::WrapFieldType(next_field_type));
|
||||
Descriptor d;
|
||||
if (next_kind == kData) {
|
||||
DCHECK_IMPLIES(!FLAG_track_constant_fields,
|
||||
@ -616,8 +621,8 @@ Handle<Map> MapUpdater::FindSplitMap(Handle<DescriptorArray> descriptors) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (!EqualImmutableValues(descriptors->GetValue(i),
|
||||
next_descriptors->GetValue(i))) {
|
||||
if (!EqualImmutableValues(descriptors->GetStrongValue(i),
|
||||
next_descriptors->GetStrongValue(i))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -665,15 +670,15 @@ MapUpdater::State MapUpdater::ConstructNewMap() {
|
||||
old_field_type = handle(
|
||||
old_descriptors_->GetFieldType(modified_descriptor_), isolate_);
|
||||
} else {
|
||||
old_value =
|
||||
handle(old_descriptors_->GetValue(modified_descriptor_), isolate_);
|
||||
old_value = handle(old_descriptors_->GetStrongValue(modified_descriptor_),
|
||||
isolate_);
|
||||
}
|
||||
if (new_details.location() == kField) {
|
||||
new_field_type =
|
||||
handle(new_descriptors->GetFieldType(modified_descriptor_), isolate_);
|
||||
} else {
|
||||
new_value =
|
||||
handle(new_descriptors->GetValue(modified_descriptor_), isolate_);
|
||||
new_value = handle(new_descriptors->GetStrongValue(modified_descriptor_),
|
||||
isolate_);
|
||||
}
|
||||
|
||||
old_map_->PrintGeneralization(
|
||||
|
@ -658,7 +658,7 @@ void FeedbackMetadata::FeedbackMetadataVerify() {
|
||||
}
|
||||
|
||||
void DescriptorArray::DescriptorArrayVerify() {
|
||||
FixedArrayVerify();
|
||||
WeakFixedArrayVerify();
|
||||
int nof_descriptors = number_of_descriptors();
|
||||
if (number_of_descriptors_storage() == 0) {
|
||||
Heap* heap = GetHeap();
|
||||
@ -673,14 +673,25 @@ void DescriptorArray::DescriptorArrayVerify() {
|
||||
Isolate* isolate = GetIsolate();
|
||||
// Check that properties with private symbols names are non-enumerable.
|
||||
for (int descriptor = 0; descriptor < nof_descriptors; descriptor++) {
|
||||
Object* key = get(ToKeyIndex(descriptor));
|
||||
Object* key = get(ToKeyIndex(descriptor))->ToObject();
|
||||
// number_of_descriptors() may be out of sync with the actual descriptors
|
||||
// written during descriptor array construction.
|
||||
if (key->IsUndefined(isolate)) continue;
|
||||
PropertyDetails details = GetDetails(descriptor);
|
||||
if (Name::cast(key)->IsPrivate()) {
|
||||
PropertyDetails details = GetDetails(descriptor);
|
||||
CHECK_NE(details.attributes() & DONT_ENUM, 0);
|
||||
}
|
||||
MaybeObject* value = get(ToValueIndex(descriptor));
|
||||
HeapObject* heap_object;
|
||||
if (details.location() == kField) {
|
||||
CHECK(value == MaybeObject::FromObject(FieldType::None()) ||
|
||||
value == MaybeObject::FromObject(FieldType::Any()) ||
|
||||
value->IsClearedWeakHeapObject() ||
|
||||
(value->ToWeakHeapObject(&heap_object) && heap_object->IsMap()));
|
||||
} else {
|
||||
CHECK(!value->IsWeakOrClearedHeapObject());
|
||||
CHECK(!value->ToObject()->IsMap());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "src/objects/bigint.h"
|
||||
#include "src/objects/descriptor-array.h"
|
||||
#include "src/objects/literal-objects.h"
|
||||
#include "src/objects/maybe-object-inl.h"
|
||||
#include "src/objects/regexp-match-info.h"
|
||||
#include "src/objects/scope-info.h"
|
||||
#include "src/objects/template-objects.h"
|
||||
@ -1813,7 +1814,7 @@ ACCESSORS(EnumCache, keys, FixedArray, kKeysOffset)
|
||||
ACCESSORS(EnumCache, indices, FixedArray, kIndicesOffset)
|
||||
|
||||
int DescriptorArray::number_of_descriptors() const {
|
||||
return Smi::ToInt(get(kDescriptorLengthIndex));
|
||||
return Smi::ToInt(get(kDescriptorLengthIndex)->ToSmi());
|
||||
}
|
||||
|
||||
int DescriptorArray::number_of_descriptors_storage() const {
|
||||
@ -1826,7 +1827,8 @@ int DescriptorArray::NumberOfSlackDescriptors() const {
|
||||
|
||||
|
||||
void DescriptorArray::SetNumberOfDescriptors(int number_of_descriptors) {
|
||||
set(kDescriptorLengthIndex, Smi::FromInt(number_of_descriptors));
|
||||
set(kDescriptorLengthIndex,
|
||||
MaybeObject::FromObject(Smi::FromInt(number_of_descriptors)));
|
||||
}
|
||||
|
||||
inline int DescriptorArray::number_of_entries() const {
|
||||
@ -1838,7 +1840,7 @@ void DescriptorArray::CopyEnumCacheFrom(DescriptorArray* array) {
|
||||
}
|
||||
|
||||
EnumCache* DescriptorArray::GetEnumCache() {
|
||||
return EnumCache::cast(get(kEnumCacheIndex));
|
||||
return EnumCache::cast(get(kEnumCacheIndex)->ToStrongHeapObject());
|
||||
}
|
||||
|
||||
// Perform a binary search in a fixed array.
|
||||
@ -1970,23 +1972,23 @@ int DescriptorArray::SearchWithCache(Isolate* isolate, Name* name, Map* map) {
|
||||
|
||||
Object** DescriptorArray::GetKeySlot(int descriptor_number) {
|
||||
DCHECK(descriptor_number < number_of_descriptors());
|
||||
return RawFieldOfElementAt(ToKeyIndex(descriptor_number));
|
||||
DCHECK((*RawFieldOfElementAt(ToKeyIndex(descriptor_number)))->IsObject());
|
||||
return reinterpret_cast<Object**>(
|
||||
RawFieldOfElementAt(ToKeyIndex(descriptor_number)));
|
||||
}
|
||||
|
||||
|
||||
Object** DescriptorArray::GetDescriptorStartSlot(int descriptor_number) {
|
||||
return GetKeySlot(descriptor_number);
|
||||
MaybeObject** DescriptorArray::GetDescriptorStartSlot(int descriptor_number) {
|
||||
return reinterpret_cast<MaybeObject**>(GetKeySlot(descriptor_number));
|
||||
}
|
||||
|
||||
|
||||
Object** DescriptorArray::GetDescriptorEndSlot(int descriptor_number) {
|
||||
MaybeObject** DescriptorArray::GetDescriptorEndSlot(int descriptor_number) {
|
||||
return GetValueSlot(descriptor_number - 1) + 1;
|
||||
}
|
||||
|
||||
|
||||
Name* DescriptorArray::GetKey(int descriptor_number) {
|
||||
DCHECK(descriptor_number < number_of_descriptors());
|
||||
return Name::cast(get(ToKeyIndex(descriptor_number)));
|
||||
return Name::cast(get(ToKeyIndex(descriptor_number))->ToStrongHeapObject());
|
||||
}
|
||||
|
||||
|
||||
@ -2002,11 +2004,11 @@ Name* DescriptorArray::GetSortedKey(int descriptor_number) {
|
||||
|
||||
void DescriptorArray::SetSortedKey(int descriptor_index, int pointer) {
|
||||
PropertyDetails details = GetDetails(descriptor_index);
|
||||
set(ToDetailsIndex(descriptor_index), details.set_pointer(pointer).AsSmi());
|
||||
set(ToDetailsIndex(descriptor_index),
|
||||
MaybeObject::FromObject(details.set_pointer(pointer).AsSmi()));
|
||||
}
|
||||
|
||||
|
||||
Object** DescriptorArray::GetValueSlot(int descriptor_number) {
|
||||
MaybeObject** DescriptorArray::GetValueSlot(int descriptor_number) {
|
||||
DCHECK(descriptor_number < number_of_descriptors());
|
||||
return RawFieldOfElementAt(ToValueIndex(descriptor_number));
|
||||
}
|
||||
@ -2016,22 +2018,25 @@ int DescriptorArray::GetValueOffset(int descriptor_number) {
|
||||
return OffsetOfElementAt(ToValueIndex(descriptor_number));
|
||||
}
|
||||
|
||||
|
||||
Object* DescriptorArray::GetValue(int descriptor_number) {
|
||||
Object* DescriptorArray::GetStrongValue(int descriptor_number) {
|
||||
DCHECK(descriptor_number < number_of_descriptors());
|
||||
return get(ToValueIndex(descriptor_number));
|
||||
return get(ToValueIndex(descriptor_number))->ToObject();
|
||||
}
|
||||
|
||||
|
||||
void DescriptorArray::SetValue(int descriptor_index, Object* value) {
|
||||
set(ToValueIndex(descriptor_index), value);
|
||||
set(ToValueIndex(descriptor_index), MaybeObject::FromObject(value));
|
||||
}
|
||||
|
||||
MaybeObject* DescriptorArray::GetValue(int descriptor_number) {
|
||||
DCHECK_LT(descriptor_number, number_of_descriptors());
|
||||
return get(ToValueIndex(descriptor_number));
|
||||
}
|
||||
|
||||
PropertyDetails DescriptorArray::GetDetails(int descriptor_number) {
|
||||
DCHECK(descriptor_number < number_of_descriptors());
|
||||
Object* details = get(ToDetailsIndex(descriptor_number));
|
||||
return PropertyDetails(Smi::cast(details));
|
||||
MaybeObject* details = get(ToDetailsIndex(descriptor_number));
|
||||
return PropertyDetails(details->ToSmi());
|
||||
}
|
||||
|
||||
int DescriptorArray::GetFieldIndex(int descriptor_number) {
|
||||
@ -2041,28 +2046,29 @@ int DescriptorArray::GetFieldIndex(int descriptor_number) {
|
||||
|
||||
FieldType* DescriptorArray::GetFieldType(int descriptor_number) {
|
||||
DCHECK_EQ(GetDetails(descriptor_number).location(), kField);
|
||||
Object* wrapped_type = GetValue(descriptor_number);
|
||||
MaybeObject* wrapped_type = GetValue(descriptor_number);
|
||||
return Map::UnwrapFieldType(wrapped_type);
|
||||
}
|
||||
|
||||
void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
|
||||
desc->Init(handle(GetKey(descriptor_number), GetIsolate()),
|
||||
handle(GetValue(descriptor_number), GetIsolate()),
|
||||
MaybeObjectHandle(GetStrongValue(descriptor_number), GetIsolate()),
|
||||
GetDetails(descriptor_number));
|
||||
}
|
||||
|
||||
void DescriptorArray::Set(int descriptor_number, Name* key, Object* value,
|
||||
void DescriptorArray::Set(int descriptor_number, Name* key, MaybeObject* value,
|
||||
PropertyDetails details) {
|
||||
// Range check.
|
||||
DCHECK(descriptor_number < number_of_descriptors());
|
||||
set(ToKeyIndex(descriptor_number), key);
|
||||
set(ToKeyIndex(descriptor_number), MaybeObject::FromObject(key));
|
||||
set(ToValueIndex(descriptor_number), value);
|
||||
set(ToDetailsIndex(descriptor_number), details.AsSmi());
|
||||
set(ToDetailsIndex(descriptor_number),
|
||||
MaybeObject::FromObject(details.AsSmi()));
|
||||
}
|
||||
|
||||
void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
|
||||
Name* key = *desc->GetKey();
|
||||
Object* value = *desc->GetValue();
|
||||
MaybeObject* value = *desc->GetValue();
|
||||
Set(descriptor_number, key, value, desc->GetDetails());
|
||||
}
|
||||
|
||||
@ -2093,6 +2099,14 @@ void DescriptorArray::SwapSortedKeys(int first, int second) {
|
||||
SetSortedKey(second, first_key);
|
||||
}
|
||||
|
||||
MaybeObject* DescriptorArray::get(int index) const {
|
||||
return WeakFixedArray::Get(index);
|
||||
}
|
||||
|
||||
void DescriptorArray::set(int index, MaybeObject* value) {
|
||||
WeakFixedArray::Set(index, value);
|
||||
}
|
||||
|
||||
bool StringSetShape::IsMatch(String* key, Object* value) {
|
||||
DCHECK(value->IsString());
|
||||
return key->Equals(String::cast(value));
|
||||
|
@ -374,7 +374,7 @@ bool JSObject::PrintProperties(std::ostream& os) { // NOLINT
|
||||
break;
|
||||
}
|
||||
case kDescriptor:
|
||||
os << Brief(descs->GetValue(i));
|
||||
os << Brief(descs->GetStrongValue(i));
|
||||
break;
|
||||
}
|
||||
os << " ";
|
||||
@ -2176,14 +2176,14 @@ void DescriptorArray::PrintDescriptorDetails(std::ostream& os, int descriptor,
|
||||
PropertyDetails details = GetDetails(descriptor);
|
||||
details.PrintAsFastTo(os, mode);
|
||||
os << " @ ";
|
||||
Object* value = GetValue(descriptor);
|
||||
switch (details.location()) {
|
||||
case kField: {
|
||||
FieldType* field_type = Map::UnwrapFieldType(value);
|
||||
FieldType* field_type = GetFieldType(descriptor);
|
||||
field_type->PrintTo(os);
|
||||
break;
|
||||
}
|
||||
case kDescriptor:
|
||||
Object* value = GetStrongValue(descriptor);
|
||||
os << Brief(value);
|
||||
if (value->IsAccessorPair()) {
|
||||
AccessorPair* pair = AccessorPair::cast(value);
|
||||
|
@ -2123,7 +2123,7 @@ V8_WARN_UNUSED_RESULT Maybe<bool> FastAssign(
|
||||
if (!details.IsEnumerable()) continue;
|
||||
if (details.kind() == kData) {
|
||||
if (details.location() == kDescriptor) {
|
||||
prop_value = handle(descriptors->GetValue(i), isolate);
|
||||
prop_value = handle(descriptors->GetStrongValue(i), isolate);
|
||||
} else {
|
||||
Representation representation = details.representation();
|
||||
FieldIndex index = FieldIndex::ForDescriptor(*map, i);
|
||||
@ -2979,7 +2979,6 @@ VisitorId Map::GetVisitorId(Map* map) {
|
||||
case FIXED_ARRAY_TYPE:
|
||||
case BOILERPLATE_DESCRIPTION_TYPE:
|
||||
case HASH_TABLE_TYPE:
|
||||
case DESCRIPTOR_ARRAY_TYPE:
|
||||
case SCOPE_INFO_TYPE:
|
||||
case BLOCK_CONTEXT_TYPE:
|
||||
case CATCH_CONTEXT_TYPE:
|
||||
@ -2994,6 +2993,7 @@ VisitorId Map::GetVisitorId(Map* map) {
|
||||
|
||||
case WEAK_FIXED_ARRAY_TYPE:
|
||||
case WEAK_ARRAY_LIST_TYPE:
|
||||
case DESCRIPTOR_ARRAY_TYPE:
|
||||
return kVisitWeakArray;
|
||||
|
||||
case FIXED_DOUBLE_ARRAY_TYPE:
|
||||
@ -3739,19 +3739,23 @@ Handle<Context> JSReceiver::GetCreationContext() {
|
||||
}
|
||||
|
||||
// static
|
||||
Handle<Object> Map::WrapFieldType(Handle<FieldType> type) {
|
||||
if (type->IsClass()) return Map::WeakCellForMap(type->AsClass());
|
||||
return type;
|
||||
MaybeObjectHandle Map::WrapFieldType(Handle<FieldType> type) {
|
||||
if (type->IsClass()) {
|
||||
return MaybeObjectHandle::Weak(type->AsClass());
|
||||
}
|
||||
return MaybeObjectHandle(type);
|
||||
}
|
||||
|
||||
// static
|
||||
FieldType* Map::UnwrapFieldType(Object* wrapped_type) {
|
||||
Object* value = wrapped_type;
|
||||
if (value->IsWeakCell()) {
|
||||
if (WeakCell::cast(value)->cleared()) return FieldType::None();
|
||||
value = WeakCell::cast(value)->value();
|
||||
FieldType* Map::UnwrapFieldType(MaybeObject* wrapped_type) {
|
||||
if (wrapped_type->IsClearedWeakHeapObject()) {
|
||||
return FieldType::None();
|
||||
}
|
||||
return FieldType::cast(value);
|
||||
HeapObject* heap_object;
|
||||
if (wrapped_type->ToWeakHeapObject(&heap_object)) {
|
||||
return FieldType::cast(heap_object);
|
||||
}
|
||||
return FieldType::cast(wrapped_type->ToObject());
|
||||
}
|
||||
|
||||
MaybeHandle<Map> Map::CopyWithField(Handle<Map> map, Handle<Name> name,
|
||||
@ -3783,7 +3787,7 @@ MaybeHandle<Map> Map::CopyWithField(Handle<Map> map, Handle<Name> name,
|
||||
isolate, map->instance_type(), &constness, &representation, &type);
|
||||
}
|
||||
|
||||
Handle<Object> wrapped_type(WrapFieldType(type));
|
||||
MaybeObjectHandle wrapped_type = WrapFieldType(type);
|
||||
|
||||
DCHECK_IMPLIES(!FLAG_track_constant_fields,
|
||||
constness == PropertyConstness::kMutable);
|
||||
@ -4068,7 +4072,7 @@ void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
|
||||
}
|
||||
} else {
|
||||
DCHECK_EQ(kData, old_details.kind());
|
||||
value = handle(old_descriptors->GetValue(i), isolate);
|
||||
value = handle(old_descriptors->GetStrongValue(i), isolate);
|
||||
DCHECK(!old_representation.IsDouble() && !representation.IsDouble());
|
||||
}
|
||||
} else {
|
||||
@ -4223,7 +4227,7 @@ void MigrateFastToSlow(Handle<JSObject> object, Handle<Map> new_map,
|
||||
|
||||
} else {
|
||||
DCHECK_EQ(kDescriptor, details.location());
|
||||
value = handle(descs->GetValue(i), isolate);
|
||||
value = handle(descs->GetStrongValue(i), isolate);
|
||||
}
|
||||
DCHECK(!value.is_null());
|
||||
PropertyDetails d(details.kind(), details.attributes(),
|
||||
@ -4374,7 +4378,7 @@ void DescriptorArray::GeneralizeAllFields() {
|
||||
details = details.CopyWithConstness(PropertyConstness::kMutable);
|
||||
SetValue(i, FieldType::Any());
|
||||
}
|
||||
set(ToDetailsIndex(i), details.AsSmi());
|
||||
set(ToDetailsIndex(i), MaybeObject::FromObject(details.AsSmi()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -4513,8 +4517,8 @@ Map* Map::FindFieldOwner(int descriptor) const {
|
||||
void Map::UpdateFieldType(int descriptor, Handle<Name> name,
|
||||
PropertyConstness new_constness,
|
||||
Representation new_representation,
|
||||
Handle<Object> new_wrapped_type) {
|
||||
DCHECK(new_wrapped_type->IsSmi() || new_wrapped_type->IsWeakCell());
|
||||
MaybeObjectHandle new_wrapped_type) {
|
||||
DCHECK(new_wrapped_type->IsSmi() || new_wrapped_type->IsWeakHeapObject());
|
||||
// We store raw pointers in the queue, so no allocations are allowed.
|
||||
DisallowHeapAllocation no_allocation;
|
||||
PropertyDetails details = instance_descriptors()->GetDetails(descriptor);
|
||||
@ -4548,7 +4552,7 @@ void Map::UpdateFieldType(int descriptor, Handle<Name> name,
|
||||
|
||||
// Skip if already updated the shared descriptor.
|
||||
if ((FLAG_modify_map_inplace && new_constness != details.constness()) ||
|
||||
descriptors->GetValue(descriptor) != *new_wrapped_type) {
|
||||
descriptors->GetFieldType(descriptor) != *new_wrapped_type.object()) {
|
||||
DCHECK_IMPLIES(!FLAG_track_constant_fields,
|
||||
new_constness == PropertyConstness::kMutable);
|
||||
Descriptor d = Descriptor::DataField(
|
||||
@ -4628,7 +4632,7 @@ void Map::GeneralizeField(Handle<Map> map, int modify_index,
|
||||
PropertyDetails details = descriptors->GetDetails(modify_index);
|
||||
Handle<Name> name(descriptors->GetKey(modify_index));
|
||||
|
||||
Handle<Object> wrapped_type(WrapFieldType(new_field_type));
|
||||
MaybeObjectHandle wrapped_type(WrapFieldType(new_field_type));
|
||||
field_owner->UpdateFieldType(modify_index, name, new_constness,
|
||||
new_representation, wrapped_type);
|
||||
field_owner->dependent_code()->DeoptimizeDependentCodeGroup(
|
||||
@ -4767,7 +4771,7 @@ Map* Map::TryReplayPropertyTransitions(Map* old_map) {
|
||||
} else {
|
||||
DCHECK_EQ(kDescriptor, old_details.location());
|
||||
DCHECK(!FLAG_track_constant_fields);
|
||||
Object* old_value = old_descriptors->GetValue(i);
|
||||
Object* old_value = old_descriptors->GetStrongValue(i);
|
||||
if (!new_type->NowContains(old_value)) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -4783,9 +4787,9 @@ Map* Map::TryReplayPropertyTransitions(Map* old_map) {
|
||||
}
|
||||
} else {
|
||||
DCHECK_EQ(kDescriptor, new_details.location());
|
||||
Object* old_value = old_descriptors->GetValue(i);
|
||||
Object* new_value = new_descriptors->GetValue(i);
|
||||
if (old_details.location() == kField || old_value != new_value) {
|
||||
if (old_details.location() == kField ||
|
||||
old_descriptors->GetStrongValue(i) !=
|
||||
new_descriptors->GetStrongValue(i)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@ -6386,7 +6390,8 @@ void JSObject::MigrateSlowToFast(Handle<JSObject> object,
|
||||
d = Descriptor::DataField(
|
||||
key, current_offset, details.attributes(), constness,
|
||||
// TODO(verwaest): value->OptimalRepresentation();
|
||||
Representation::Tagged(), FieldType::Any(isolate));
|
||||
Representation::Tagged(),
|
||||
MaybeObjectHandle(FieldType::Any(isolate)));
|
||||
}
|
||||
} else {
|
||||
DCHECK_EQ(kAccessor, details.kind());
|
||||
@ -8795,7 +8800,7 @@ V8_WARN_UNUSED_RESULT Maybe<bool> FastGetOwnValuesOrEntries(
|
||||
if (!details.IsEnumerable()) continue;
|
||||
if (details.kind() == kData) {
|
||||
if (details.location() == kDescriptor) {
|
||||
prop_value = handle(descriptors->GetValue(index), isolate);
|
||||
prop_value = handle(descriptors->GetStrongValue(index), isolate);
|
||||
} else {
|
||||
Representation representation = details.representation();
|
||||
FieldIndex field_index = FieldIndex::ForDescriptor(*map, index);
|
||||
@ -9064,7 +9069,7 @@ Object* JSObject::SlowReverseLookup(Object* value) {
|
||||
} else {
|
||||
DCHECK_EQ(kDescriptor, details.location());
|
||||
if (details.kind() == kData) {
|
||||
if (descs->GetValue(i) == value) {
|
||||
if (descs->GetStrongValue(i) == value) {
|
||||
return descs->GetKey(i);
|
||||
}
|
||||
}
|
||||
@ -9693,9 +9698,9 @@ bool CanHoldValue(DescriptorArray* descriptors, int descriptor,
|
||||
DCHECK_EQ(PropertyConstness::kConst, details.constness());
|
||||
if (details.kind() == kData) {
|
||||
DCHECK(!FLAG_track_constant_fields);
|
||||
DCHECK(descriptors->GetValue(descriptor) != value ||
|
||||
DCHECK(descriptors->GetStrongValue(descriptor) != value ||
|
||||
value->FitsRepresentation(details.representation()));
|
||||
return descriptors->GetValue(descriptor) == value;
|
||||
return descriptors->GetStrongValue(descriptor) == value;
|
||||
} else {
|
||||
DCHECK_EQ(kAccessor, details.kind());
|
||||
return false;
|
||||
@ -9886,7 +9891,7 @@ Handle<Map> Map::TransitionToAccessorProperty(Isolate* isolate, Handle<Map> map,
|
||||
DCHECK_EQ(kAccessor, descriptors->GetDetails(descriptor).kind());
|
||||
DCHECK_EQ(attributes, descriptors->GetDetails(descriptor).attributes());
|
||||
|
||||
Handle<Object> maybe_pair(descriptors->GetValue(descriptor), isolate);
|
||||
Handle<Object> maybe_pair(descriptors->GetStrongValue(descriptor), isolate);
|
||||
if (!maybe_pair->IsAccessorPair()) {
|
||||
return Map::Normalize(map, mode, "TransitionToAccessorFromNonPair");
|
||||
}
|
||||
@ -9914,7 +9919,8 @@ Handle<Map> Map::TransitionToAccessorProperty(Isolate* isolate, Handle<Map> map,
|
||||
return Map::Normalize(map, mode, "AccessorsWithAttributes");
|
||||
}
|
||||
|
||||
Handle<Object> maybe_pair(old_descriptors->GetValue(descriptor), isolate);
|
||||
Handle<Object> maybe_pair(old_descriptors->GetStrongValue(descriptor),
|
||||
isolate);
|
||||
if (!maybe_pair->IsAccessorPair()) {
|
||||
return Map::Normalize(map, mode, "AccessorsOverwritingNonPair");
|
||||
}
|
||||
@ -10021,20 +10027,23 @@ Handle<DescriptorArray> DescriptorArray::CopyUpToAddAttributes(
|
||||
|
||||
if (attributes != NONE) {
|
||||
for (int i = 0; i < size; ++i) {
|
||||
Object* value = desc->GetValue(i);
|
||||
MaybeObject* value_or_field_type = desc->GetValue(i);
|
||||
Name* key = desc->GetKey(i);
|
||||
PropertyDetails details = desc->GetDetails(i);
|
||||
// Bulk attribute changes never affect private properties.
|
||||
if (!key->IsPrivate()) {
|
||||
int mask = DONT_DELETE | DONT_ENUM;
|
||||
// READ_ONLY is an invalid attribute for JS setters/getters.
|
||||
if (details.kind() != kAccessor || !value->IsAccessorPair()) {
|
||||
HeapObject* heap_object;
|
||||
if (details.kind() != kAccessor ||
|
||||
!(value_or_field_type->ToStrongHeapObject(&heap_object) &&
|
||||
heap_object->IsAccessorPair())) {
|
||||
mask |= READ_ONLY;
|
||||
}
|
||||
details = details.CopyAddAttributes(
|
||||
static_cast<PropertyAttributes>(attributes & mask));
|
||||
}
|
||||
descriptors->Set(i, key, value, details);
|
||||
descriptors->Set(i, key, value_or_field_type, details);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < size; ++i) {
|
||||
@ -10462,15 +10471,18 @@ Handle<DescriptorArray> DescriptorArray::Allocate(Isolate* isolate,
|
||||
int size = number_of_descriptors + slack;
|
||||
if (size == 0) return factory->empty_descriptor_array();
|
||||
// Allocate the array of keys.
|
||||
Handle<FixedArray> result = factory->NewFixedArrayWithMap(
|
||||
Heap::kDescriptorArrayMapRootIndex, LengthFor(size), pretenure);
|
||||
result->set(kDescriptorLengthIndex, Smi::FromInt(number_of_descriptors));
|
||||
result->set(kEnumCacheIndex, isolate->heap()->empty_enum_cache());
|
||||
Handle<WeakFixedArray> result =
|
||||
factory->NewWeakFixedArrayWithMap<DescriptorArray>(
|
||||
Heap::kDescriptorArrayMapRootIndex, LengthFor(size), pretenure);
|
||||
result->Set(kDescriptorLengthIndex,
|
||||
MaybeObject::FromObject(Smi::FromInt(number_of_descriptors)));
|
||||
result->Set(kEnumCacheIndex,
|
||||
MaybeObject::FromObject(isolate->heap()->empty_enum_cache()));
|
||||
return Handle<DescriptorArray>::cast(result);
|
||||
}
|
||||
|
||||
void DescriptorArray::ClearEnumCache() {
|
||||
set(kEnumCacheIndex, GetHeap()->empty_enum_cache());
|
||||
set(kEnumCacheIndex, MaybeObject::FromObject(GetHeap()->empty_enum_cache()));
|
||||
}
|
||||
|
||||
void DescriptorArray::Replace(int index, Descriptor* descriptor) {
|
||||
@ -10485,7 +10497,7 @@ void DescriptorArray::SetEnumCache(Handle<DescriptorArray> descriptors,
|
||||
EnumCache* enum_cache = descriptors->GetEnumCache();
|
||||
if (enum_cache == isolate->heap()->empty_enum_cache()) {
|
||||
enum_cache = *isolate->factory()->NewEnumCache(keys, indices);
|
||||
descriptors->set(kEnumCacheIndex, enum_cache);
|
||||
descriptors->set(kEnumCacheIndex, MaybeObject::FromObject(enum_cache));
|
||||
} else {
|
||||
enum_cache->set_keys(*keys);
|
||||
enum_cache->set_indices(*indices);
|
||||
|
@ -415,7 +415,6 @@ const int kStubMinorKeyBits = kSmiValueSize - kStubMajorKeyBits - 1;
|
||||
\
|
||||
V(FIXED_ARRAY_TYPE) \
|
||||
V(BOILERPLATE_DESCRIPTION_TYPE) \
|
||||
V(DESCRIPTOR_ARRAY_TYPE) \
|
||||
V(HASH_TABLE_TYPE) \
|
||||
V(SCOPE_INFO_TYPE) \
|
||||
\
|
||||
@ -430,6 +429,7 @@ const int kStubMinorKeyBits = kSmiValueSize - kStubMajorKeyBits - 1;
|
||||
V(WITH_CONTEXT_TYPE) \
|
||||
\
|
||||
V(WEAK_FIXED_ARRAY_TYPE) \
|
||||
V(DESCRIPTOR_ARRAY_TYPE) \
|
||||
V(TRANSITION_ARRAY_TYPE) \
|
||||
\
|
||||
V(CALL_HANDLER_INFO_TYPE) \
|
||||
@ -798,7 +798,6 @@ enum InstanceType : uint16_t {
|
||||
// FixedArrays.
|
||||
FIXED_ARRAY_TYPE, // FIRST_FIXED_ARRAY_TYPE
|
||||
BOILERPLATE_DESCRIPTION_TYPE,
|
||||
DESCRIPTOR_ARRAY_TYPE,
|
||||
HASH_TABLE_TYPE,
|
||||
SCOPE_INFO_TYPE,
|
||||
BLOCK_CONTEXT_TYPE, // FIRST_CONTEXT_TYPE
|
||||
@ -812,6 +811,7 @@ enum InstanceType : uint16_t {
|
||||
WITH_CONTEXT_TYPE, // LAST_FIXED_ARRAY_TYPE, LAST_CONTEXT_TYPE
|
||||
|
||||
WEAK_FIXED_ARRAY_TYPE, // FIRST_WEAK_FIXED_ARRAY_TYPE
|
||||
DESCRIPTOR_ARRAY_TYPE,
|
||||
TRANSITION_ARRAY_TYPE, // LAST_WEAK_FIXED_ARRAY_TYPE
|
||||
|
||||
// Misc.
|
||||
|
@ -44,7 +44,10 @@ class EnumCache : public Tuple2 {
|
||||
// [4]: first value for constants | Smi(1) when not used
|
||||
//
|
||||
// [2 + number of descriptors * 3]: start of slack
|
||||
class DescriptorArray : public FixedArray {
|
||||
// The "value" fields store either values or field types. A field type is either
|
||||
// FieldType::None(), FieldType::Any() or a weak reference to a Map. All other
|
||||
// references are strong.
|
||||
class DescriptorArray : public WeakFixedArray {
|
||||
public:
|
||||
// Returns the number of descriptors in the array.
|
||||
inline int number_of_descriptors() const;
|
||||
@ -66,12 +69,13 @@ class DescriptorArray : public FixedArray {
|
||||
// Accessors for fetching instance descriptor at descriptor number.
|
||||
inline Name* GetKey(int descriptor_number);
|
||||
inline Object** GetKeySlot(int descriptor_number);
|
||||
inline Object* GetValue(int descriptor_number);
|
||||
inline Object* GetStrongValue(int descriptor_number);
|
||||
inline void SetValue(int descriptor_number, Object* value);
|
||||
inline Object** GetValueSlot(int descriptor_number);
|
||||
inline MaybeObject* GetValue(int descriptor_number);
|
||||
inline MaybeObject** GetValueSlot(int descriptor_number);
|
||||
static inline int GetValueOffset(int descriptor_number);
|
||||
inline Object** GetDescriptorStartSlot(int descriptor_number);
|
||||
inline Object** GetDescriptorEndSlot(int descriptor_number);
|
||||
inline MaybeObject** GetDescriptorStartSlot(int descriptor_number);
|
||||
inline MaybeObject** GetDescriptorEndSlot(int descriptor_number);
|
||||
inline PropertyDetails GetDetails(int descriptor_number);
|
||||
inline int GetFieldIndex(int descriptor_number);
|
||||
inline FieldType* GetFieldType(int descriptor_number);
|
||||
@ -83,7 +87,7 @@ class DescriptorArray : public FixedArray {
|
||||
// Accessor for complete descriptor.
|
||||
inline void Get(int descriptor_number, Descriptor* desc);
|
||||
inline void Set(int descriptor_number, Descriptor* desc);
|
||||
inline void Set(int descriptor_number, Name* key, Object* value,
|
||||
inline void Set(int descriptor_number, Name* key, MaybeObject* value,
|
||||
PropertyDetails details);
|
||||
void Replace(int descriptor_number, Descriptor* descriptor);
|
||||
|
||||
@ -183,6 +187,9 @@ class DescriptorArray : public FixedArray {
|
||||
}
|
||||
|
||||
private:
|
||||
inline MaybeObject* get(int index) const;
|
||||
inline void set(int index, MaybeObject* value);
|
||||
|
||||
// Transfer a complete descriptor from the src descriptor array to this
|
||||
// descriptor array.
|
||||
void CopyFrom(int index, DescriptorArray* src);
|
||||
|
@ -249,6 +249,11 @@ MaybeObject** WeakFixedArray::RawFieldOfElementAt(int index) {
|
||||
return HeapObject::RawMaybeWeakField(this, OffsetOfElementAt(index));
|
||||
}
|
||||
|
||||
MaybeObject** WeakFixedArray::GetFirstElementAddress() {
|
||||
return reinterpret_cast<MaybeObject**>(
|
||||
FIELD_ADDR(this, OffsetOfElementAt(0)));
|
||||
}
|
||||
|
||||
MaybeObject* WeakArrayList::Get(int index) const {
|
||||
SLOW_DCHECK(index >= 0 && index < this->capacity());
|
||||
return RELAXED_READ_WEAK_FIELD(this, OffsetOfElementAt(index));
|
||||
|
@ -280,6 +280,8 @@ class WeakFixedArray : public HeapObject {
|
||||
|
||||
inline MaybeObject** RawFieldOfElementAt(int index);
|
||||
|
||||
inline MaybeObject** GetFirstElementAddress();
|
||||
|
||||
DECL_PRINTER(WeakFixedArray)
|
||||
DECL_VERIFIER(WeakFixedArray)
|
||||
|
||||
@ -292,11 +294,12 @@ class WeakFixedArray : public HeapObject {
|
||||
static const int kMaxLength =
|
||||
(FixedArray::kMaxSize - kHeaderSize) / kPointerSize;
|
||||
|
||||
private:
|
||||
protected:
|
||||
static int OffsetOfElementAt(int index) {
|
||||
return kHeaderSize + index * kPointerSize;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class Heap;
|
||||
|
||||
static const int kFirstIndex = 1;
|
||||
|
@ -99,7 +99,7 @@ void AddToDescriptorArrayTemplate(
|
||||
} else {
|
||||
DCHECK(value_kind == ClassBoilerplate::kGetter ||
|
||||
value_kind == ClassBoilerplate::kSetter);
|
||||
Object* raw_accessor = descriptor_array_template->GetValue(entry);
|
||||
Object* raw_accessor = descriptor_array_template->GetStrongValue(entry);
|
||||
AccessorPair* pair;
|
||||
if (raw_accessor->IsAccessorPair()) {
|
||||
pair = AccessorPair::cast(raw_accessor);
|
||||
|
@ -648,8 +648,8 @@ class Map : public HeapObject {
|
||||
Descriptor* descriptor,
|
||||
TransitionFlag flag);
|
||||
|
||||
static Handle<Object> WrapFieldType(Handle<FieldType> type);
|
||||
static FieldType* UnwrapFieldType(Object* wrapped_type);
|
||||
static MaybeObjectHandle WrapFieldType(Handle<FieldType> type);
|
||||
static FieldType* UnwrapFieldType(MaybeObject* wrapped_type);
|
||||
|
||||
V8_WARN_UNUSED_RESULT static MaybeHandle<Map> CopyWithField(
|
||||
Handle<Map> map, Handle<Name> name, Handle<FieldType> type,
|
||||
@ -930,7 +930,7 @@ class Map : public HeapObject {
|
||||
void UpdateFieldType(int descriptor_number, Handle<Name> name,
|
||||
PropertyConstness new_constness,
|
||||
Representation new_representation,
|
||||
Handle<Object> new_wrapped_type);
|
||||
MaybeObjectHandle new_wrapped_type);
|
||||
|
||||
// TODO(ishell): Move to MapUpdater.
|
||||
void PrintReconfiguration(FILE* file, int modify_index, PropertyKind kind,
|
||||
|
@ -104,6 +104,8 @@ Object* MaybeObject::GetHeapObjectOrSmi() {
|
||||
return GetHeapObject();
|
||||
}
|
||||
|
||||
bool MaybeObject::IsObject() { return IsSmi() || IsStrongHeapObject(); }
|
||||
|
||||
Object* MaybeObject::ToObject() {
|
||||
DCHECK(!HasWeakHeapObjectTag(this));
|
||||
return reinterpret_cast<Object*>(this);
|
||||
|
@ -43,6 +43,7 @@ class MaybeObject {
|
||||
inline HeapObject* GetHeapObject();
|
||||
inline Object* GetHeapObjectOrSmi();
|
||||
|
||||
inline bool IsObject();
|
||||
inline Object* ToObject();
|
||||
|
||||
static MaybeObject* FromSmi(Smi* smi) {
|
||||
|
@ -1448,7 +1448,7 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, int entry) {
|
||||
case kDescriptor:
|
||||
SetDataOrAccessorPropertyReference(details.kind(), js_obj, entry,
|
||||
descs->GetKey(i),
|
||||
descs->GetValue(i));
|
||||
descs->GetStrongValue(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ bool ToPropertyDescriptorFastPath(Isolate* isolate, Handle<JSReceiver> obj,
|
||||
} else {
|
||||
DCHECK_EQ(kDescriptor, details.location());
|
||||
if (details.kind() == kData) {
|
||||
value = handle(descs->GetValue(i), isolate);
|
||||
value = handle(descs->GetStrongValue(i), isolate);
|
||||
} else {
|
||||
DCHECK_EQ(kAccessor, details.kind());
|
||||
// Bail out to slow path.
|
||||
|
@ -26,15 +26,16 @@ Descriptor Descriptor::DataField(Handle<Name> key, int field_index,
|
||||
PropertyAttributes attributes,
|
||||
Representation representation) {
|
||||
return DataField(key, field_index, attributes, PropertyConstness::kMutable,
|
||||
representation, FieldType::Any(key->GetIsolate()));
|
||||
representation,
|
||||
MaybeObjectHandle(FieldType::Any(key->GetIsolate())));
|
||||
}
|
||||
|
||||
Descriptor Descriptor::DataField(Handle<Name> key, int field_index,
|
||||
PropertyAttributes attributes,
|
||||
PropertyConstness constness,
|
||||
Representation representation,
|
||||
Handle<Object> wrapped_field_type) {
|
||||
DCHECK(wrapped_field_type->IsSmi() || wrapped_field_type->IsWeakCell());
|
||||
MaybeObjectHandle wrapped_field_type) {
|
||||
DCHECK(wrapped_field_type->IsSmi() || wrapped_field_type->IsWeakHeapObject());
|
||||
PropertyDetails details(kData, attributes, kField, constness, representation,
|
||||
field_index);
|
||||
return Descriptor(key, wrapped_field_type, details);
|
||||
@ -44,14 +45,14 @@ Descriptor Descriptor::DataConstant(Handle<Name> key, int field_index,
|
||||
Handle<Object> value,
|
||||
PropertyAttributes attributes) {
|
||||
if (FLAG_track_constant_fields) {
|
||||
Handle<Object> any_type(FieldType::Any(), key->GetIsolate());
|
||||
MaybeObjectHandle any_type(FieldType::Any(), key->GetIsolate());
|
||||
return DataField(key, field_index, attributes, PropertyConstness::kConst,
|
||||
Representation::Tagged(), any_type);
|
||||
|
||||
} else {
|
||||
return Descriptor(key, value, kData, attributes, kDescriptor,
|
||||
PropertyConstness::kConst, value->OptimalRepresentation(),
|
||||
field_index);
|
||||
return Descriptor(key, MaybeObjectHandle(value), kData, attributes,
|
||||
kDescriptor, PropertyConstness::kConst,
|
||||
value->OptimalRepresentation(), field_index);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ class Descriptor final BASE_EMBEDDED {
|
||||
Descriptor() : details_(Smi::kZero) {}
|
||||
|
||||
Handle<Name> GetKey() const { return key_; }
|
||||
Handle<Object> GetValue() const { return value_; }
|
||||
MaybeObjectHandle GetValue() const { return value_; }
|
||||
PropertyDetails GetDetails() const { return details_; }
|
||||
|
||||
void SetSortedKeyIndex(int index) { details_ = details_.set_pointer(index); }
|
||||
@ -39,13 +39,13 @@ class Descriptor final BASE_EMBEDDED {
|
||||
PropertyAttributes attributes,
|
||||
PropertyConstness constness,
|
||||
Representation representation,
|
||||
Handle<Object> wrapped_field_type);
|
||||
MaybeObjectHandle wrapped_field_type);
|
||||
|
||||
static Descriptor DataConstant(Handle<Name> key, Handle<Object> value,
|
||||
PropertyAttributes attributes) {
|
||||
return Descriptor(key, value, kData, attributes, kDescriptor,
|
||||
PropertyConstness::kConst, value->OptimalRepresentation(),
|
||||
0);
|
||||
return Descriptor(key, MaybeObjectHandle(value), kData, attributes,
|
||||
kDescriptor, PropertyConstness::kConst,
|
||||
value->OptimalRepresentation(), 0);
|
||||
}
|
||||
|
||||
static Descriptor DataConstant(Handle<Name> key, int field_index,
|
||||
@ -54,17 +54,19 @@ class Descriptor final BASE_EMBEDDED {
|
||||
|
||||
static Descriptor AccessorConstant(Handle<Name> key, Handle<Object> foreign,
|
||||
PropertyAttributes attributes) {
|
||||
return Descriptor(key, foreign, kAccessor, attributes, kDescriptor,
|
||||
PropertyConstness::kConst, Representation::Tagged(), 0);
|
||||
return Descriptor(key, MaybeObjectHandle(foreign), kAccessor, attributes,
|
||||
kDescriptor, PropertyConstness::kConst,
|
||||
Representation::Tagged(), 0);
|
||||
}
|
||||
|
||||
private:
|
||||
Handle<Name> key_;
|
||||
Handle<Object> value_;
|
||||
MaybeObjectHandle value_;
|
||||
PropertyDetails details_;
|
||||
|
||||
protected:
|
||||
void Init(Handle<Name> key, Handle<Object> value, PropertyDetails details) {
|
||||
void Init(Handle<Name> key, MaybeObjectHandle value,
|
||||
PropertyDetails details) {
|
||||
DCHECK(key->IsUniqueName());
|
||||
DCHECK_IMPLIES(key->IsPrivate(), !details.IsEnumerable());
|
||||
key_ = key;
|
||||
@ -72,13 +74,13 @@ class Descriptor final BASE_EMBEDDED {
|
||||
details_ = details;
|
||||
}
|
||||
|
||||
Descriptor(Handle<Name> key, Handle<Object> value, PropertyDetails details)
|
||||
Descriptor(Handle<Name> key, MaybeObjectHandle value, PropertyDetails details)
|
||||
: key_(key), value_(value), details_(details) {
|
||||
DCHECK(key->IsUniqueName());
|
||||
DCHECK_IMPLIES(key->IsPrivate(), !details_.IsEnumerable());
|
||||
}
|
||||
|
||||
Descriptor(Handle<Name> key, Handle<Object> value, PropertyKind kind,
|
||||
Descriptor(Handle<Name> key, MaybeObjectHandle value, PropertyKind kind,
|
||||
PropertyAttributes attributes, PropertyLocation location,
|
||||
PropertyConstness constness, Representation representation,
|
||||
int field_index)
|
||||
|
@ -295,7 +295,7 @@ bool AddDescriptorsByTemplate(
|
||||
// Read values from |descriptors_template| and store possibly post-processed
|
||||
// values into "instantiated" |descriptors| array.
|
||||
for (int i = 0; i < nof_descriptors; i++) {
|
||||
Object* value = descriptors_template->GetValue(i);
|
||||
Object* value = descriptors_template->GetStrongValue(i);
|
||||
if (value->IsAccessorPair()) {
|
||||
Handle<AccessorPair> pair =
|
||||
AccessorPair::Copy(handle(AccessorPair::cast(value), isolate));
|
||||
@ -335,7 +335,7 @@ bool AddDescriptorsByTemplate(
|
||||
DCHECK(!details.representation().IsDouble());
|
||||
}
|
||||
DCHECK(value->FitsRepresentation(details.representation()));
|
||||
descriptors->Set(i, name, value, details);
|
||||
descriptors->Set(i, name, MaybeObject::FromObject(value), details);
|
||||
}
|
||||
|
||||
map->InitializeDescriptors(*descriptors,
|
||||
|
@ -267,7 +267,6 @@ class Expectations {
|
||||
Representation expected_representation = representations_[descriptor];
|
||||
if (!details.representation().Equals(expected_representation)) return false;
|
||||
|
||||
Object* value = descriptors->GetValue(descriptor);
|
||||
Object* expected_value = *values_[descriptor];
|
||||
if (details.location() == kField) {
|
||||
if (details.kind() == kData) {
|
||||
@ -278,6 +277,7 @@ class Expectations {
|
||||
UNREACHABLE();
|
||||
}
|
||||
} else {
|
||||
Object* value = descriptors->GetStrongValue(descriptor);
|
||||
// kDescriptor
|
||||
if (details.kind() == kData) {
|
||||
CHECK(!FLAG_track_constant_fields);
|
||||
@ -561,7 +561,8 @@ TEST(ReconfigureAccessorToNonExistingDataFieldHeavy) {
|
||||
Handle<JSObject> obj = Handle<JSObject>::cast(obj_value);
|
||||
|
||||
CHECK_EQ(1, obj->map()->NumberOfOwnDescriptors());
|
||||
CHECK(obj->map()->instance_descriptors()->GetValue(0)->IsAccessorPair());
|
||||
CHECK(
|
||||
obj->map()->instance_descriptors()->GetStrongValue(0)->IsAccessorPair());
|
||||
|
||||
Handle<Object> value(Smi::FromInt(42), isolate);
|
||||
JSObject::SetOwnPropertyIgnoreAttributes(obj, foo_str, value, NONE).Check();
|
||||
|
@ -86,19 +86,19 @@ INSTANCE_TYPES = {
|
||||
182: "PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE",
|
||||
183: "FIXED_ARRAY_TYPE",
|
||||
184: "BOILERPLATE_DESCRIPTION_TYPE",
|
||||
185: "DESCRIPTOR_ARRAY_TYPE",
|
||||
186: "HASH_TABLE_TYPE",
|
||||
187: "SCOPE_INFO_TYPE",
|
||||
188: "BLOCK_CONTEXT_TYPE",
|
||||
189: "CATCH_CONTEXT_TYPE",
|
||||
190: "DEBUG_EVALUATE_CONTEXT_TYPE",
|
||||
191: "EVAL_CONTEXT_TYPE",
|
||||
192: "FUNCTION_CONTEXT_TYPE",
|
||||
193: "MODULE_CONTEXT_TYPE",
|
||||
194: "NATIVE_CONTEXT_TYPE",
|
||||
195: "SCRIPT_CONTEXT_TYPE",
|
||||
196: "WITH_CONTEXT_TYPE",
|
||||
197: "WEAK_FIXED_ARRAY_TYPE",
|
||||
185: "HASH_TABLE_TYPE",
|
||||
186: "SCOPE_INFO_TYPE",
|
||||
187: "BLOCK_CONTEXT_TYPE",
|
||||
188: "CATCH_CONTEXT_TYPE",
|
||||
189: "DEBUG_EVALUATE_CONTEXT_TYPE",
|
||||
190: "EVAL_CONTEXT_TYPE",
|
||||
191: "FUNCTION_CONTEXT_TYPE",
|
||||
192: "MODULE_CONTEXT_TYPE",
|
||||
193: "NATIVE_CONTEXT_TYPE",
|
||||
194: "SCRIPT_CONTEXT_TYPE",
|
||||
195: "WITH_CONTEXT_TYPE",
|
||||
196: "WEAK_FIXED_ARRAY_TYPE",
|
||||
197: "DESCRIPTOR_ARRAY_TYPE",
|
||||
198: "TRANSITION_ARRAY_TYPE",
|
||||
199: "CALL_HANDLER_INFO_TYPE",
|
||||
200: "CELL_TYPE",
|
||||
@ -163,7 +163,7 @@ KNOWN_MAPS = {
|
||||
("RO_SPACE", 0x02201): (138, "FreeSpaceMap"),
|
||||
("RO_SPACE", 0x02259): (132, "MetaMap"),
|
||||
("RO_SPACE", 0x022e1): (131, "NullMap"),
|
||||
("RO_SPACE", 0x02359): (185, "DescriptorArrayMap"),
|
||||
("RO_SPACE", 0x02359): (197, "DescriptorArrayMap"),
|
||||
("RO_SPACE", 0x023c1): (183, "FixedArrayMap"),
|
||||
("RO_SPACE", 0x02429): (211, "WeakCellMap"),
|
||||
("RO_SPACE", 0x024d1): (152, "OnePointerFillerMap"),
|
||||
@ -176,13 +176,13 @@ KNOWN_MAPS = {
|
||||
("RO_SPACE", 0x028f9): (131, "BooleanMap"),
|
||||
("RO_SPACE", 0x02a09): (136, "ByteArrayMap"),
|
||||
("RO_SPACE", 0x02a71): (183, "FixedCOWArrayMap"),
|
||||
("RO_SPACE", 0x02ad9): (186, "HashTableMap"),
|
||||
("RO_SPACE", 0x02ad9): (185, "HashTableMap"),
|
||||
("RO_SPACE", 0x02b41): (128, "SymbolMap"),
|
||||
("RO_SPACE", 0x02ba9): (72, "OneByteStringMap"),
|
||||
("RO_SPACE", 0x02c11): (187, "ScopeInfoMap"),
|
||||
("RO_SPACE", 0x02c11): (186, "ScopeInfoMap"),
|
||||
("RO_SPACE", 0x02c79): (207, "SharedFunctionInfoMap"),
|
||||
("RO_SPACE", 0x02ce1): (133, "CodeMap"),
|
||||
("RO_SPACE", 0x02d49): (192, "FunctionContextMap"),
|
||||
("RO_SPACE", 0x02d49): (191, "FunctionContextMap"),
|
||||
("RO_SPACE", 0x02db1): (200, "CellMap"),
|
||||
("RO_SPACE", 0x02e19): (206, "GlobalPropertyCellMap"),
|
||||
("RO_SPACE", 0x02e81): (135, "ForeignMap"),
|
||||
@ -193,14 +193,14 @@ KNOWN_MAPS = {
|
||||
("RO_SPACE", 0x03179): (131, "TerminationExceptionMap"),
|
||||
("RO_SPACE", 0x03241): (131, "OptimizedOutMap"),
|
||||
("RO_SPACE", 0x03301): (131, "StaleRegisterMap"),
|
||||
("RO_SPACE", 0x03391): (194, "NativeContextMap"),
|
||||
("RO_SPACE", 0x033f9): (193, "ModuleContextMap"),
|
||||
("RO_SPACE", 0x03461): (191, "EvalContextMap"),
|
||||
("RO_SPACE", 0x034c9): (195, "ScriptContextMap"),
|
||||
("RO_SPACE", 0x03531): (188, "BlockContextMap"),
|
||||
("RO_SPACE", 0x03599): (189, "CatchContextMap"),
|
||||
("RO_SPACE", 0x03601): (196, "WithContextMap"),
|
||||
("RO_SPACE", 0x03669): (190, "DebugEvaluateContextMap"),
|
||||
("RO_SPACE", 0x03391): (193, "NativeContextMap"),
|
||||
("RO_SPACE", 0x033f9): (192, "ModuleContextMap"),
|
||||
("RO_SPACE", 0x03461): (190, "EvalContextMap"),
|
||||
("RO_SPACE", 0x034c9): (194, "ScriptContextMap"),
|
||||
("RO_SPACE", 0x03531): (187, "BlockContextMap"),
|
||||
("RO_SPACE", 0x03599): (188, "CatchContextMap"),
|
||||
("RO_SPACE", 0x03601): (195, "WithContextMap"),
|
||||
("RO_SPACE", 0x03669): (189, "DebugEvaluateContextMap"),
|
||||
("RO_SPACE", 0x036d1): (183, "ScriptContextTableMap"),
|
||||
("RO_SPACE", 0x03739): (151, "FeedbackMetadataArrayMap"),
|
||||
("RO_SPACE", 0x037a1): (183, "ArrayListMap"),
|
||||
@ -209,26 +209,26 @@ KNOWN_MAPS = {
|
||||
("RO_SPACE", 0x038d9): (137, "BytecodeArrayMap"),
|
||||
("RO_SPACE", 0x03941): (201, "CodeDataContainerMap"),
|
||||
("RO_SPACE", 0x039a9): (150, "FixedDoubleArrayMap"),
|
||||
("RO_SPACE", 0x03a11): (186, "GlobalDictionaryMap"),
|
||||
("RO_SPACE", 0x03a11): (185, "GlobalDictionaryMap"),
|
||||
("RO_SPACE", 0x03a79): (202, "ManyClosuresCellMap"),
|
||||
("RO_SPACE", 0x03ae1): (183, "ModuleInfoMap"),
|
||||
("RO_SPACE", 0x03b49): (134, "MutableHeapNumberMap"),
|
||||
("RO_SPACE", 0x03bb1): (186, "NameDictionaryMap"),
|
||||
("RO_SPACE", 0x03bb1): (185, "NameDictionaryMap"),
|
||||
("RO_SPACE", 0x03c19): (202, "NoClosuresCellMap"),
|
||||
("RO_SPACE", 0x03c81): (186, "NumberDictionaryMap"),
|
||||
("RO_SPACE", 0x03c81): (185, "NumberDictionaryMap"),
|
||||
("RO_SPACE", 0x03ce9): (202, "OneClosureCellMap"),
|
||||
("RO_SPACE", 0x03d51): (186, "OrderedHashMapMap"),
|
||||
("RO_SPACE", 0x03db9): (186, "OrderedHashSetMap"),
|
||||
("RO_SPACE", 0x03d51): (185, "OrderedHashMapMap"),
|
||||
("RO_SPACE", 0x03db9): (185, "OrderedHashSetMap"),
|
||||
("RO_SPACE", 0x03e21): (205, "PropertyArrayMap"),
|
||||
("RO_SPACE", 0x03e89): (199, "SideEffectCallHandlerInfoMap"),
|
||||
("RO_SPACE", 0x03ef1): (199, "SideEffectFreeCallHandlerInfoMap"),
|
||||
("RO_SPACE", 0x03f59): (199, "NextCallSideEffectFreeCallHandlerInfoMap"),
|
||||
("RO_SPACE", 0x03fc1): (186, "SimpleNumberDictionaryMap"),
|
||||
("RO_SPACE", 0x03fc1): (185, "SimpleNumberDictionaryMap"),
|
||||
("RO_SPACE", 0x04029): (183, "SloppyArgumentsElementsMap"),
|
||||
("RO_SPACE", 0x04091): (208, "SmallOrderedHashMapMap"),
|
||||
("RO_SPACE", 0x040f9): (209, "SmallOrderedHashSetMap"),
|
||||
("RO_SPACE", 0x04161): (186, "StringTableMap"),
|
||||
("RO_SPACE", 0x041c9): (197, "WeakFixedArrayMap"),
|
||||
("RO_SPACE", 0x04161): (185, "StringTableMap"),
|
||||
("RO_SPACE", 0x041c9): (196, "WeakFixedArrayMap"),
|
||||
("RO_SPACE", 0x04231): (212, "WeakArrayListMap"),
|
||||
("RO_SPACE", 0x04299): (106, "NativeSourceStringMap"),
|
||||
("RO_SPACE", 0x04301): (64, "StringMap"),
|
||||
|
Loading…
Reference in New Issue
Block a user