[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:
Marja Hölttä 2018-06-01 10:09:24 +02:00 committed by Commit Bot
parent c6d5b6968f
commit 0f23ceddfb
35 changed files with 368 additions and 255 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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.

View File

@ -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,

View File

@ -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);

View File

@ -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

View File

@ -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();
}

View File

@ -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));
}

View File

@ -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);

View File

@ -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());

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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_);
}

View File

@ -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(

View File

@ -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());
}
}
}
}

View File

@ -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));

View File

@ -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);

View File

@ -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);

View File

@ -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.

View File

@ -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);

View File

@ -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));

View File

@ -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;

View File

@ -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);

View File

@ -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,

View File

@ -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);

View File

@ -43,6 +43,7 @@ class MaybeObject {
inline HeapObject* GetHeapObject();
inline Object* GetHeapObjectOrSmi();
inline bool IsObject();
inline Object* ToObject();
static MaybeObject* FromSmi(Smi* smi) {

View File

@ -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;
}
}

View File

@ -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.

View File

@ -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);
}
}

View File

@ -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)

View File

@ -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,

View File

@ -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();

View File

@ -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"),