Remove UnseededNumberDictionary.
Use (Seeded)NumberDictionary instead. Change-Id: I426cd0a33df7d47fe4fec0c108be5632ef7c0f19 Reviewed-on: https://chromium-review.googlesource.com/756697 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Commit-Queue: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#49179}
This commit is contained in:
parent
8ba5cfd873
commit
6e1c57eaa9
@ -285,10 +285,10 @@ MaybeHandle<JSObject> ProbeInstantiationsCache(Isolate* isolate,
|
||||
} else if (caching_mode == CachingMode::kUnlimited ||
|
||||
(serial_number <=
|
||||
TemplateInfo::kSlowTemplateInstantiationsCacheSize)) {
|
||||
Handle<UnseededNumberDictionary> slow_cache =
|
||||
Handle<NumberDictionary> slow_cache =
|
||||
isolate->slow_template_instantiations_cache();
|
||||
int entry = slow_cache->FindEntry(serial_number);
|
||||
if (entry == UnseededNumberDictionary::kNotFound) {
|
||||
if (entry == NumberDictionary::kNotFound) {
|
||||
return MaybeHandle<JSObject>();
|
||||
}
|
||||
return handle(JSObject::cast(slow_cache->ValueAt(entry)), isolate);
|
||||
@ -313,10 +313,9 @@ void CacheTemplateInstantiation(Isolate* isolate, int serial_number,
|
||||
} else if (caching_mode == CachingMode::kUnlimited ||
|
||||
(serial_number <=
|
||||
TemplateInfo::kSlowTemplateInstantiationsCacheSize)) {
|
||||
Handle<UnseededNumberDictionary> cache =
|
||||
Handle<NumberDictionary> cache =
|
||||
isolate->slow_template_instantiations_cache();
|
||||
auto new_cache =
|
||||
UnseededNumberDictionary::Set(cache, serial_number, object);
|
||||
auto new_cache = NumberDictionary::Set(cache, serial_number, object);
|
||||
if (*new_cache != *cache) {
|
||||
isolate->native_context()->set_slow_template_instantiations_cache(
|
||||
*new_cache);
|
||||
@ -335,11 +334,11 @@ void UncacheTemplateInstantiation(Isolate* isolate, int serial_number,
|
||||
} else if (caching_mode == CachingMode::kUnlimited ||
|
||||
(serial_number <=
|
||||
TemplateInfo::kSlowTemplateInstantiationsCacheSize)) {
|
||||
Handle<UnseededNumberDictionary> cache =
|
||||
Handle<NumberDictionary> cache =
|
||||
isolate->slow_template_instantiations_cache();
|
||||
int entry = cache->FindEntry(serial_number);
|
||||
DCHECK_NE(UnseededNumberDictionary::kNotFound, entry);
|
||||
cache = UnseededNumberDictionary::DeleteEntry(cache, entry);
|
||||
DCHECK_NE(NumberDictionary::kNotFound, entry);
|
||||
cache = NumberDictionary::DeleteEntry(cache, entry);
|
||||
isolate->native_context()->set_slow_template_instantiations_cache(*cache);
|
||||
}
|
||||
}
|
||||
|
@ -4594,8 +4594,8 @@ bool Genesis::InstallNatives(GlobalContextType context_type) {
|
||||
native_context()->set_fast_template_instantiations_cache(
|
||||
*fast_template_instantiations_cache);
|
||||
|
||||
auto slow_template_instantiations_cache = UnseededNumberDictionary::New(
|
||||
isolate(), ApiNatives::kInitialFunctionCacheSize);
|
||||
auto slow_template_instantiations_cache =
|
||||
NumberDictionary::New(isolate(), ApiNatives::kInitialFunctionCacheSize);
|
||||
native_context()->set_slow_template_instantiations_cache(
|
||||
*slow_template_instantiations_cache);
|
||||
|
||||
|
@ -433,13 +433,12 @@ class ArrayConcatVisitor {
|
||||
// Fall-through to dictionary mode.
|
||||
}
|
||||
DCHECK(!fast_elements());
|
||||
Handle<SeededNumberDictionary> dict(
|
||||
SeededNumberDictionary::cast(*storage_));
|
||||
Handle<NumberDictionary> dict(NumberDictionary::cast(*storage_));
|
||||
// The object holding this backing store has just been allocated, so
|
||||
// it cannot yet be used as a prototype.
|
||||
Handle<JSObject> not_a_prototype_holder;
|
||||
Handle<SeededNumberDictionary> result =
|
||||
SeededNumberDictionary::Set(dict, index, elm, not_a_prototype_holder);
|
||||
Handle<NumberDictionary> result =
|
||||
NumberDictionary::Set(dict, index, elm, not_a_prototype_holder);
|
||||
if (!result.is_identical_to(dict)) {
|
||||
// Dictionary needed to grow.
|
||||
clear_storage();
|
||||
@ -502,8 +501,8 @@ class ArrayConcatVisitor {
|
||||
void SetDictionaryMode() {
|
||||
DCHECK(fast_elements() && is_fixed_array());
|
||||
Handle<FixedArray> current_storage = storage_fixed_array();
|
||||
Handle<SeededNumberDictionary> slow_storage(
|
||||
SeededNumberDictionary::New(isolate_, current_storage->length()));
|
||||
Handle<NumberDictionary> slow_storage(
|
||||
NumberDictionary::New(isolate_, current_storage->length()));
|
||||
uint32_t current_length = static_cast<uint32_t>(current_storage->length());
|
||||
FOR_WITH_HANDLE_SCOPE(
|
||||
isolate_, uint32_t, i = 0, i, i < current_length, i++, {
|
||||
@ -512,9 +511,8 @@ class ArrayConcatVisitor {
|
||||
// The object holding this backing store has just been allocated, so
|
||||
// it cannot yet be used as a prototype.
|
||||
Handle<JSObject> not_a_prototype_holder;
|
||||
Handle<SeededNumberDictionary> new_storage =
|
||||
SeededNumberDictionary::Set(slow_storage, i, element,
|
||||
not_a_prototype_holder);
|
||||
Handle<NumberDictionary> new_storage = NumberDictionary::Set(
|
||||
slow_storage, i, element, not_a_prototype_holder);
|
||||
if (!new_storage.is_identical_to(slow_storage)) {
|
||||
slow_storage = loop_scope.CloseAndEscape(new_storage);
|
||||
}
|
||||
@ -597,8 +595,7 @@ uint32_t EstimateElementCount(Handle<JSArray> array) {
|
||||
break;
|
||||
}
|
||||
case DICTIONARY_ELEMENTS: {
|
||||
SeededNumberDictionary* dictionary =
|
||||
SeededNumberDictionary::cast(array->elements());
|
||||
NumberDictionary* dictionary = NumberDictionary::cast(array->elements());
|
||||
Isolate* isolate = dictionary->GetIsolate();
|
||||
int capacity = dictionary->Capacity();
|
||||
for (int i = 0; i < capacity; i++) {
|
||||
@ -667,8 +664,7 @@ void CollectElementIndices(Handle<JSObject> object, uint32_t range,
|
||||
}
|
||||
case DICTIONARY_ELEMENTS: {
|
||||
DisallowHeapAllocation no_gc;
|
||||
SeededNumberDictionary* dict =
|
||||
SeededNumberDictionary::cast(object->elements());
|
||||
NumberDictionary* dict = NumberDictionary::cast(object->elements());
|
||||
uint32_t capacity = dict->Capacity();
|
||||
FOR_WITH_HANDLE_SCOPE(isolate, uint32_t, j = 0, j, j < capacity, j++, {
|
||||
Object* k = dict->KeyAt(j);
|
||||
@ -864,7 +860,7 @@ bool IterateElements(Isolate* isolate, Handle<JSReceiver> receiver,
|
||||
}
|
||||
|
||||
case DICTIONARY_ELEMENTS: {
|
||||
Handle<SeededNumberDictionary> dict(array->element_dictionary());
|
||||
Handle<NumberDictionary> dict(array->element_dictionary());
|
||||
std::vector<uint32_t> indices;
|
||||
indices.reserve(dict->Capacity() / 2);
|
||||
|
||||
@ -1071,7 +1067,7 @@ Object* Slow_ArrayConcat(BuiltinArguments* args, Handle<Object> species,
|
||||
storage =
|
||||
isolate->factory()->NewFixedArrayWithHoles(estimate_result_length);
|
||||
} else if (is_array_species) {
|
||||
storage = SeededNumberDictionary::New(isolate, estimate_nof);
|
||||
storage = NumberDictionary::New(isolate, estimate_nof);
|
||||
} else {
|
||||
DCHECK(species->IsConstructor());
|
||||
Handle<Object> length(Smi::kZero, isolate);
|
||||
|
@ -4307,12 +4307,12 @@ Node* CodeStubAssembler::IsHashTable(Node* object) {
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::IsDictionary(Node* object) {
|
||||
return Word32Or(IsHashTable(object), IsUnseededNumberDictionary(object));
|
||||
return Word32Or(IsHashTable(object), IsNumberDictionary(object));
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::IsUnseededNumberDictionary(Node* object) {
|
||||
Node* CodeStubAssembler::IsNumberDictionary(Node* object) {
|
||||
return WordEqual(LoadMap(object),
|
||||
LoadRoot(Heap::kUnseededNumberDictionaryMapRootIndex));
|
||||
LoadRoot(Heap::kNumberDictionaryMapRootIndex));
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::IsJSFunctionInstanceType(Node* instance_type) {
|
||||
@ -5961,8 +5961,7 @@ Node* CodeStubAssembler::EntryToIndex(Node* entry, int field_index) {
|
||||
|
||||
template Node* CodeStubAssembler::EntryToIndex<NameDictionary>(Node*, int);
|
||||
template Node* CodeStubAssembler::EntryToIndex<GlobalDictionary>(Node*, int);
|
||||
template Node* CodeStubAssembler::EntryToIndex<SeededNumberDictionary>(Node*,
|
||||
int);
|
||||
template Node* CodeStubAssembler::EntryToIndex<NumberDictionary>(Node*, int);
|
||||
|
||||
// This must be kept in sync with HashTableBase::ComputeCapacity().
|
||||
TNode<IntPtrT> CodeStubAssembler::HashTableComputeCapacity(
|
||||
@ -6117,22 +6116,19 @@ Node* CodeStubAssembler::ComputeIntegerHash(Node* key, Node* seed) {
|
||||
return Word32And(hash, Int32Constant(0x3fffffff));
|
||||
}
|
||||
|
||||
template <typename Dictionary>
|
||||
void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary,
|
||||
Node* intptr_index,
|
||||
Label* if_found,
|
||||
Variable* var_entry,
|
||||
Label* if_not_found) {
|
||||
CSA_ASSERT(this, IsDictionary(dictionary));
|
||||
CSA_ASSERT(this, IsNumberDictionary(dictionary));
|
||||
DCHECK_EQ(MachineType::PointerRepresentation(), var_entry->rep());
|
||||
Comment("NumberDictionaryLookup");
|
||||
|
||||
Node* capacity = SmiUntag(GetCapacity<Dictionary>(dictionary));
|
||||
Node* capacity = SmiUntag(GetCapacity<NumberDictionary>(dictionary));
|
||||
Node* mask = IntPtrSub(capacity, IntPtrConstant(1));
|
||||
|
||||
Node* int32_seed = std::is_same<Dictionary, SeededNumberDictionary>::value
|
||||
? HashSeed()
|
||||
: Int32Constant(kZeroHashSeed);
|
||||
Node* int32_seed = HashSeed();
|
||||
Node* hash = ChangeUint32ToWord(ComputeIntegerHash(intptr_index, int32_seed));
|
||||
Node* key_as_float64 = RoundIntPtrToFloat64(intptr_index);
|
||||
|
||||
@ -6152,7 +6148,7 @@ void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary,
|
||||
{
|
||||
Node* entry = var_entry->value();
|
||||
|
||||
Node* index = EntryToIndex<Dictionary>(entry);
|
||||
Node* index = EntryToIndex<NumberDictionary>(entry);
|
||||
Node* current = LoadFixedArrayElement(dictionary, index);
|
||||
GotoIf(WordEqual(current, undefined), if_not_found);
|
||||
Label next_probe(this);
|
||||
@ -6948,8 +6944,8 @@ void CodeStubAssembler::TryLookupElement(Node* object, Node* map,
|
||||
|
||||
VARIABLE(var_entry, MachineType::PointerRepresentation());
|
||||
Node* elements = LoadElements(object);
|
||||
NumberDictionaryLookup<SeededNumberDictionary>(
|
||||
elements, intptr_index, if_found, &var_entry, if_not_found);
|
||||
NumberDictionaryLookup(elements, intptr_index, if_found, &var_entry,
|
||||
if_not_found);
|
||||
}
|
||||
BIND(&if_isfaststringwrapper);
|
||||
{
|
||||
@ -6987,12 +6983,6 @@ void CodeStubAssembler::TryLookupElement(Node* object, Node* map,
|
||||
}
|
||||
}
|
||||
|
||||
// Instantiate template methods to workaround GCC compilation issue.
|
||||
template void CodeStubAssembler::NumberDictionaryLookup<SeededNumberDictionary>(
|
||||
Node*, Node*, Label*, Variable*, Label*);
|
||||
template void CodeStubAssembler::NumberDictionaryLookup<
|
||||
UnseededNumberDictionary>(Node*, Node*, Label*, Variable*, Label*);
|
||||
|
||||
void CodeStubAssembler::TryPrototypeChainLookup(
|
||||
Node* receiver, Node* key, const LookupInHolder& lookup_property_in_holder,
|
||||
const LookupInHolder& lookup_element_in_holder, Label* if_end,
|
||||
|
@ -1019,17 +1019,19 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
||||
Node* IsAllocationSite(Node* object);
|
||||
Node* IsAnyHeapNumber(Node* object);
|
||||
Node* IsArrayIteratorInstanceType(Node* instance_type);
|
||||
Node* IsArrayProtectorCellInvalid();
|
||||
Node* IsBigIntInstanceType(Node* instance_type);
|
||||
Node* IsBigInt(Node* object);
|
||||
Node* IsBoolean(Node* object);
|
||||
Node* IsExtensibleMap(Node* map);
|
||||
Node* IsCallableMap(Node* map);
|
||||
Node* IsCallable(Node* object);
|
||||
Node* IsCell(Node* object);
|
||||
Node* IsConsStringInstanceType(Node* instance_type);
|
||||
Node* IsConstructorMap(Node* map);
|
||||
Node* IsConstructor(Node* object);
|
||||
Node* IsFunctionWithPrototypeSlotMap(Node* map);
|
||||
Node* IsDeprecatedMap(Node* map);
|
||||
Node* IsDictionary(Node* object);
|
||||
Node* IsExtensibleMap(Node* map);
|
||||
Node* IsExternalStringInstanceType(Node* instance_type);
|
||||
Node* IsFeedbackVector(Node* object);
|
||||
Node* IsFixedArray(Node* object);
|
||||
@ -1037,7 +1039,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
||||
Node* IsFixedArrayWithKindOrEmpty(Node* object, ElementsKind kind);
|
||||
Node* IsFixedDoubleArray(Node* object);
|
||||
Node* IsFixedTypedArray(Node* object);
|
||||
Node* IsZeroOrFixedArray(Node* object);
|
||||
Node* IsFunctionWithPrototypeSlotMap(Node* map);
|
||||
Node* IsHashTable(Node* object);
|
||||
Node* IsHeapNumber(Node* object);
|
||||
Node* IsIndirectStringInstanceType(Node* instance_type);
|
||||
@ -1048,17 +1050,15 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
||||
Node* IsJSFunctionInstanceType(Node* instance_type);
|
||||
Node* IsJSFunctionMap(Node* object);
|
||||
Node* IsJSFunction(Node* object);
|
||||
Node* IsJSGlobalProxyInstanceType(Node* instance_type);
|
||||
Node* IsJSGlobalProxy(Node* object);
|
||||
Node* IsJSObjectInstanceType(Node* instance_type);
|
||||
Node* IsJSObjectMap(Node* map);
|
||||
Node* IsJSObject(Node* object);
|
||||
Node* IsJSGlobalProxyInstanceType(Node* instance_type);
|
||||
Node* IsJSProxy(Node* object);
|
||||
Node* IsJSReceiverInstanceType(Node* instance_type);
|
||||
Node* IsJSReceiverMap(Node* map);
|
||||
Node* IsJSReceiver(Node* object);
|
||||
Node* IsNullOrJSReceiver(Node* object);
|
||||
Node* IsNullOrUndefined(Node* object);
|
||||
Node* IsJSRegExp(Node* object);
|
||||
Node* IsJSTypedArray(Node* object);
|
||||
Node* IsJSValueInstanceType(Node* instance_type);
|
||||
@ -1068,30 +1068,31 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
||||
Node* IsMutableHeapNumber(Node* object);
|
||||
Node* IsName(Node* object);
|
||||
Node* IsNativeContext(Node* object);
|
||||
Node* IsNullOrJSReceiver(Node* object);
|
||||
Node* IsNullOrUndefined(Node* object);
|
||||
Node* IsNumberDictionary(Node* object);
|
||||
Node* IsOneByteStringInstanceType(Node* instance_type);
|
||||
Node* IsPrimitiveInstanceType(Node* instance_type);
|
||||
Node* IsPrivateSymbol(Node* object);
|
||||
Node* IsPropertyArray(Node* object);
|
||||
Node* IsPropertyCell(Node* object);
|
||||
Node* IsPrototypeInitialArrayPrototype(Node* context, Node* map);
|
||||
Node* IsSequentialStringInstanceType(Node* instance_type);
|
||||
inline Node* IsSharedFunctionInfo(Node* object) {
|
||||
return IsSharedFunctionInfoMap(LoadMap(object));
|
||||
}
|
||||
Node* IsShortExternalStringInstanceType(Node* instance_type);
|
||||
Node* IsSpecialReceiverInstanceType(Node* instance_type);
|
||||
Node* IsSpecialReceiverMap(Node* map);
|
||||
Node* IsSpeciesProtectorCellInvalid();
|
||||
Node* IsStringInstanceType(Node* instance_type);
|
||||
Node* IsString(Node* object);
|
||||
Node* IsSymbolInstanceType(Node* instance_type);
|
||||
Node* IsSymbol(Node* object);
|
||||
Node* IsBigIntInstanceType(Node* instance_type);
|
||||
Node* IsBigInt(Node* object);
|
||||
Node* IsUnseededNumberDictionary(Node* object);
|
||||
Node* IsWeakCell(Node* object);
|
||||
Node* IsUndetectableMap(Node* map);
|
||||
Node* IsArrayProtectorCellInvalid();
|
||||
Node* IsSpeciesProtectorCellInvalid();
|
||||
Node* IsPrototypeInitialArrayPrototype(Node* context, Node* map);
|
||||
Node* IsWeakCell(Node* object);
|
||||
Node* IsZeroOrFixedArray(Node* object);
|
||||
|
||||
inline Node* IsSharedFunctionInfo(Node* object) {
|
||||
return IsSharedFunctionInfoMap(LoadMap(object));
|
||||
}
|
||||
|
||||
// True iff |object| is a Smi or a HeapNumber.
|
||||
Node* IsNumber(Node* object);
|
||||
@ -1466,7 +1467,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
||||
Node* ComputeIntegerHash(Node* key);
|
||||
Node* ComputeIntegerHash(Node* key, Node* seed);
|
||||
|
||||
template <typename Dictionary>
|
||||
void NumberDictionaryLookup(Node* dictionary, Node* intptr_index,
|
||||
Label* if_found, Variable* var_entry,
|
||||
Label* if_not_found);
|
||||
|
@ -71,9 +71,9 @@ void CodeStubDescriptor::Initialize(Register stack_parameter_count,
|
||||
|
||||
|
||||
bool CodeStub::FindCodeInCache(Code** code_out) {
|
||||
UnseededNumberDictionary* stubs = isolate()->heap()->code_stubs();
|
||||
NumberDictionary* stubs = isolate()->heap()->code_stubs();
|
||||
int index = stubs->FindEntry(isolate(), GetKey());
|
||||
if (index != UnseededNumberDictionary::kNotFound) {
|
||||
if (index != NumberDictionary::kNotFound) {
|
||||
*code_out = Code::cast(stubs->ValueAt(index));
|
||||
return true;
|
||||
}
|
||||
@ -97,10 +97,10 @@ void CodeStub::RecordCodeGeneration(Handle<Code> code) {
|
||||
|
||||
void CodeStub::DeleteStubFromCacheForTesting() {
|
||||
Heap* heap = isolate_->heap();
|
||||
Handle<UnseededNumberDictionary> dict(heap->code_stubs());
|
||||
Handle<NumberDictionary> dict(heap->code_stubs());
|
||||
int entry = dict->FindEntry(GetKey());
|
||||
DCHECK_NE(UnseededNumberDictionary::kNotFound, entry);
|
||||
dict = UnseededNumberDictionary::DeleteEntry(dict, entry);
|
||||
DCHECK_NE(NumberDictionary::kNotFound, entry);
|
||||
dict = NumberDictionary::DeleteEntry(dict, entry);
|
||||
heap->SetRootCodeStubs(*dict);
|
||||
}
|
||||
|
||||
@ -165,8 +165,8 @@ Handle<Code> CodeStub::GetCode() {
|
||||
#endif
|
||||
|
||||
// Update the dictionary and the root in Heap.
|
||||
Handle<UnseededNumberDictionary> dict = UnseededNumberDictionary::Set(
|
||||
handle(heap->code_stubs()), GetKey(), new_object);
|
||||
Handle<NumberDictionary> dict =
|
||||
NumberDictionary::Set(handle(heap->code_stubs()), GetKey(), new_object);
|
||||
heap->SetRootCodeStubs(*dict);
|
||||
code = *new_object;
|
||||
}
|
||||
|
@ -1102,7 +1102,7 @@ ElementAccess AccessBuilder::ForOrderedHashMapEntryValue() {
|
||||
FieldAccess AccessBuilder::ForDictionaryMaxNumberKey() {
|
||||
FieldAccess access = {
|
||||
kTaggedBase,
|
||||
FixedArray::OffsetOfElementAt(SeededNumberDictionary::kMaxNumberKeyIndex),
|
||||
FixedArray::OffsetOfElementAt(NumberDictionary::kMaxNumberKeyIndex),
|
||||
MaybeHandle<Name>(),
|
||||
MaybeHandle<Map>(),
|
||||
Type::Any(),
|
||||
|
@ -352,7 +352,7 @@ enum ContextLookupFlags {
|
||||
slow_object_with_null_prototype_map) \
|
||||
V(SLOW_OBJECT_WITH_OBJECT_PROTOTYPE_MAP, Map, \
|
||||
slow_object_with_object_prototype_map) \
|
||||
V(SLOW_TEMPLATE_INSTANTIATIONS_CACHE_INDEX, UnseededNumberDictionary, \
|
||||
V(SLOW_TEMPLATE_INSTANTIATIONS_CACHE_INDEX, NumberDictionary, \
|
||||
slow_template_instantiations_cache) \
|
||||
/* All *_FUNCTION_MAP_INDEX definitions used by Context::FunctionMapIndex */ \
|
||||
/* must remain together. */ \
|
||||
|
161
src/elements.cc
161
src/elements.cc
@ -71,7 +71,7 @@ enum Where { AT_START, AT_END };
|
||||
V(FastPackedDoubleElementsAccessor, PACKED_DOUBLE_ELEMENTS, \
|
||||
FixedDoubleArray) \
|
||||
V(FastHoleyDoubleElementsAccessor, HOLEY_DOUBLE_ELEMENTS, FixedDoubleArray) \
|
||||
V(DictionaryElementsAccessor, DICTIONARY_ELEMENTS, SeededNumberDictionary) \
|
||||
V(DictionaryElementsAccessor, DICTIONARY_ELEMENTS, NumberDictionary) \
|
||||
V(FastSloppyArgumentsElementsAccessor, FAST_SLOPPY_ARGUMENTS_ELEMENTS, \
|
||||
FixedArray) \
|
||||
V(SlowSloppyArgumentsElementsAccessor, SLOW_SLOPPY_ARGUMENTS_ELEMENTS, \
|
||||
@ -161,7 +161,7 @@ static void CopyDictionaryToObjectElements(
|
||||
FixedArrayBase* from_base, uint32_t from_start, FixedArrayBase* to_base,
|
||||
ElementsKind to_kind, uint32_t to_start, int raw_copy_size) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
SeededNumberDictionary* from = SeededNumberDictionary::cast(from_base);
|
||||
NumberDictionary* from = NumberDictionary::cast(from_base);
|
||||
int copy_size = raw_copy_size;
|
||||
if (raw_copy_size < 0) {
|
||||
DCHECK(raw_copy_size == ElementsAccessor::kCopyToEnd ||
|
||||
@ -190,7 +190,7 @@ static void CopyDictionaryToObjectElements(
|
||||
Isolate* isolate = from->GetIsolate();
|
||||
for (int i = 0; i < copy_size; i++) {
|
||||
int entry = from->FindEntry(isolate, i + from_start);
|
||||
if (entry != SeededNumberDictionary::kNotFound) {
|
||||
if (entry != NumberDictionary::kNotFound) {
|
||||
Object* value = from->ValueAt(entry);
|
||||
DCHECK(!value->IsTheHole(isolate));
|
||||
to->set(i + to_start, value, write_barrier_mode);
|
||||
@ -401,7 +401,7 @@ static void CopyDictionaryToDoubleElements(FixedArrayBase* from_base,
|
||||
uint32_t to_start,
|
||||
int raw_copy_size) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
SeededNumberDictionary* from = SeededNumberDictionary::cast(from_base);
|
||||
NumberDictionary* from = NumberDictionary::cast(from_base);
|
||||
int copy_size = raw_copy_size;
|
||||
if (copy_size < 0) {
|
||||
DCHECK(copy_size == ElementsAccessor::kCopyToEnd ||
|
||||
@ -422,7 +422,7 @@ static void CopyDictionaryToDoubleElements(FixedArrayBase* from_base,
|
||||
Isolate* isolate = from->GetIsolate();
|
||||
for (int i = 0; i < copy_size; i++) {
|
||||
int entry = from->FindEntry(isolate, i + from_start);
|
||||
if (entry != SeededNumberDictionary::kNotFound) {
|
||||
if (entry != NumberDictionary::kNotFound) {
|
||||
to->set(i + to_start, from->ValueAt(entry)->Number());
|
||||
} else {
|
||||
to->set_the_hole(i + to_start);
|
||||
@ -1031,11 +1031,11 @@ class ElementsAccessorBase : public ElementsAccessor {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
Handle<SeededNumberDictionary> Normalize(Handle<JSObject> object) final {
|
||||
Handle<NumberDictionary> Normalize(Handle<JSObject> object) final {
|
||||
return Subclass::NormalizeImpl(object, handle(object->elements()));
|
||||
}
|
||||
|
||||
static Handle<SeededNumberDictionary> NormalizeImpl(
|
||||
static Handle<NumberDictionary> NormalizeImpl(
|
||||
Handle<JSObject> object, Handle<FixedArrayBase> elements) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
@ -1365,15 +1365,15 @@ class DictionaryElementsAccessor
|
||||
|
||||
static uint32_t NumberOfElementsImpl(JSObject* receiver,
|
||||
FixedArrayBase* backing_store) {
|
||||
SeededNumberDictionary* dict = SeededNumberDictionary::cast(backing_store);
|
||||
NumberDictionary* dict = NumberDictionary::cast(backing_store);
|
||||
return dict->NumberOfElements();
|
||||
}
|
||||
|
||||
static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array,
|
||||
uint32_t length,
|
||||
Handle<FixedArrayBase> backing_store) {
|
||||
Handle<SeededNumberDictionary> dict =
|
||||
Handle<SeededNumberDictionary>::cast(backing_store);
|
||||
Handle<NumberDictionary> dict =
|
||||
Handle<NumberDictionary>::cast(backing_store);
|
||||
int capacity = dict->Capacity();
|
||||
uint32_t old_length = 0;
|
||||
CHECK(array->length()->ToArrayLength(&old_length));
|
||||
@ -1439,16 +1439,16 @@ class DictionaryElementsAccessor
|
||||
isolate->factory()->NewJSArray(0, HOLEY_ELEMENTS);
|
||||
JSObject::NormalizeElements(result_array);
|
||||
result_array->set_length(Smi::FromInt(result_length));
|
||||
Handle<SeededNumberDictionary> source_dict(
|
||||
SeededNumberDictionary::cast(receiver->elements()));
|
||||
Handle<NumberDictionary> source_dict(
|
||||
NumberDictionary::cast(receiver->elements()));
|
||||
int entry_count = source_dict->Capacity();
|
||||
for (int i = 0; i < entry_count; i++) {
|
||||
Object* key = source_dict->KeyAt(i);
|
||||
if (!key->IsUndefined(isolate)) {
|
||||
uint64_t key_value = NumberToInt64(key);
|
||||
if (key_value >= start && key_value < end) {
|
||||
Handle<SeededNumberDictionary> dest_dict(
|
||||
SeededNumberDictionary::cast(result_array->elements()));
|
||||
Handle<NumberDictionary> dest_dict(
|
||||
NumberDictionary::cast(result_array->elements()));
|
||||
Handle<Object> value(source_dict->ValueAt(i), isolate);
|
||||
PropertyDetails details = source_dict->DetailsAt(i);
|
||||
PropertyAttributes attr = details.attributes();
|
||||
@ -1462,16 +1462,15 @@ class DictionaryElementsAccessor
|
||||
}
|
||||
|
||||
static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) {
|
||||
Handle<SeededNumberDictionary> dict(
|
||||
SeededNumberDictionary::cast(obj->elements()));
|
||||
dict = SeededNumberDictionary::DeleteEntry(dict, entry);
|
||||
Handle<NumberDictionary> dict(NumberDictionary::cast(obj->elements()));
|
||||
dict = NumberDictionary::DeleteEntry(dict, entry);
|
||||
obj->set_elements(*dict);
|
||||
}
|
||||
|
||||
static bool HasAccessorsImpl(JSObject* holder,
|
||||
FixedArrayBase* backing_store) {
|
||||
DisallowHeapAllocation no_gc;
|
||||
SeededNumberDictionary* dict = SeededNumberDictionary::cast(backing_store);
|
||||
NumberDictionary* dict = NumberDictionary::cast(backing_store);
|
||||
if (!dict->requires_slow_elements()) return false;
|
||||
int capacity = dict->Capacity();
|
||||
Isolate* isolate = dict->GetIsolate();
|
||||
@ -1485,7 +1484,7 @@ class DictionaryElementsAccessor
|
||||
}
|
||||
|
||||
static Object* GetRaw(FixedArrayBase* store, uint32_t entry) {
|
||||
SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store);
|
||||
NumberDictionary* backing_store = NumberDictionary::cast(store);
|
||||
return backing_store->ValueAt(entry);
|
||||
}
|
||||
|
||||
@ -1501,14 +1500,14 @@ class DictionaryElementsAccessor
|
||||
|
||||
static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry,
|
||||
Object* value) {
|
||||
SeededNumberDictionary::cast(backing_store)->ValueAtPut(entry, value);
|
||||
NumberDictionary::cast(backing_store)->ValueAtPut(entry, value);
|
||||
}
|
||||
|
||||
static void ReconfigureImpl(Handle<JSObject> object,
|
||||
Handle<FixedArrayBase> store, uint32_t entry,
|
||||
Handle<Object> value,
|
||||
PropertyAttributes attributes) {
|
||||
SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(*store);
|
||||
NumberDictionary* dictionary = NumberDictionary::cast(*store);
|
||||
if (attributes != NONE) object->RequireSlowElements(dictionary);
|
||||
dictionary->ValueAtPut(entry, *value);
|
||||
PropertyDetails details = dictionary->DetailsAt(entry);
|
||||
@ -1522,12 +1521,12 @@ class DictionaryElementsAccessor
|
||||
Handle<Object> value, PropertyAttributes attributes,
|
||||
uint32_t new_capacity) {
|
||||
PropertyDetails details(kData, attributes, PropertyCellType::kNoCell);
|
||||
Handle<SeededNumberDictionary> dictionary =
|
||||
Handle<NumberDictionary> dictionary =
|
||||
object->HasFastElements() || object->HasFastStringWrapperElements()
|
||||
? JSObject::NormalizeElements(object)
|
||||
: handle(SeededNumberDictionary::cast(object->elements()));
|
||||
Handle<SeededNumberDictionary> new_dictionary =
|
||||
SeededNumberDictionary::Add(dictionary, index, value, details);
|
||||
: handle(NumberDictionary::cast(object->elements()));
|
||||
Handle<NumberDictionary> new_dictionary =
|
||||
NumberDictionary::Add(dictionary, index, value, details);
|
||||
new_dictionary->UpdateMaxNumberKey(index, object);
|
||||
if (attributes != NONE) object->RequireSlowElements(*new_dictionary);
|
||||
if (dictionary.is_identical_to(new_dictionary)) return;
|
||||
@ -1537,14 +1536,14 @@ class DictionaryElementsAccessor
|
||||
static bool HasEntryImpl(Isolate* isolate, FixedArrayBase* store,
|
||||
uint32_t entry) {
|
||||
DisallowHeapAllocation no_gc;
|
||||
SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
|
||||
NumberDictionary* dict = NumberDictionary::cast(store);
|
||||
Object* index = dict->KeyAt(entry);
|
||||
return !index->IsTheHole(isolate);
|
||||
}
|
||||
|
||||
static uint32_t GetIndexForEntryImpl(FixedArrayBase* store, uint32_t entry) {
|
||||
DisallowHeapAllocation no_gc;
|
||||
SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
|
||||
NumberDictionary* dict = NumberDictionary::cast(store);
|
||||
uint32_t result = 0;
|
||||
CHECK(dict->KeyAt(entry)->ToArrayIndex(&result));
|
||||
return result;
|
||||
@ -1554,9 +1553,9 @@ class DictionaryElementsAccessor
|
||||
FixedArrayBase* store, uint32_t index,
|
||||
PropertyFilter filter) {
|
||||
DisallowHeapAllocation no_gc;
|
||||
SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store);
|
||||
NumberDictionary* dictionary = NumberDictionary::cast(store);
|
||||
int entry = dictionary->FindEntry(isolate, index);
|
||||
if (entry == SeededNumberDictionary::kNotFound) return kMaxUInt32;
|
||||
if (entry == NumberDictionary::kNotFound) return kMaxUInt32;
|
||||
if (filter != ALL_PROPERTIES) {
|
||||
PropertyDetails details = dictionary->DetailsAt(entry);
|
||||
PropertyAttributes attr = details.attributes();
|
||||
@ -1571,11 +1570,11 @@ class DictionaryElementsAccessor
|
||||
|
||||
static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
|
||||
uint32_t entry) {
|
||||
return SeededNumberDictionary::cast(backing_store)->DetailsAt(entry);
|
||||
return NumberDictionary::cast(backing_store)->DetailsAt(entry);
|
||||
}
|
||||
|
||||
static uint32_t FilterKey(Handle<SeededNumberDictionary> dictionary,
|
||||
int entry, Object* raw_key, PropertyFilter filter) {
|
||||
static uint32_t FilterKey(Handle<NumberDictionary> dictionary, int entry,
|
||||
Object* raw_key, PropertyFilter filter) {
|
||||
DCHECK(raw_key->IsNumber());
|
||||
DCHECK_LE(raw_key->Number(), kMaxUInt32);
|
||||
PropertyDetails details = dictionary->DetailsAt(entry);
|
||||
@ -1585,7 +1584,7 @@ class DictionaryElementsAccessor
|
||||
}
|
||||
|
||||
static uint32_t GetKeyForEntryImpl(Isolate* isolate,
|
||||
Handle<SeededNumberDictionary> dictionary,
|
||||
Handle<NumberDictionary> dictionary,
|
||||
int entry, PropertyFilter filter) {
|
||||
DisallowHeapAllocation no_gc;
|
||||
Object* raw_key = dictionary->KeyAt(entry);
|
||||
@ -1598,8 +1597,8 @@ class DictionaryElementsAccessor
|
||||
KeyAccumulator* keys) {
|
||||
if (keys->filter() & SKIP_STRINGS) return;
|
||||
Isolate* isolate = keys->isolate();
|
||||
Handle<SeededNumberDictionary> dictionary =
|
||||
Handle<SeededNumberDictionary>::cast(backing_store);
|
||||
Handle<NumberDictionary> dictionary =
|
||||
Handle<NumberDictionary>::cast(backing_store);
|
||||
int capacity = dictionary->Capacity();
|
||||
Handle<FixedArray> elements = isolate->factory()->NewFixedArray(
|
||||
GetMaxNumberOfEntries(*object, *backing_store));
|
||||
@ -1630,8 +1629,8 @@ class DictionaryElementsAccessor
|
||||
if (filter & SKIP_STRINGS) return list;
|
||||
if (filter & ONLY_ALL_CAN_READ) return list;
|
||||
|
||||
Handle<SeededNumberDictionary> dictionary =
|
||||
Handle<SeededNumberDictionary>::cast(backing_store);
|
||||
Handle<NumberDictionary> dictionary =
|
||||
Handle<NumberDictionary>::cast(backing_store);
|
||||
uint32_t capacity = dictionary->Capacity();
|
||||
for (uint32_t i = 0; i < capacity; i++) {
|
||||
uint32_t key = GetKeyForEntryImpl(isolate, dictionary, i, filter);
|
||||
@ -1648,8 +1647,8 @@ class DictionaryElementsAccessor
|
||||
KeyAccumulator* accumulator,
|
||||
AddKeyConversion convert) {
|
||||
Isolate* isolate = accumulator->isolate();
|
||||
Handle<SeededNumberDictionary> dictionary(
|
||||
SeededNumberDictionary::cast(receiver->elements()), isolate);
|
||||
Handle<NumberDictionary> dictionary(
|
||||
NumberDictionary::cast(receiver->elements()), isolate);
|
||||
int capacity = dictionary->Capacity();
|
||||
for (int i = 0; i < capacity; i++) {
|
||||
Object* k = dictionary->KeyAt(i);
|
||||
@ -1666,8 +1665,7 @@ class DictionaryElementsAccessor
|
||||
Handle<Object> value, uint32_t start_from,
|
||||
uint32_t length, Maybe<bool>* result) {
|
||||
DisallowHeapAllocation no_gc;
|
||||
SeededNumberDictionary* dictionary =
|
||||
SeededNumberDictionary::cast(receiver->elements());
|
||||
NumberDictionary* dictionary = NumberDictionary::cast(receiver->elements());
|
||||
int capacity = dictionary->Capacity();
|
||||
Object* the_hole = isolate->heap()->the_hole_value();
|
||||
Object* undefined = isolate->heap()->undefined_value();
|
||||
@ -1714,13 +1712,13 @@ class DictionaryElementsAccessor
|
||||
}
|
||||
}
|
||||
|
||||
Handle<SeededNumberDictionary> dictionary(
|
||||
SeededNumberDictionary::cast(receiver->elements()), isolate);
|
||||
Handle<NumberDictionary> dictionary(
|
||||
NumberDictionary::cast(receiver->elements()), isolate);
|
||||
// Iterate through entire range, as accessing elements out of order is
|
||||
// observable
|
||||
for (uint32_t k = start_from; k < length; ++k) {
|
||||
int entry = dictionary->FindEntry(isolate, k);
|
||||
if (entry == SeededNumberDictionary::kNotFound) {
|
||||
if (entry == NumberDictionary::kNotFound) {
|
||||
if (search_for_hole) return Just(true);
|
||||
continue;
|
||||
}
|
||||
@ -1768,8 +1766,8 @@ class DictionaryElementsAccessor
|
||||
return accessor->IncludesValue(isolate, receiver, value, k + 1,
|
||||
length);
|
||||
}
|
||||
dictionary = handle(
|
||||
SeededNumberDictionary::cast(receiver->elements()), isolate);
|
||||
dictionary =
|
||||
handle(NumberDictionary::cast(receiver->elements()), isolate);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1783,13 +1781,13 @@ class DictionaryElementsAccessor
|
||||
uint32_t start_from, uint32_t length) {
|
||||
DCHECK(JSObject::PrototypeHasNoElements(isolate, *receiver));
|
||||
|
||||
Handle<SeededNumberDictionary> dictionary(
|
||||
SeededNumberDictionary::cast(receiver->elements()), isolate);
|
||||
Handle<NumberDictionary> dictionary(
|
||||
NumberDictionary::cast(receiver->elements()), isolate);
|
||||
// Iterate through entire range, as accessing elements out of order is
|
||||
// observable.
|
||||
for (uint32_t k = start_from; k < length; ++k) {
|
||||
int entry = dictionary->FindEntry(isolate, k);
|
||||
if (entry == SeededNumberDictionary::kNotFound) {
|
||||
if (entry == NumberDictionary::kNotFound) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1830,8 +1828,8 @@ class DictionaryElementsAccessor
|
||||
return IndexOfValueSlowPath(isolate, receiver, value, k + 1,
|
||||
length);
|
||||
}
|
||||
dictionary = handle(
|
||||
SeededNumberDictionary::cast(receiver->elements()), isolate);
|
||||
dictionary =
|
||||
handle(NumberDictionary::cast(receiver->elements()), isolate);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1845,8 +1843,7 @@ class DictionaryElementsAccessor
|
||||
DCHECK_EQ(holder->map()->elements_kind(), DICTIONARY_ELEMENTS);
|
||||
if (!FLAG_enable_slow_asserts) return;
|
||||
Isolate* isolate = holder->GetIsolate();
|
||||
SeededNumberDictionary* dictionary =
|
||||
SeededNumberDictionary::cast(holder->elements());
|
||||
NumberDictionary* dictionary = NumberDictionary::cast(holder->elements());
|
||||
// Validate the requires_slow_elements and max_number_key values.
|
||||
int capacity = dictionary->Capacity();
|
||||
bool requires_slow_elements = false;
|
||||
@ -1855,7 +1852,7 @@ class DictionaryElementsAccessor
|
||||
Object* k;
|
||||
if (!dictionary->ToKey(isolate, i, &k)) continue;
|
||||
DCHECK_LE(0.0, k->Number());
|
||||
if (k->Number() > SeededNumberDictionary::kRequiresSlowElementsLimit) {
|
||||
if (k->Number() > NumberDictionary::kRequiresSlowElementsLimit) {
|
||||
requires_slow_elements = true;
|
||||
} else {
|
||||
max_key = Max(max_key, Smi::ToInt(k));
|
||||
@ -1880,8 +1877,8 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> {
|
||||
|
||||
typedef typename KindTraits::BackingStore BackingStore;
|
||||
|
||||
static Handle<SeededNumberDictionary> NormalizeImpl(
|
||||
Handle<JSObject> object, Handle<FixedArrayBase> store) {
|
||||
static Handle<NumberDictionary> NormalizeImpl(Handle<JSObject> object,
|
||||
Handle<FixedArrayBase> store) {
|
||||
Isolate* isolate = store->GetIsolate();
|
||||
ElementsKind kind = Subclass::kind();
|
||||
|
||||
@ -1893,8 +1890,8 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> {
|
||||
}
|
||||
|
||||
int capacity = object->GetFastElementsUsage();
|
||||
Handle<SeededNumberDictionary> dictionary =
|
||||
SeededNumberDictionary::New(isolate, capacity);
|
||||
Handle<NumberDictionary> dictionary =
|
||||
NumberDictionary::New(isolate, capacity);
|
||||
|
||||
PropertyDetails details = PropertyDetails::Empty();
|
||||
int j = 0;
|
||||
@ -1905,7 +1902,7 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> {
|
||||
}
|
||||
max_number_key = i;
|
||||
Handle<Object> value = Subclass::GetImpl(isolate, *store, i);
|
||||
dictionary = SeededNumberDictionary::Add(dictionary, i, value, details);
|
||||
dictionary = NumberDictionary::Add(dictionary, i, value, details);
|
||||
j++;
|
||||
}
|
||||
|
||||
@ -1973,8 +1970,8 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> {
|
||||
// enough to reliably hit the "window" of remaining elements count where
|
||||
// normalization would be beneficial.
|
||||
STATIC_ASSERT(kLengthFraction >=
|
||||
SeededNumberDictionary::kEntrySize *
|
||||
SeededNumberDictionary::kPreferFastElementsSizeFactor);
|
||||
NumberDictionary::kEntrySize *
|
||||
NumberDictionary::kPreferFastElementsSizeFactor);
|
||||
size_t current_counter = isolate->elements_deletion_counter();
|
||||
if (current_counter < length / kLengthFraction) {
|
||||
isolate->set_elements_deletion_counter(current_counter + 1);
|
||||
@ -1998,9 +1995,9 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> {
|
||||
if (!backing_store->is_the_hole(isolate, i)) {
|
||||
++num_used;
|
||||
// Bail out if a number dictionary wouldn't be able to save much space.
|
||||
if (SeededNumberDictionary::kPreferFastElementsSizeFactor *
|
||||
SeededNumberDictionary::ComputeCapacity(num_used) *
|
||||
SeededNumberDictionary::kEntrySize >
|
||||
if (NumberDictionary::kPreferFastElementsSizeFactor *
|
||||
NumberDictionary::ComputeCapacity(num_used) *
|
||||
NumberDictionary::kEntrySize >
|
||||
static_cast<uint32_t>(backing_store->length())) {
|
||||
return;
|
||||
}
|
||||
@ -2013,8 +2010,7 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> {
|
||||
Handle<FixedArrayBase> store, uint32_t entry,
|
||||
Handle<Object> value,
|
||||
PropertyAttributes attributes) {
|
||||
Handle<SeededNumberDictionary> dictionary =
|
||||
JSObject::NormalizeElements(object);
|
||||
Handle<NumberDictionary> dictionary = JSObject::NormalizeElements(object);
|
||||
entry = dictionary->FindEntry(entry);
|
||||
DictionaryElementsAccessor::ReconfigureImpl(object, dictionary, entry,
|
||||
value, attributes);
|
||||
@ -3829,10 +3825,10 @@ class SlowSloppyArgumentsElementsAccessor
|
||||
// No need to delete a context mapped entry from the arguments elements.
|
||||
if (entry == kMaxUInt32) return;
|
||||
Isolate* isolate = obj->GetIsolate();
|
||||
Handle<SeededNumberDictionary> dict(
|
||||
SeededNumberDictionary::cast(elements->arguments()), isolate);
|
||||
Handle<NumberDictionary> dict(NumberDictionary::cast(elements->arguments()),
|
||||
isolate);
|
||||
int length = elements->parameter_map_length();
|
||||
dict = SeededNumberDictionary::DeleteEntry(dict, entry - length);
|
||||
dict = NumberDictionary::DeleteEntry(dict, entry - length);
|
||||
elements->set_arguments(*dict);
|
||||
}
|
||||
static void AddImpl(Handle<JSObject> object, uint32_t index,
|
||||
@ -3843,13 +3839,13 @@ class SlowSloppyArgumentsElementsAccessor
|
||||
SloppyArgumentsElements::cast(object->elements()), isolate);
|
||||
Handle<FixedArrayBase> old_arguments(
|
||||
FixedArrayBase::cast(elements->arguments()), isolate);
|
||||
Handle<SeededNumberDictionary> dictionary =
|
||||
old_arguments->IsSeededNumberDictionary()
|
||||
? Handle<SeededNumberDictionary>::cast(old_arguments)
|
||||
Handle<NumberDictionary> dictionary =
|
||||
old_arguments->IsNumberDictionary()
|
||||
? Handle<NumberDictionary>::cast(old_arguments)
|
||||
: JSObject::NormalizeElements(object);
|
||||
PropertyDetails details(kData, attributes, PropertyCellType::kNoCell);
|
||||
Handle<SeededNumberDictionary> new_dictionary =
|
||||
SeededNumberDictionary::Add(dictionary, index, value, details);
|
||||
Handle<NumberDictionary> new_dictionary =
|
||||
NumberDictionary::Add(dictionary, index, value, details);
|
||||
if (attributes != NONE) object->RequireSlowElements(*new_dictionary);
|
||||
if (*dictionary != *new_dictionary) {
|
||||
elements->set_arguments(*new_dictionary);
|
||||
@ -3880,9 +3876,9 @@ class SlowSloppyArgumentsElementsAccessor
|
||||
}
|
||||
|
||||
PropertyDetails details(kData, attributes, PropertyCellType::kNoCell);
|
||||
Handle<SeededNumberDictionary> arguments(
|
||||
SeededNumberDictionary::cast(elements->arguments()), isolate);
|
||||
arguments = SeededNumberDictionary::Add(arguments, entry, value, details);
|
||||
Handle<NumberDictionary> arguments(
|
||||
NumberDictionary::cast(elements->arguments()), isolate);
|
||||
arguments = NumberDictionary::Add(arguments, entry, value, details);
|
||||
// If the attributes were NONE, we would have called set rather than
|
||||
// reconfigure.
|
||||
DCHECK_NE(NONE, attributes);
|
||||
@ -3921,18 +3917,17 @@ class FastSloppyArgumentsElementsAccessor
|
||||
return Handle<FixedArray>(elements->arguments(), isolate);
|
||||
}
|
||||
|
||||
static Handle<SeededNumberDictionary> NormalizeImpl(
|
||||
static Handle<NumberDictionary> NormalizeImpl(
|
||||
Handle<JSObject> object, Handle<FixedArrayBase> elements) {
|
||||
Handle<FixedArray> arguments =
|
||||
GetArguments(elements->GetIsolate(), *elements);
|
||||
return FastHoleyObjectElementsAccessor::NormalizeImpl(object, arguments);
|
||||
}
|
||||
|
||||
static Handle<SeededNumberDictionary> NormalizeArgumentsElements(
|
||||
static Handle<NumberDictionary> NormalizeArgumentsElements(
|
||||
Handle<JSObject> object, Handle<SloppyArgumentsElements> elements,
|
||||
uint32_t* entry) {
|
||||
Handle<SeededNumberDictionary> dictionary =
|
||||
JSObject::NormalizeElements(object);
|
||||
Handle<NumberDictionary> dictionary = JSObject::NormalizeElements(object);
|
||||
elements->set_arguments(*dictionary);
|
||||
// kMaxUInt32 indicates that a context mapped element got deleted. In this
|
||||
// case we only normalize the elements (aka. migrate to SLOW_SLOPPY).
|
||||
@ -3960,7 +3955,7 @@ class FastSloppyArgumentsElementsAccessor
|
||||
Handle<SloppyArgumentsElements> elements(
|
||||
SloppyArgumentsElements::cast(object->elements()), isolate);
|
||||
Handle<FixedArray> old_arguments(elements->arguments(), isolate);
|
||||
if (old_arguments->IsSeededNumberDictionary() ||
|
||||
if (old_arguments->IsNumberDictionary() ||
|
||||
static_cast<uint32_t>(old_arguments->length()) < new_capacity) {
|
||||
GrowCapacityAndConvertImpl(object, new_capacity);
|
||||
}
|
||||
@ -4209,7 +4204,7 @@ class FastStringWrapperElementsAccessor
|
||||
FastStringWrapperElementsAccessor, FastHoleyObjectElementsAccessor,
|
||||
ElementsKindTraits<FAST_STRING_WRAPPER_ELEMENTS>>(name) {}
|
||||
|
||||
static Handle<SeededNumberDictionary> NormalizeImpl(
|
||||
static Handle<NumberDictionary> NormalizeImpl(
|
||||
Handle<JSObject> object, Handle<FixedArrayBase> elements) {
|
||||
return FastHoleyObjectElementsAccessor::NormalizeImpl(object, elements);
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ class ElementsAccessor {
|
||||
|
||||
virtual Handle<Object> Shift(Handle<JSArray> receiver) = 0;
|
||||
|
||||
virtual Handle<SeededNumberDictionary> Normalize(Handle<JSObject> object) = 0;
|
||||
virtual Handle<NumberDictionary> Normalize(Handle<JSObject> object) = 0;
|
||||
|
||||
virtual uint32_t GetCapacity(JSObject* holder,
|
||||
FixedArrayBase* backing_store) = 0;
|
||||
|
@ -2812,7 +2812,7 @@ Handle<StackFrameInfo> Factory::NewStackFrameInfo() {
|
||||
Handle<SourcePositionTableWithFrameCache>
|
||||
Factory::NewSourcePositionTableWithFrameCache(
|
||||
Handle<ByteArray> source_position_table,
|
||||
Handle<UnseededNumberDictionary> stack_frame_cache) {
|
||||
Handle<NumberDictionary> stack_frame_cache) {
|
||||
Handle<SourcePositionTableWithFrameCache>
|
||||
source_position_table_with_frame_cache =
|
||||
Handle<SourcePositionTableWithFrameCache>::cast(
|
||||
|
@ -377,7 +377,7 @@ class V8_EXPORT_PRIVATE Factory final {
|
||||
Handle<SourcePositionTableWithFrameCache>
|
||||
NewSourcePositionTableWithFrameCache(
|
||||
Handle<ByteArray> source_position_table,
|
||||
Handle<UnseededNumberDictionary> stack_frame_cache);
|
||||
Handle<NumberDictionary> stack_frame_cache);
|
||||
|
||||
// Foreign objects are pretenured when allocated by the bootstrapper.
|
||||
Handle<Foreign> NewForeign(Address addr,
|
||||
|
@ -1060,26 +1060,26 @@ void CollectTypeProfileNexus::Collect(Handle<String> type, int position) {
|
||||
Object* const feedback = GetFeedback();
|
||||
|
||||
// Map source position to collection of types
|
||||
Handle<UnseededNumberDictionary> types;
|
||||
Handle<NumberDictionary> types;
|
||||
|
||||
if (feedback == *FeedbackVector::UninitializedSentinel(isolate)) {
|
||||
types = UnseededNumberDictionary::New(isolate, 1);
|
||||
types = NumberDictionary::New(isolate, 1);
|
||||
} else {
|
||||
types = handle(UnseededNumberDictionary::cast(feedback));
|
||||
types = handle(NumberDictionary::cast(feedback));
|
||||
}
|
||||
|
||||
Handle<ArrayList> position_specific_types;
|
||||
|
||||
int entry = types->FindEntry(position);
|
||||
if (entry == UnseededNumberDictionary::kNotFound) {
|
||||
if (entry == NumberDictionary::kNotFound) {
|
||||
position_specific_types = ArrayList::New(isolate, 1);
|
||||
types = UnseededNumberDictionary::Set(
|
||||
types = NumberDictionary::Set(
|
||||
types, position, ArrayList::Add(position_specific_types, type));
|
||||
} else {
|
||||
DCHECK(types->ValueAt(entry)->IsArrayList());
|
||||
position_specific_types = handle(ArrayList::cast(types->ValueAt(entry)));
|
||||
if (!InList(position_specific_types, type)) { // Add type
|
||||
types = UnseededNumberDictionary::Set(
|
||||
types = NumberDictionary::Set(
|
||||
types, position, ArrayList::Add(position_specific_types, type));
|
||||
}
|
||||
}
|
||||
@ -1100,12 +1100,12 @@ std::vector<int> CollectTypeProfileNexus::GetSourcePositions() const {
|
||||
return source_positions;
|
||||
}
|
||||
|
||||
Handle<UnseededNumberDictionary> types = Handle<UnseededNumberDictionary>(
|
||||
UnseededNumberDictionary::cast(feedback), isolate);
|
||||
Handle<NumberDictionary> types =
|
||||
Handle<NumberDictionary>(NumberDictionary::cast(feedback), isolate);
|
||||
|
||||
for (int index = UnseededNumberDictionary::kElementsStartIndex;
|
||||
index < types->length(); index += UnseededNumberDictionary::kEntrySize) {
|
||||
int key_index = index + UnseededNumberDictionary::kEntryKeyIndex;
|
||||
for (int index = NumberDictionary::kElementsStartIndex;
|
||||
index < types->length(); index += NumberDictionary::kEntrySize) {
|
||||
int key_index = index + NumberDictionary::kEntryKeyIndex;
|
||||
Object* key = types->get(key_index);
|
||||
if (key->IsSmi()) {
|
||||
int position = Smi::cast(key)->value();
|
||||
@ -1125,11 +1125,11 @@ std::vector<Handle<String>> CollectTypeProfileNexus::GetTypesForSourcePositions(
|
||||
return types_for_position;
|
||||
}
|
||||
|
||||
Handle<UnseededNumberDictionary> types = Handle<UnseededNumberDictionary>(
|
||||
UnseededNumberDictionary::cast(feedback), isolate);
|
||||
Handle<NumberDictionary> types =
|
||||
Handle<NumberDictionary>(NumberDictionary::cast(feedback), isolate);
|
||||
|
||||
int entry = types->FindEntry(position);
|
||||
if (entry == UnseededNumberDictionary::kNotFound) {
|
||||
if (entry == NumberDictionary::kNotFound) {
|
||||
return types_for_position;
|
||||
}
|
||||
DCHECK(types->ValueAt(entry)->IsArrayList());
|
||||
@ -1146,17 +1146,16 @@ std::vector<Handle<String>> CollectTypeProfileNexus::GetTypesForSourcePositions(
|
||||
namespace {
|
||||
|
||||
Handle<JSObject> ConvertToJSObject(Isolate* isolate,
|
||||
Handle<UnseededNumberDictionary> feedback) {
|
||||
Handle<NumberDictionary> feedback) {
|
||||
Handle<JSObject> type_profile =
|
||||
isolate->factory()->NewJSObject(isolate->object_function());
|
||||
|
||||
for (int index = UnseededNumberDictionary::kElementsStartIndex;
|
||||
index < feedback->length();
|
||||
index += UnseededNumberDictionary::kEntrySize) {
|
||||
int key_index = index + UnseededNumberDictionary::kEntryKeyIndex;
|
||||
for (int index = NumberDictionary::kElementsStartIndex;
|
||||
index < feedback->length(); index += NumberDictionary::kEntrySize) {
|
||||
int key_index = index + NumberDictionary::kEntryKeyIndex;
|
||||
Object* key = feedback->get(key_index);
|
||||
if (key->IsSmi()) {
|
||||
int value_index = index + UnseededNumberDictionary::kEntryValueIndex;
|
||||
int value_index = index + NumberDictionary::kEntryValueIndex;
|
||||
|
||||
Handle<ArrayList> position_specific_types(
|
||||
ArrayList::cast(feedback->get(value_index)));
|
||||
@ -1183,8 +1182,7 @@ JSObject* CollectTypeProfileNexus::GetTypeProfile() const {
|
||||
return *isolate->factory()->NewJSObject(isolate->object_function());
|
||||
}
|
||||
|
||||
return *ConvertToJSObject(isolate,
|
||||
handle(UnseededNumberDictionary::cast(feedback)));
|
||||
return *ConvertToJSObject(isolate, handle(NumberDictionary::cast(feedback)));
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
@ -484,8 +484,7 @@ class ExternalReference;
|
||||
class FixedArray;
|
||||
class FunctionTemplateInfo;
|
||||
class MemoryChunk;
|
||||
class SeededNumberDictionary;
|
||||
class UnseededNumberDictionary;
|
||||
class NumberDictionary;
|
||||
class NameDictionary;
|
||||
class GlobalDictionary;
|
||||
template <typename T> class MaybeHandle;
|
||||
|
@ -631,7 +631,7 @@ const char* Heap::GetSpaceName(int idx) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Heap::SetRootCodeStubs(UnseededNumberDictionary* value) {
|
||||
void Heap::SetRootCodeStubs(NumberDictionary* value) {
|
||||
roots_[kCodeStubsRootIndex] = value;
|
||||
}
|
||||
|
||||
|
@ -106,8 +106,7 @@ using v8::MemoryPressureLevel;
|
||||
V(Map, ordered_hash_table_map, OrderedHashTableMap) \
|
||||
V(Map, name_dictionary_map, NameDictionaryMap) \
|
||||
V(Map, global_dictionary_map, GlobalDictionaryMap) \
|
||||
V(Map, seeded_number_dictionary_map, SeededNumberDictionaryMap) \
|
||||
V(Map, unseeded_number_dictionary_map, UnseededNumberDictionaryMap) \
|
||||
V(Map, seeded_number_dictionary_map, NumberDictionaryMap) \
|
||||
V(Map, sloppy_arguments_elements_map, SloppyArgumentsElementsMap) \
|
||||
V(Map, small_ordered_hash_map_map, SmallOrderedHashMapMap) \
|
||||
V(Map, small_ordered_hash_set_map, SmallOrderedHashSetMap) \
|
||||
@ -188,7 +187,7 @@ using v8::MemoryPressureLevel;
|
||||
V(Script, empty_script, EmptyScript) \
|
||||
V(Cell, undefined_cell, UndefinedCell) \
|
||||
V(FixedArray, empty_sloppy_arguments_elements, EmptySloppyArgumentsElements) \
|
||||
V(SeededNumberDictionary, empty_slow_element_dictionary, \
|
||||
V(NumberDictionary, empty_slow_element_dictionary, \
|
||||
EmptySlowElementDictionary) \
|
||||
V(FixedArray, empty_ordered_hash_table, EmptyOrderedHashTable) \
|
||||
V(PropertyCell, empty_property_cell, EmptyPropertyCell) \
|
||||
@ -221,7 +220,7 @@ using v8::MemoryPressureLevel;
|
||||
V(NameDictionary, api_symbol_table, ApiSymbolTable) \
|
||||
V(NameDictionary, api_private_symbol_table, ApiPrivateSymbolTable) \
|
||||
V(Object, script_list, ScriptList) \
|
||||
V(UnseededNumberDictionary, code_stubs, CodeStubs) \
|
||||
V(NumberDictionary, code_stubs, CodeStubs) \
|
||||
V(FixedArray, materialized_objects, MaterializedObjects) \
|
||||
V(FixedArray, microtask_queue, MicrotaskQueue) \
|
||||
V(FixedArray, detached_contexts, DetachedContexts) \
|
||||
@ -342,7 +341,7 @@ using v8::MemoryPressureLevel;
|
||||
V(PropertyArrayMap) \
|
||||
V(ScopeInfoMap) \
|
||||
V(ScriptContextMap) \
|
||||
V(SeededNumberDictionaryMap) \
|
||||
V(NumberDictionaryMap) \
|
||||
V(SharedFunctionInfoMap) \
|
||||
V(SloppyArgumentsElementsMap) \
|
||||
V(SmallOrderedHashMapMap) \
|
||||
@ -362,7 +361,6 @@ using v8::MemoryPressureLevel;
|
||||
V(UndefinedValue) \
|
||||
V(UninitializedMap) \
|
||||
V(UninitializedValue) \
|
||||
V(UnseededNumberDictionaryMap) \
|
||||
V(WeakCellMap) \
|
||||
V(WithContextMap) \
|
||||
PRIVATE_SYMBOL_LIST(V)
|
||||
@ -1051,7 +1049,7 @@ class Heap {
|
||||
Object** roots_array_start() { return roots_; }
|
||||
|
||||
// Sets the stub_cache_ (only used when expanding the dictionary).
|
||||
void SetRootCodeStubs(UnseededNumberDictionary* value);
|
||||
void SetRootCodeStubs(NumberDictionary* value);
|
||||
|
||||
void SetRootMaterializedObjects(FixedArray* objects) {
|
||||
roots_[kMaterializedObjectsRootIndex] = objects;
|
||||
|
@ -367,7 +367,7 @@ void ObjectStatsCollector::RecordJSObjectDetails(JSObject* object) {
|
||||
FixedArrayBase* elements = object->elements();
|
||||
if (CanRecordFixedArray(heap_, elements) && !IsCowArray(heap_, elements)) {
|
||||
if (elements->IsDictionary() && SameLiveness(object, elements)) {
|
||||
SeededNumberDictionary* dict = SeededNumberDictionary::cast(elements);
|
||||
NumberDictionary* dict = NumberDictionary::cast(elements);
|
||||
RecordHashTableHelper(object, dict, DICTIONARY_ELEMENTS_SUB_TYPE);
|
||||
} else {
|
||||
if (IsHoleyElementsKind(object->GetElementsKind())) {
|
||||
|
@ -291,7 +291,6 @@ bool Heap::CreateInitialMaps() {
|
||||
ALLOCATE_VARSIZE_MAP(HASH_TABLE_TYPE, name_dictionary)
|
||||
ALLOCATE_VARSIZE_MAP(HASH_TABLE_TYPE, global_dictionary)
|
||||
ALLOCATE_VARSIZE_MAP(HASH_TABLE_TYPE, seeded_number_dictionary)
|
||||
ALLOCATE_VARSIZE_MAP(HASH_TABLE_TYPE, unseeded_number_dictionary)
|
||||
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, function_context)
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, catch_context)
|
||||
@ -460,7 +459,7 @@ void Heap::CreateInitialObjects() {
|
||||
|
||||
// Create the code_stubs dictionary. The initial size is set to avoid
|
||||
// expanding the dictionary during bootstrapping.
|
||||
set_code_stubs(*UnseededNumberDictionary::New(isolate(), 128));
|
||||
set_code_stubs(*NumberDictionary::New(isolate(), 128));
|
||||
|
||||
{
|
||||
HandleScope scope(isolate());
|
||||
@ -552,9 +551,8 @@ void Heap::CreateInitialObjects() {
|
||||
|
||||
set_script_list(Smi::kZero);
|
||||
|
||||
Handle<SeededNumberDictionary> slow_element_dictionary =
|
||||
SeededNumberDictionary::New(isolate(), 1, TENURED,
|
||||
USE_CUSTOM_MINIMUM_CAPACITY);
|
||||
Handle<NumberDictionary> slow_element_dictionary =
|
||||
NumberDictionary::New(isolate(), 1, TENURED, USE_CUSTOM_MINIMUM_CAPACITY);
|
||||
DCHECK(!slow_element_dictionary->HasSufficientCapacityToAdd(1));
|
||||
slow_element_dictionary->set_requires_slow_elements();
|
||||
set_empty_slow_element_dictionary(*slow_element_dictionary);
|
||||
|
@ -1521,19 +1521,17 @@ void AccessorAssembler::EmitElementLoad(
|
||||
GotoIf(IntPtrLessThan(intptr_index, IntPtrConstant(0)), out_of_bounds);
|
||||
VARIABLE(var_entry, MachineType::PointerRepresentation());
|
||||
Label if_found(this);
|
||||
NumberDictionaryLookup<SeededNumberDictionary>(
|
||||
elements, intptr_index, &if_found, &var_entry, if_hole);
|
||||
NumberDictionaryLookup(elements, intptr_index, &if_found, &var_entry,
|
||||
if_hole);
|
||||
BIND(&if_found);
|
||||
// Check that the value is a data property.
|
||||
Node* index = EntryToIndex<SeededNumberDictionary>(var_entry.value());
|
||||
Node* details =
|
||||
LoadDetailsByKeyIndex<SeededNumberDictionary>(elements, index);
|
||||
Node* index = EntryToIndex<NumberDictionary>(var_entry.value());
|
||||
Node* details = LoadDetailsByKeyIndex<NumberDictionary>(elements, index);
|
||||
Node* kind = DecodeWord32<PropertyDetails::KindField>(details);
|
||||
// TODO(jkummerow): Support accessors without missing?
|
||||
GotoIfNot(Word32Equal(kind, Int32Constant(kData)), miss);
|
||||
// Finally, load the value.
|
||||
exit_point->Return(
|
||||
LoadValueByKeyIndex<SeededNumberDictionary>(elements, index));
|
||||
exit_point->Return(LoadValueByKeyIndex<NumberDictionary>(elements, index));
|
||||
}
|
||||
|
||||
BIND(&if_typed_array);
|
||||
|
@ -705,19 +705,19 @@ class CaptureStackTraceHelper {
|
||||
int code_offset;
|
||||
Handle<ByteArray> source_position_table;
|
||||
Handle<Object> maybe_cache;
|
||||
Handle<UnseededNumberDictionary> cache;
|
||||
Handle<NumberDictionary> cache;
|
||||
if (!FLAG_optimize_for_size) {
|
||||
code_offset = summ.code_offset();
|
||||
source_position_table =
|
||||
handle(summ.abstract_code()->source_position_table(), isolate_);
|
||||
maybe_cache = handle(summ.abstract_code()->stack_frame_cache(), isolate_);
|
||||
if (maybe_cache->IsUnseededNumberDictionary()) {
|
||||
cache = Handle<UnseededNumberDictionary>::cast(maybe_cache);
|
||||
if (maybe_cache->IsNumberDictionary()) {
|
||||
cache = Handle<NumberDictionary>::cast(maybe_cache);
|
||||
} else {
|
||||
cache = UnseededNumberDictionary::New(isolate_, 1);
|
||||
cache = NumberDictionary::New(isolate_, 1);
|
||||
}
|
||||
int entry = cache->FindEntry(code_offset);
|
||||
if (entry != UnseededNumberDictionary::kNotFound) {
|
||||
if (entry != NumberDictionary::kNotFound) {
|
||||
Handle<StackFrameInfo> frame(
|
||||
StackFrameInfo::cast(cache->ValueAt(entry)));
|
||||
DCHECK(frame->function_name()->IsString());
|
||||
@ -747,8 +747,8 @@ class CaptureStackTraceHelper {
|
||||
frame->set_is_constructor(summ.is_constructor());
|
||||
frame->set_is_wasm(false);
|
||||
if (!FLAG_optimize_for_size) {
|
||||
auto new_cache = UnseededNumberDictionary::Set(cache, code_offset, frame);
|
||||
if (*new_cache != *cache || !maybe_cache->IsUnseededNumberDictionary()) {
|
||||
auto new_cache = NumberDictionary::Set(cache, code_offset, frame);
|
||||
if (*new_cache != *cache || !maybe_cache->IsNumberDictionary()) {
|
||||
AbstractCode::SetStackFrameCache(summ.abstract_code(), new_cache);
|
||||
}
|
||||
}
|
||||
|
@ -619,11 +619,10 @@ void LookupIterator::TransitionToAccessorPair(Handle<Object> pair,
|
||||
if (IsElement()) {
|
||||
// TODO(verwaest): Move code into the element accessor.
|
||||
isolate_->CountUsage(v8::Isolate::kIndexAccessor);
|
||||
Handle<SeededNumberDictionary> dictionary =
|
||||
JSObject::NormalizeElements(receiver);
|
||||
Handle<NumberDictionary> dictionary = JSObject::NormalizeElements(receiver);
|
||||
|
||||
dictionary = SeededNumberDictionary::Set(dictionary, index_, pair, receiver,
|
||||
details);
|
||||
dictionary =
|
||||
NumberDictionary::Set(dictionary, index_, pair, receiver, details);
|
||||
receiver->RequireSlowElements(*dictionary);
|
||||
|
||||
if (receiver->HasSlowArgumentsElements()) {
|
||||
|
@ -923,7 +923,7 @@ void JSArray::JSArrayVerify() {
|
||||
CHECK(length()->ToArrayLength(&array_length));
|
||||
}
|
||||
if (array_length != 0) {
|
||||
SeededNumberDictionary* dict = SeededNumberDictionary::cast(elements());
|
||||
NumberDictionary* dict = NumberDictionary::cast(elements());
|
||||
// The dictionary can never have more elements than the array length + 1.
|
||||
// If the backing store grows the verification might be triggered with
|
||||
// the old length in place.
|
||||
@ -1506,7 +1506,7 @@ void JSObject::IncrementSpillStatistics(SpillInformation* info) {
|
||||
}
|
||||
case DICTIONARY_ELEMENTS:
|
||||
case SLOW_STRING_WRAPPER_ELEMENTS: {
|
||||
SeededNumberDictionary* dict = element_dictionary();
|
||||
NumberDictionary* dict = element_dictionary();
|
||||
info->number_of_slow_used_elements_ += dict->NumberOfElements();
|
||||
info->number_of_slow_unused_elements_ +=
|
||||
dict->Capacity() - dict->NumberOfElements();
|
||||
|
@ -432,14 +432,10 @@ bool HeapObject::IsNameDictionary() const {
|
||||
return map() == GetHeap()->name_dictionary_map();
|
||||
}
|
||||
|
||||
bool HeapObject::IsSeededNumberDictionary() const {
|
||||
bool HeapObject::IsNumberDictionary() const {
|
||||
return map() == GetHeap()->seeded_number_dictionary_map();
|
||||
}
|
||||
|
||||
bool HeapObject::IsUnseededNumberDictionary() const {
|
||||
return map() == GetHeap()->unseeded_number_dictionary_map();
|
||||
}
|
||||
|
||||
bool HeapObject::IsStringTable() const { return IsHashTable(); }
|
||||
|
||||
bool HeapObject::IsStringSet() const { return IsHashTable(); }
|
||||
@ -605,7 +601,7 @@ CAST_ACCESSOR(PropertyCell)
|
||||
CAST_ACCESSOR(PrototypeInfo)
|
||||
CAST_ACCESSOR(RegExpMatchInfo)
|
||||
CAST_ACCESSOR(ScopeInfo)
|
||||
CAST_ACCESSOR(SeededNumberDictionary)
|
||||
CAST_ACCESSOR(NumberDictionary)
|
||||
CAST_ACCESSOR(SmallOrderedHashMap)
|
||||
CAST_ACCESSOR(SmallOrderedHashSet)
|
||||
CAST_ACCESSOR(Smi)
|
||||
@ -621,7 +617,6 @@ CAST_ACCESSOR(TemplateObjectDescription)
|
||||
CAST_ACCESSOR(Tuple2)
|
||||
CAST_ACCESSOR(Tuple3)
|
||||
CAST_ACCESSOR(TypeFeedbackInfo)
|
||||
CAST_ACCESSOR(UnseededNumberDictionary)
|
||||
CAST_ACCESSOR(WeakCell)
|
||||
CAST_ACCESSOR(WeakFixedArray)
|
||||
CAST_ACCESSOR(WeakHashTable)
|
||||
@ -1965,10 +1960,9 @@ AllocationAlignment HeapObject::RequiredAlignment() const {
|
||||
|
||||
bool HeapObject::NeedsRehashing() const {
|
||||
switch (map()->instance_type()) {
|
||||
case HASH_TABLE_TYPE:
|
||||
return !IsUnseededNumberDictionary();
|
||||
case TRANSITION_ARRAY_TYPE:
|
||||
return TransitionArray::cast(this)->number_of_entries() > 1;
|
||||
case HASH_TABLE_TYPE:
|
||||
case SMALL_ORDERED_HASH_MAP_TYPE:
|
||||
case SMALL_ORDERED_HASH_SET_TYPE:
|
||||
return true;
|
||||
@ -2505,14 +2499,13 @@ uint32_t StringTableShape::HashForObject(Isolate* isolate, Object* object) {
|
||||
return String::cast(object)->Hash();
|
||||
}
|
||||
|
||||
bool SeededNumberDictionary::requires_slow_elements() {
|
||||
bool NumberDictionary::requires_slow_elements() {
|
||||
Object* max_index_object = get(kMaxNumberKeyIndex);
|
||||
if (!max_index_object->IsSmi()) return false;
|
||||
return 0 != (Smi::ToInt(max_index_object) & kRequiresSlowElementsMask);
|
||||
}
|
||||
|
||||
|
||||
uint32_t SeededNumberDictionary::max_number_key() {
|
||||
uint32_t NumberDictionary::max_number_key() {
|
||||
DCHECK(!requires_slow_elements());
|
||||
Object* max_index_object = get(kMaxNumberKeyIndex);
|
||||
if (!max_index_object->IsSmi()) return 0;
|
||||
@ -2520,8 +2513,7 @@ uint32_t SeededNumberDictionary::max_number_key() {
|
||||
return value >> kRequiresSlowElementsTagSize;
|
||||
}
|
||||
|
||||
|
||||
void SeededNumberDictionary::set_requires_slow_elements() {
|
||||
void NumberDictionary::set_requires_slow_elements() {
|
||||
set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
|
||||
}
|
||||
|
||||
@ -4009,7 +4001,7 @@ SMI_ACCESSORS(StackFrameInfo, id, kIdIndex)
|
||||
ACCESSORS(SourcePositionTableWithFrameCache, source_position_table, ByteArray,
|
||||
kSourcePositionTableIndex)
|
||||
ACCESSORS(SourcePositionTableWithFrameCache, stack_frame_cache,
|
||||
UnseededNumberDictionary, kStackFrameCacheIndex)
|
||||
NumberDictionary, kStackFrameCacheIndex)
|
||||
|
||||
SMI_ACCESSORS(FunctionTemplateInfo, length, kLengthOffset)
|
||||
BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
|
||||
@ -4478,10 +4470,9 @@ GlobalDictionary* JSGlobalObject::global_dictionary() {
|
||||
return GlobalDictionary::cast(raw_properties_or_hash());
|
||||
}
|
||||
|
||||
|
||||
SeededNumberDictionary* JSObject::element_dictionary() {
|
||||
NumberDictionary* JSObject::element_dictionary() {
|
||||
DCHECK(HasDictionaryElements() || HasSlowStringWrapperElements());
|
||||
return SeededNumberDictionary::cast(elements());
|
||||
return NumberDictionary::cast(elements());
|
||||
}
|
||||
|
||||
// static
|
||||
@ -4843,32 +4834,17 @@ bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
|
||||
return key == static_cast<uint32_t>(other->Number());
|
||||
}
|
||||
|
||||
uint32_t UnseededNumberDictionaryShape::Hash(Isolate* isolate, uint32_t key) {
|
||||
return ComputeIntegerHash(key);
|
||||
}
|
||||
|
||||
uint32_t UnseededNumberDictionaryShape::HashForObject(Isolate* isolate,
|
||||
Object* other) {
|
||||
DCHECK(other->IsNumber());
|
||||
return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
|
||||
}
|
||||
|
||||
Map* UnseededNumberDictionaryShape::GetMap(Isolate* isolate) {
|
||||
return isolate->heap()->unseeded_number_dictionary_map();
|
||||
}
|
||||
|
||||
uint32_t SeededNumberDictionaryShape::Hash(Isolate* isolate, uint32_t key) {
|
||||
uint32_t NumberDictionaryShape::Hash(Isolate* isolate, uint32_t key) {
|
||||
return ComputeIntegerHash(key, isolate->heap()->HashSeed());
|
||||
}
|
||||
|
||||
uint32_t SeededNumberDictionaryShape::HashForObject(Isolate* isolate,
|
||||
Object* other) {
|
||||
uint32_t NumberDictionaryShape::HashForObject(Isolate* isolate, Object* other) {
|
||||
DCHECK(other->IsNumber());
|
||||
return ComputeIntegerHash(static_cast<uint32_t>(other->Number()),
|
||||
isolate->heap()->HashSeed());
|
||||
}
|
||||
|
||||
Map* SeededNumberDictionaryShape::GetMap(Isolate* isolate) {
|
||||
Map* NumberDictionaryShape::GetMap(Isolate* isolate) {
|
||||
return isolate->heap()->seeded_number_dictionary_map();
|
||||
}
|
||||
|
||||
|
@ -386,7 +386,7 @@ void PrintFixedArrayElements(std::ostream& os, T* array) {
|
||||
|
||||
void PrintDictionaryElements(std::ostream& os, FixedArrayBase* elements) {
|
||||
// Print some internal fields
|
||||
SeededNumberDictionary* dict = SeededNumberDictionary::cast(elements);
|
||||
NumberDictionary* dict = NumberDictionary::cast(elements);
|
||||
if (dict->requires_slow_elements()) {
|
||||
os << "\n - requires_slow_elements";
|
||||
} else {
|
||||
|
142
src/objects.cc
142
src/objects.cc
@ -3634,8 +3634,7 @@ bool HeapObject::CanBeRehashed() const {
|
||||
DCHECK(NeedsRehashing());
|
||||
switch (map()->instance_type()) {
|
||||
case HASH_TABLE_TYPE:
|
||||
return IsNameDictionary() || IsGlobalDictionary() ||
|
||||
IsSeededNumberDictionary();
|
||||
return IsNameDictionary() || IsGlobalDictionary() || IsNumberDictionary();
|
||||
case TRANSITION_ARRAY_TYPE:
|
||||
return true;
|
||||
case SMALL_ORDERED_HASH_MAP_TYPE:
|
||||
@ -3653,8 +3652,8 @@ void HeapObject::RehashBasedOnMap() {
|
||||
case HASH_TABLE_TYPE:
|
||||
if (IsNameDictionary()) {
|
||||
NameDictionary::cast(this)->Rehash();
|
||||
} else if (IsSeededNumberDictionary()) {
|
||||
SeededNumberDictionary::cast(this)->Rehash();
|
||||
} else if (IsNumberDictionary()) {
|
||||
NumberDictionary::cast(this)->Rehash();
|
||||
} else if (IsGlobalDictionary()) {
|
||||
GlobalDictionary::cast(this)->Rehash();
|
||||
} else {
|
||||
@ -6384,7 +6383,7 @@ void JSObject::MigrateSlowToFast(Handle<JSObject> object,
|
||||
DCHECK(object->HasFastProperties());
|
||||
}
|
||||
|
||||
void JSObject::RequireSlowElements(SeededNumberDictionary* dictionary) {
|
||||
void JSObject::RequireSlowElements(NumberDictionary* dictionary) {
|
||||
if (dictionary->requires_slow_elements()) return;
|
||||
dictionary->set_requires_slow_elements();
|
||||
if (map()->is_prototype_map()) {
|
||||
@ -6394,9 +6393,7 @@ void JSObject::RequireSlowElements(SeededNumberDictionary* dictionary) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Handle<SeededNumberDictionary> JSObject::NormalizeElements(
|
||||
Handle<JSObject> object) {
|
||||
Handle<NumberDictionary> JSObject::NormalizeElements(Handle<JSObject> object) {
|
||||
DCHECK(!object->HasFixedTypedArrayElements());
|
||||
Isolate* isolate = object->GetIsolate();
|
||||
bool is_sloppy_arguments = object->HasSloppyArgumentsElements();
|
||||
@ -6409,7 +6406,7 @@ Handle<SeededNumberDictionary> JSObject::NormalizeElements(
|
||||
}
|
||||
|
||||
if (elements->IsDictionary()) {
|
||||
return handle(SeededNumberDictionary::cast(elements), isolate);
|
||||
return handle(NumberDictionary::cast(elements), isolate);
|
||||
}
|
||||
}
|
||||
|
||||
@ -6417,7 +6414,7 @@ Handle<SeededNumberDictionary> JSObject::NormalizeElements(
|
||||
object->HasFastArgumentsElements() ||
|
||||
object->HasFastStringWrapperElements());
|
||||
|
||||
Handle<SeededNumberDictionary> dictionary =
|
||||
Handle<NumberDictionary> dictionary =
|
||||
object->GetElementsAccessor()->Normalize(object);
|
||||
|
||||
// Switch to using the dictionary as the backing storage for elements.
|
||||
@ -7877,8 +7874,7 @@ bool JSObject::ReferencesObjectFromElements(FixedArray* elements,
|
||||
}
|
||||
} else {
|
||||
DCHECK(kind == DICTIONARY_ELEMENTS || kind == SLOW_STRING_WRAPPER_ELEMENTS);
|
||||
Object* key =
|
||||
SeededNumberDictionary::cast(elements)->SlowReverseLookup(object);
|
||||
Object* key = NumberDictionary::cast(elements)->SlowReverseLookup(object);
|
||||
if (!key->IsUndefined(isolate)) return true;
|
||||
}
|
||||
return false;
|
||||
@ -8128,7 +8124,7 @@ bool TestElementsIntegrityLevel(JSObject* object, PropertyAttributes level) {
|
||||
|
||||
if (IsDictionaryElementsKind(kind)) {
|
||||
return TestDictionaryPropertiesIntegrityLevel(
|
||||
SeededNumberDictionary::cast(object->elements()), object->GetIsolate(),
|
||||
NumberDictionary::cast(object->elements()), object->GetIsolate(),
|
||||
level);
|
||||
}
|
||||
|
||||
@ -8290,7 +8286,7 @@ Maybe<bool> JSObject::PreventExtensions(Handle<JSObject> object,
|
||||
|
||||
if (!object->HasFixedTypedArrayElements()) {
|
||||
// If there are fast elements we normalize.
|
||||
Handle<SeededNumberDictionary> dictionary = NormalizeElements(object);
|
||||
Handle<NumberDictionary> dictionary = NormalizeElements(object);
|
||||
DCHECK(object->HasDictionaryElements() ||
|
||||
object->HasSlowArgumentsElements());
|
||||
|
||||
@ -8446,7 +8442,7 @@ Maybe<bool> JSObject::PreventExtensionsWithTransition(
|
||||
RETURN_FAILURE(isolate, should_throw, NewTypeError(message));
|
||||
}
|
||||
|
||||
Handle<SeededNumberDictionary> new_element_dictionary;
|
||||
Handle<NumberDictionary> new_element_dictionary;
|
||||
if (!object->HasFixedTypedArrayElements() &&
|
||||
!object->HasDictionaryElements() &&
|
||||
!object->HasSlowStringWrapperElements()) {
|
||||
@ -8535,8 +8531,7 @@ Maybe<bool> JSObject::PreventExtensionsWithTransition(
|
||||
}
|
||||
|
||||
if (object->elements() != isolate->heap()->empty_slow_element_dictionary()) {
|
||||
Handle<SeededNumberDictionary> dictionary(object->element_dictionary(),
|
||||
isolate);
|
||||
Handle<NumberDictionary> dictionary(object->element_dictionary(), isolate);
|
||||
// Make sure we never go back to the fast case
|
||||
object->RequireSlowElements(*dictionary);
|
||||
if (attrs != NONE) {
|
||||
@ -8668,8 +8663,7 @@ bool JSObject::HasEnumerableElements() {
|
||||
return length > 0;
|
||||
}
|
||||
case DICTIONARY_ELEMENTS: {
|
||||
SeededNumberDictionary* elements =
|
||||
SeededNumberDictionary::cast(object->elements());
|
||||
NumberDictionary* elements = NumberDictionary::cast(object->elements());
|
||||
return elements->NumberOfEnumerableProperties() > 0;
|
||||
}
|
||||
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
|
||||
@ -8886,7 +8880,7 @@ bool Map::DictionaryElementsInPrototypeChainOnly() {
|
||||
if (current->HasSlowArgumentsElements()) {
|
||||
FixedArray* parameter_map = FixedArray::cast(current->elements());
|
||||
Object* arguments = parameter_map->get(1);
|
||||
if (SeededNumberDictionary::cast(arguments)->requires_slow_elements()) {
|
||||
if (NumberDictionary::cast(arguments)->requires_slow_elements()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -13942,7 +13936,7 @@ SafepointEntry Code::GetSafepointEntry(Address pc) {
|
||||
namespace {
|
||||
template <typename Code>
|
||||
void SetStackFrameCacheCommon(Handle<Code> code,
|
||||
Handle<UnseededNumberDictionary> cache) {
|
||||
Handle<NumberDictionary> cache) {
|
||||
Handle<Object> maybe_table(code->source_position_table(), code->GetIsolate());
|
||||
if (maybe_table->IsSourcePositionTableWithFrameCache()) {
|
||||
Handle<SourcePositionTableWithFrameCache>::cast(maybe_table)
|
||||
@ -13960,7 +13954,7 @@ void SetStackFrameCacheCommon(Handle<Code> code,
|
||||
|
||||
// static
|
||||
void AbstractCode::SetStackFrameCache(Handle<AbstractCode> abstract_code,
|
||||
Handle<UnseededNumberDictionary> cache) {
|
||||
Handle<NumberDictionary> cache) {
|
||||
if (abstract_code->IsCode()) {
|
||||
SetStackFrameCacheCommon(handle(abstract_code->GetCode()), cache);
|
||||
} else {
|
||||
@ -15184,10 +15178,9 @@ static bool ShouldConvertToSlowElements(JSObject* object, uint32_t capacity,
|
||||
// If the fast-case backing storage takes up much more memory than a
|
||||
// dictionary backing storage would, the object should have slow elements.
|
||||
int used_elements = object->GetFastElementsUsage();
|
||||
uint32_t size_threshold =
|
||||
SeededNumberDictionary::kPreferFastElementsSizeFactor *
|
||||
SeededNumberDictionary::ComputeCapacity(used_elements) *
|
||||
SeededNumberDictionary::kEntrySize;
|
||||
uint32_t size_threshold = NumberDictionary::kPreferFastElementsSizeFactor *
|
||||
NumberDictionary::ComputeCapacity(used_elements) *
|
||||
NumberDictionary::kEntrySize;
|
||||
return size_threshold <= *new_capacity;
|
||||
}
|
||||
|
||||
@ -15211,7 +15204,7 @@ static ElementsKind BestFittingFastElementsKind(JSObject* object) {
|
||||
return FAST_STRING_WRAPPER_ELEMENTS;
|
||||
}
|
||||
DCHECK(object->HasDictionaryElements());
|
||||
SeededNumberDictionary* dictionary = object->element_dictionary();
|
||||
NumberDictionary* dictionary = object->element_dictionary();
|
||||
ElementsKind kind = HOLEY_SMI_ELEMENTS;
|
||||
for (int i = 0; i < dictionary->Capacity(); i++) {
|
||||
Object* key = dictionary->KeyAt(i);
|
||||
@ -15227,9 +15220,8 @@ static ElementsKind BestFittingFastElementsKind(JSObject* object) {
|
||||
return kind;
|
||||
}
|
||||
|
||||
|
||||
static bool ShouldConvertToFastElements(JSObject* object,
|
||||
SeededNumberDictionary* dictionary,
|
||||
NumberDictionary* dictionary,
|
||||
uint32_t index,
|
||||
uint32_t* new_capacity) {
|
||||
// If properties with non-standard attributes or accessors were added, we
|
||||
@ -15251,7 +15243,7 @@ static bool ShouldConvertToFastElements(JSObject* object,
|
||||
*new_capacity = Max(index + 1, *new_capacity);
|
||||
|
||||
uint32_t dictionary_size = static_cast<uint32_t>(dictionary->Capacity()) *
|
||||
SeededNumberDictionary::kEntrySize;
|
||||
NumberDictionary::kEntrySize;
|
||||
|
||||
// Turn fast if the dictionary only saves 50% space.
|
||||
return 2 * dictionary_size >= *new_capacity;
|
||||
@ -15297,10 +15289,9 @@ Maybe<bool> JSObject::AddDataElement(Handle<JSObject> object, uint32_t index,
|
||||
|
||||
if (attributes != NONE) {
|
||||
kind = dictionary_kind;
|
||||
} else if (elements->IsSeededNumberDictionary()) {
|
||||
kind = ShouldConvertToFastElements(*object,
|
||||
SeededNumberDictionary::cast(elements),
|
||||
index, &new_capacity)
|
||||
} else if (elements->IsNumberDictionary()) {
|
||||
kind = ShouldConvertToFastElements(
|
||||
*object, NumberDictionary::cast(elements), index, &new_capacity)
|
||||
? BestFittingFastElementsKind(*object)
|
||||
: dictionary_kind;
|
||||
} else if (ShouldConvertToSlowElements(
|
||||
@ -16322,14 +16313,11 @@ template class Dictionary<NameDictionary, NameDictionaryShape>;
|
||||
|
||||
template class Dictionary<GlobalDictionary, GlobalDictionaryShape>;
|
||||
|
||||
template class EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
|
||||
HashTable<SeededNumberDictionary, SeededNumberDictionaryShape>;
|
||||
template class EXPORT_TEMPLATE_DEFINE(
|
||||
V8_EXPORT_PRIVATE) HashTable<NumberDictionary, NumberDictionaryShape>;
|
||||
|
||||
template class EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
|
||||
Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape>;
|
||||
|
||||
template class Dictionary<UnseededNumberDictionary,
|
||||
UnseededNumberDictionaryShape>;
|
||||
Dictionary<NumberDictionary, NumberDictionaryShape>;
|
||||
|
||||
template Handle<NameDictionary>
|
||||
BaseNameDictionary<NameDictionary, NameDictionaryShape>::New(
|
||||
@ -16339,19 +16327,12 @@ template Handle<GlobalDictionary>
|
||||
BaseNameDictionary<GlobalDictionary, GlobalDictionaryShape>::New(
|
||||
Isolate*, int n, PretenureFlag pretenure, MinimumCapacity capacity_option);
|
||||
|
||||
template Handle<SeededNumberDictionary>
|
||||
Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape>::AtPut(
|
||||
Handle<SeededNumberDictionary>, uint32_t, Handle<Object>,
|
||||
PropertyDetails);
|
||||
template Handle<NumberDictionary>
|
||||
Dictionary<NumberDictionary, NumberDictionaryShape>::AtPut(
|
||||
Handle<NumberDictionary>, uint32_t, Handle<Object>, PropertyDetails);
|
||||
|
||||
template Handle<UnseededNumberDictionary>
|
||||
Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape>::AtPut(
|
||||
Handle<UnseededNumberDictionary>, uint32_t, Handle<Object>,
|
||||
PropertyDetails);
|
||||
|
||||
template Object*
|
||||
Dictionary<SeededNumberDictionary,
|
||||
SeededNumberDictionaryShape>::SlowReverseLookup(Object* value);
|
||||
template Object* Dictionary<
|
||||
NumberDictionary, NumberDictionaryShape>::SlowReverseLookup(Object* value);
|
||||
|
||||
template Object* Dictionary<
|
||||
NameDictionary, NameDictionaryShape>::SlowReverseLookup(Object* value);
|
||||
@ -16360,17 +16341,9 @@ template Handle<NameDictionary>
|
||||
Dictionary<NameDictionary, NameDictionaryShape>::DeleteEntry(
|
||||
Handle<NameDictionary>, int);
|
||||
|
||||
template Handle<SeededNumberDictionary>
|
||||
Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape>::DeleteEntry(
|
||||
Handle<SeededNumberDictionary>, int);
|
||||
|
||||
template Handle<UnseededNumberDictionary>
|
||||
Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape>::
|
||||
DeleteEntry(Handle<UnseededNumberDictionary>, int);
|
||||
|
||||
template Handle<UnseededNumberDictionary>
|
||||
HashTable<UnseededNumberDictionary, UnseededNumberDictionaryShape>::New(
|
||||
Isolate*, int, PretenureFlag, MinimumCapacity);
|
||||
template Handle<NumberDictionary>
|
||||
Dictionary<NumberDictionary, NumberDictionaryShape>::DeleteEntry(
|
||||
Handle<NumberDictionary>, int);
|
||||
|
||||
template Handle<NameDictionary>
|
||||
HashTable<NameDictionary, NameDictionaryShape>::New(Isolate*, int,
|
||||
@ -16385,10 +16358,6 @@ HashTable<ObjectHashSet, ObjectHashSetShape>::New(Isolate*, int n,
|
||||
template Handle<NameDictionary> HashTable<
|
||||
NameDictionary, NameDictionaryShape>::Shrink(Handle<NameDictionary>);
|
||||
|
||||
template Handle<UnseededNumberDictionary>
|
||||
HashTable<UnseededNumberDictionary, UnseededNumberDictionaryShape>::Shrink(
|
||||
Handle<UnseededNumberDictionary>);
|
||||
|
||||
template Handle<NameDictionary>
|
||||
BaseNameDictionary<NameDictionary, NameDictionaryShape>::Add(
|
||||
Handle<NameDictionary>, Handle<Name>, Handle<Object>, PropertyDetails,
|
||||
@ -16401,15 +16370,9 @@ BaseNameDictionary<GlobalDictionary, GlobalDictionaryShape>::Add(
|
||||
|
||||
template void HashTable<GlobalDictionary, GlobalDictionaryShape>::Rehash();
|
||||
|
||||
template Handle<SeededNumberDictionary>
|
||||
Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape>::Add(
|
||||
Handle<SeededNumberDictionary>, uint32_t, Handle<Object>, PropertyDetails,
|
||||
int*);
|
||||
|
||||
template Handle<UnseededNumberDictionary>
|
||||
Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape>::Add(
|
||||
Handle<UnseededNumberDictionary>, uint32_t, Handle<Object>, PropertyDetails,
|
||||
int*);
|
||||
template Handle<NumberDictionary>
|
||||
Dictionary<NumberDictionary, NumberDictionaryShape>::Add(
|
||||
Handle<NumberDictionary>, uint32_t, Handle<Object>, PropertyDetails, int*);
|
||||
|
||||
template Handle<NameDictionary>
|
||||
BaseNameDictionary<NameDictionary, NameDictionaryShape>::EnsureCapacity(
|
||||
@ -16445,9 +16408,8 @@ template void
|
||||
BaseNameDictionary<NameDictionary, NameDictionaryShape>::CollectKeysTo(
|
||||
Handle<NameDictionary> dictionary, KeyAccumulator* keys);
|
||||
|
||||
template int
|
||||
Dictionary<SeededNumberDictionary,
|
||||
SeededNumberDictionaryShape>::NumberOfEnumerableProperties();
|
||||
template int Dictionary<NumberDictionary,
|
||||
NumberDictionaryShape>::NumberOfEnumerableProperties();
|
||||
|
||||
namespace {
|
||||
|
||||
@ -17478,7 +17440,7 @@ Handle<Derived> Dictionary<Derived, Shape>::Add(Handle<Derived> dictionary,
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
bool SeededNumberDictionary::HasComplexElements() {
|
||||
bool NumberDictionary::HasComplexElements() {
|
||||
if (!requires_slow_elements()) return false;
|
||||
Isolate* isolate = this->GetIsolate();
|
||||
int capacity = this->Capacity();
|
||||
@ -17493,8 +17455,8 @@ bool SeededNumberDictionary::HasComplexElements() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void SeededNumberDictionary::UpdateMaxNumberKey(
|
||||
uint32_t key, Handle<JSObject> dictionary_holder) {
|
||||
void NumberDictionary::UpdateMaxNumberKey(uint32_t key,
|
||||
Handle<JSObject> dictionary_holder) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
// If the dictionary requires slow elements an element has already
|
||||
// been added at a high index.
|
||||
@ -17516,15 +17478,14 @@ void SeededNumberDictionary::UpdateMaxNumberKey(
|
||||
}
|
||||
}
|
||||
|
||||
Handle<SeededNumberDictionary> SeededNumberDictionary::Set(
|
||||
Handle<SeededNumberDictionary> dictionary, uint32_t key,
|
||||
Handle<Object> value, Handle<JSObject> dictionary_holder,
|
||||
PropertyDetails details) {
|
||||
Handle<NumberDictionary> NumberDictionary::Set(
|
||||
Handle<NumberDictionary> dictionary, uint32_t key, Handle<Object> value,
|
||||
Handle<JSObject> dictionary_holder, PropertyDetails details) {
|
||||
dictionary->UpdateMaxNumberKey(key, dictionary_holder);
|
||||
return AtPut(dictionary, key, value, details);
|
||||
}
|
||||
|
||||
void SeededNumberDictionary::CopyValuesTo(FixedArray* elements) {
|
||||
void NumberDictionary::CopyValuesTo(FixedArray* elements) {
|
||||
Isolate* isolate = this->GetIsolate();
|
||||
int pos = 0;
|
||||
int capacity = this->Capacity();
|
||||
@ -17539,13 +17500,6 @@ void SeededNumberDictionary::CopyValuesTo(FixedArray* elements) {
|
||||
DCHECK_EQ(pos, elements->length());
|
||||
}
|
||||
|
||||
Handle<UnseededNumberDictionary> UnseededNumberDictionary::Set(
|
||||
Handle<UnseededNumberDictionary> dictionary,
|
||||
uint32_t key,
|
||||
Handle<Object> value) {
|
||||
return AtPut(dictionary, key, value, PropertyDetails::Empty());
|
||||
}
|
||||
|
||||
template <typename Derived, typename Shape>
|
||||
int Dictionary<Derived, Shape>::NumberOfEnumerableProperties() {
|
||||
Isolate* isolate = this->GetIsolate();
|
||||
|
@ -1071,7 +1071,7 @@ template <class C> inline bool Is(Object* obj);
|
||||
V(RegExpMatchInfo) \
|
||||
V(ScopeInfo) \
|
||||
V(ScriptContextTable) \
|
||||
V(SeededNumberDictionary) \
|
||||
V(NumberDictionary) \
|
||||
V(SeqOneByteString) \
|
||||
V(SeqString) \
|
||||
V(SeqTwoByteString) \
|
||||
@ -1096,7 +1096,6 @@ template <class C> inline bool Is(Object* obj);
|
||||
V(TypeFeedbackInfo) \
|
||||
V(Undetectable) \
|
||||
V(UniqueName) \
|
||||
V(UnseededNumberDictionary) \
|
||||
V(WasmInstanceObject) \
|
||||
V(WasmMemoryObject) \
|
||||
V(WasmModuleObject) \
|
||||
@ -2290,7 +2289,7 @@ class JSObject: public JSReceiver {
|
||||
inline bool HasSlowStringWrapperElements();
|
||||
bool HasEnumerableElements();
|
||||
|
||||
inline SeededNumberDictionary* element_dictionary(); // Gets slow elements.
|
||||
inline NumberDictionary* element_dictionary(); // Gets slow elements.
|
||||
|
||||
// Requires: HasFastElements().
|
||||
static void EnsureWritableFastElements(Handle<JSObject> object);
|
||||
@ -2525,11 +2524,10 @@ class JSObject: public JSReceiver {
|
||||
const char* reason);
|
||||
|
||||
// Convert and update the elements backing store to be a
|
||||
// SeededNumberDictionary dictionary. Returns the backing after conversion.
|
||||
static Handle<SeededNumberDictionary> NormalizeElements(
|
||||
Handle<JSObject> object);
|
||||
// NumberDictionary dictionary. Returns the backing after conversion.
|
||||
static Handle<NumberDictionary> NormalizeElements(Handle<JSObject> object);
|
||||
|
||||
void RequireSlowElements(SeededNumberDictionary* dictionary);
|
||||
void RequireSlowElements(NumberDictionary* dictionary);
|
||||
|
||||
// Transform slow named properties to fast variants.
|
||||
static void MigrateSlowToFast(Handle<JSObject> object,
|
||||
@ -5664,7 +5662,7 @@ class StackFrameInfo : public Struct {
|
||||
class SourcePositionTableWithFrameCache : public Tuple2 {
|
||||
public:
|
||||
DECL_ACCESSORS(source_position_table, ByteArray)
|
||||
DECL_ACCESSORS(stack_frame_cache, UnseededNumberDictionary)
|
||||
DECL_ACCESSORS(stack_frame_cache, NumberDictionary)
|
||||
|
||||
DECL_CAST(SourcePositionTableWithFrameCache)
|
||||
|
||||
|
@ -580,7 +580,7 @@ class AbstractCode : public HeapObject {
|
||||
|
||||
inline Object* stack_frame_cache();
|
||||
static void SetStackFrameCache(Handle<AbstractCode> abstract_code,
|
||||
Handle<UnseededNumberDictionary> cache);
|
||||
Handle<NumberDictionary> cache);
|
||||
void DropStackFrameCache();
|
||||
|
||||
// Returns the size of instructions and the metadata.
|
||||
|
@ -225,60 +225,34 @@ class GlobalDictionary
|
||||
};
|
||||
|
||||
class NumberDictionaryShape : public BaseDictionaryShape<uint32_t> {
|
||||
public:
|
||||
static inline bool IsMatch(uint32_t key, Object* other);
|
||||
static inline Handle<Object> AsHandle(Isolate* isolate, uint32_t key);
|
||||
};
|
||||
|
||||
class SeededNumberDictionaryShape : public NumberDictionaryShape {
|
||||
public:
|
||||
static const int kPrefixSize = 1;
|
||||
static const int kEntrySize = 3;
|
||||
|
||||
static inline bool IsMatch(uint32_t key, Object* other);
|
||||
static inline Handle<Object> AsHandle(Isolate* isolate, uint32_t key);
|
||||
|
||||
static inline uint32_t Hash(Isolate* isolate, uint32_t key);
|
||||
static inline uint32_t HashForObject(Isolate* isolate, Object* object);
|
||||
|
||||
static inline Map* GetMap(Isolate* isolate);
|
||||
};
|
||||
|
||||
class UnseededNumberDictionaryShape : public NumberDictionaryShape {
|
||||
public:
|
||||
static const bool kHasDetails = false;
|
||||
static const int kPrefixSize = 0;
|
||||
static const int kEntrySize = 2;
|
||||
|
||||
static inline uint32_t Hash(Isolate* isolate, uint32_t key);
|
||||
static inline uint32_t HashForObject(Isolate* isolate, Object* object);
|
||||
|
||||
template <typename Dictionary>
|
||||
static inline PropertyDetails DetailsAt(Dictionary* dict, int entry) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
template <typename Dictionary>
|
||||
static inline void DetailsAtPut(Dictionary* dict, int entry,
|
||||
PropertyDetails value) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
static inline Map* GetMap(Isolate* isolate);
|
||||
};
|
||||
extern template class EXPORT_TEMPLATE_DECLARE(
|
||||
V8_EXPORT_PRIVATE) HashTable<NumberDictionary, NumberDictionaryShape>;
|
||||
|
||||
extern template class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
|
||||
HashTable<SeededNumberDictionary, SeededNumberDictionaryShape>;
|
||||
Dictionary<NumberDictionary, NumberDictionaryShape>;
|
||||
|
||||
extern template class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
|
||||
Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape>;
|
||||
|
||||
class SeededNumberDictionary
|
||||
: public Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape> {
|
||||
class NumberDictionary
|
||||
: public Dictionary<NumberDictionary, NumberDictionaryShape> {
|
||||
public:
|
||||
DECL_CAST(SeededNumberDictionary)
|
||||
DECL_CAST(NumberDictionary)
|
||||
|
||||
// Type specific at put (default NONE attributes is used when adding).
|
||||
MUST_USE_RESULT static Handle<SeededNumberDictionary> Set(
|
||||
Handle<SeededNumberDictionary> dictionary, uint32_t key,
|
||||
Handle<Object> value, Handle<JSObject> dictionary_holder,
|
||||
MUST_USE_RESULT static Handle<NumberDictionary> Set(
|
||||
Handle<NumberDictionary> dictionary, uint32_t key, Handle<Object> value,
|
||||
Handle<JSObject> dictionary_holder = Handle<JSObject>::null(),
|
||||
PropertyDetails details = PropertyDetails::Empty());
|
||||
|
||||
static const int kMaxNumberKeyIndex = kPrefixStartIndex;
|
||||
@ -317,20 +291,6 @@ class SeededNumberDictionary
|
||||
static const uint32_t kPreferFastElementsSizeFactor = 3;
|
||||
};
|
||||
|
||||
class UnseededNumberDictionary
|
||||
: public Dictionary<UnseededNumberDictionary,
|
||||
UnseededNumberDictionaryShape> {
|
||||
public:
|
||||
DECL_CAST(UnseededNumberDictionary)
|
||||
|
||||
// Type specific at put (default NONE attributes is used when adding).
|
||||
MUST_USE_RESULT static Handle<UnseededNumberDictionary> Set(
|
||||
Handle<UnseededNumberDictionary> dictionary, uint32_t key,
|
||||
Handle<Object> value);
|
||||
|
||||
static const int kEntryValueIndex = 1;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
|
@ -1463,7 +1463,7 @@ void V8HeapExplorer::ExtractElementReferences(JSObject* js_obj, int entry) {
|
||||
}
|
||||
}
|
||||
} else if (js_obj->HasDictionaryElements()) {
|
||||
SeededNumberDictionary* dictionary = js_obj->element_dictionary();
|
||||
NumberDictionary* dictionary = js_obj->element_dictionary();
|
||||
int length = dictionary->Capacity();
|
||||
for (int i = 0; i < length; ++i) {
|
||||
Object* k = dictionary->KeyAt(i);
|
||||
|
@ -37,9 +37,9 @@ Object* PrepareSlowElementsForSort(Handle<JSObject> object, uint32_t limit) {
|
||||
// Must stay in dictionary mode, either because of requires_slow_elements,
|
||||
// or because we are not going to sort (and therefore compact) all of the
|
||||
// elements.
|
||||
Handle<SeededNumberDictionary> dict(object->element_dictionary(), isolate);
|
||||
Handle<SeededNumberDictionary> new_dict =
|
||||
SeededNumberDictionary::New(isolate, dict->NumberOfElements());
|
||||
Handle<NumberDictionary> dict(object->element_dictionary(), isolate);
|
||||
Handle<NumberDictionary> new_dict =
|
||||
NumberDictionary::New(isolate, dict->NumberOfElements());
|
||||
|
||||
uint32_t pos = 0;
|
||||
uint32_t undefs = 0;
|
||||
@ -70,7 +70,7 @@ Object* PrepareSlowElementsForSort(Handle<JSObject> object, uint32_t limit) {
|
||||
undefs++;
|
||||
} else {
|
||||
Handle<Object> result =
|
||||
SeededNumberDictionary::Add(new_dict, pos, value, details);
|
||||
NumberDictionary::Add(new_dict, pos, value, details);
|
||||
// Add should not grow the dictionary since we allocated the right size.
|
||||
DCHECK(result.is_identical_to(new_dict));
|
||||
USE(result);
|
||||
@ -78,7 +78,7 @@ Object* PrepareSlowElementsForSort(Handle<JSObject> object, uint32_t limit) {
|
||||
}
|
||||
} else {
|
||||
Handle<Object> result =
|
||||
SeededNumberDictionary::Add(new_dict, key, value, details);
|
||||
NumberDictionary::Add(new_dict, key, value, details);
|
||||
// Add should not grow the dictionary since we allocated the right size.
|
||||
DCHECK(result.is_identical_to(new_dict));
|
||||
USE(result);
|
||||
@ -95,7 +95,7 @@ Object* PrepareSlowElementsForSort(Handle<JSObject> object, uint32_t limit) {
|
||||
return bailout;
|
||||
}
|
||||
HandleScope scope(isolate);
|
||||
Handle<Object> result = SeededNumberDictionary::Add(
|
||||
Handle<Object> result = NumberDictionary::Add(
|
||||
new_dict, pos, isolate->factory()->undefined_value(), no_details);
|
||||
// Add should not grow the dictionary since we allocated the right size.
|
||||
DCHECK(result.is_identical_to(new_dict));
|
||||
@ -130,7 +130,7 @@ Object* PrepareElementsForSort(Handle<JSObject> object, uint32_t limit) {
|
||||
if (object->HasDictionaryElements()) {
|
||||
// Convert to fast elements containing only the existing properties.
|
||||
// Ordering is irrelevant, since we are going to sort anyway.
|
||||
Handle<SeededNumberDictionary> dict(object->element_dictionary());
|
||||
Handle<NumberDictionary> dict(object->element_dictionary());
|
||||
if (object->IsJSArray() || dict->requires_slow_elements() ||
|
||||
dict->max_number_key() >= limit) {
|
||||
return PrepareSlowElementsForSort(object, limit);
|
||||
@ -294,7 +294,7 @@ RUNTIME_FUNCTION(Runtime_EstimateNumberOfElements) {
|
||||
FixedArrayBase* elements = array->elements();
|
||||
SealHandleScope shs(isolate);
|
||||
if (elements->IsDictionary()) {
|
||||
int result = SeededNumberDictionary::cast(elements)->NumberOfElements();
|
||||
int result = NumberDictionary::cast(elements)->NumberOfElements();
|
||||
return Smi::FromInt(result);
|
||||
} else {
|
||||
DCHECK(array->length()->IsSmi());
|
||||
|
@ -165,8 +165,7 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
|
||||
break;
|
||||
}
|
||||
case DICTIONARY_ELEMENTS: {
|
||||
Handle<SeededNumberDictionary> element_dictionary(
|
||||
copy->element_dictionary());
|
||||
Handle<NumberDictionary> element_dictionary(copy->element_dictionary());
|
||||
int capacity = element_dictionary->Capacity();
|
||||
for (int i = 0; i < capacity; i++) {
|
||||
Object* raw = element_dictionary->ValueAt(i);
|
||||
|
@ -1086,13 +1086,13 @@ bool ValueDeserializer::ReadRawBytes(size_t length, const void** data) {
|
||||
void ValueDeserializer::TransferArrayBuffer(
|
||||
uint32_t transfer_id, Handle<JSArrayBuffer> array_buffer) {
|
||||
if (array_buffer_transfer_map_.is_null()) {
|
||||
array_buffer_transfer_map_ = isolate_->global_handles()->Create(
|
||||
*UnseededNumberDictionary::New(isolate_, 0));
|
||||
array_buffer_transfer_map_ =
|
||||
isolate_->global_handles()->Create(*NumberDictionary::New(isolate_, 0));
|
||||
}
|
||||
Handle<UnseededNumberDictionary> dictionary =
|
||||
Handle<NumberDictionary> dictionary =
|
||||
array_buffer_transfer_map_.ToHandleChecked();
|
||||
Handle<UnseededNumberDictionary> new_dictionary =
|
||||
UnseededNumberDictionary::Set(dictionary, transfer_id, array_buffer);
|
||||
Handle<NumberDictionary> new_dictionary =
|
||||
NumberDictionary::Set(dictionary, transfer_id, array_buffer);
|
||||
if (!new_dictionary.is_identical_to(dictionary)) {
|
||||
GlobalHandles::Destroy(Handle<Object>::cast(dictionary).location());
|
||||
array_buffer_transfer_map_ =
|
||||
@ -1601,13 +1601,13 @@ MaybeHandle<JSArrayBuffer> ValueDeserializer::ReadTransferredJSArrayBuffer(
|
||||
bool is_shared) {
|
||||
uint32_t id = next_id_++;
|
||||
uint32_t transfer_id;
|
||||
Handle<UnseededNumberDictionary> transfer_map;
|
||||
Handle<NumberDictionary> transfer_map;
|
||||
if (!ReadVarint<uint32_t>().To(&transfer_id) ||
|
||||
!array_buffer_transfer_map_.ToHandle(&transfer_map)) {
|
||||
return MaybeHandle<JSArrayBuffer>();
|
||||
}
|
||||
int index = transfer_map->FindEntry(isolate_, transfer_id);
|
||||
if (index == UnseededNumberDictionary::kNotFound) {
|
||||
if (index == NumberDictionary::kNotFound) {
|
||||
return MaybeHandle<JSArrayBuffer>();
|
||||
}
|
||||
Handle<JSArrayBuffer> array_buffer(
|
||||
|
@ -300,7 +300,7 @@ class ValueDeserializer {
|
||||
|
||||
// Always global handles.
|
||||
Handle<FixedArray> id_map_;
|
||||
MaybeHandle<UnseededNumberDictionary> array_buffer_transfer_map_;
|
||||
MaybeHandle<NumberDictionary> array_buffer_transfer_map_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ValueDeserializer);
|
||||
};
|
||||
|
@ -657,10 +657,7 @@ TEST(NameDictionaryLookup) { TestNameDictionaryLookup<NameDictionary>(); }
|
||||
|
||||
TEST(GlobalDictionaryLookup) { TestNameDictionaryLookup<GlobalDictionary>(); }
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename Dictionary>
|
||||
void TestNumberDictionaryLookup() {
|
||||
TEST(NumberDictionaryLookup) {
|
||||
Isolate* isolate(CcTest::InitIsolateOnce());
|
||||
|
||||
const int kNumParams = 4;
|
||||
@ -678,8 +675,8 @@ void TestNumberDictionaryLookup() {
|
||||
Label if_found(&m), if_not_found(&m);
|
||||
Variable var_entry(&m, MachineType::PointerRepresentation());
|
||||
|
||||
m.NumberDictionaryLookup<Dictionary>(dictionary, key, &if_found, &var_entry,
|
||||
&if_not_found);
|
||||
m.NumberDictionaryLookup(dictionary, key, &if_found, &var_entry,
|
||||
&if_not_found);
|
||||
m.BIND(&if_found);
|
||||
m.GotoIfNot(
|
||||
m.WordEqual(expected_result, m.SmiConstant(Smi::FromInt(kFound))),
|
||||
@ -705,7 +702,8 @@ void TestNumberDictionaryLookup() {
|
||||
Handle<Object> expect_not_found(Smi::FromInt(kNotFound), isolate);
|
||||
|
||||
const int kKeysCount = 1000;
|
||||
Handle<Dictionary> dictionary = Dictionary::New(isolate, kKeysCount);
|
||||
Handle<NumberDictionary> dictionary =
|
||||
NumberDictionary::New(isolate, kKeysCount);
|
||||
uint32_t keys[kKeysCount];
|
||||
|
||||
Handle<Object> fake_value(Smi::FromInt(42), isolate);
|
||||
@ -716,15 +714,16 @@ void TestNumberDictionaryLookup() {
|
||||
for (int i = 0; i < kKeysCount; i++) {
|
||||
int random_key = rand_gen.NextInt(Smi::kMaxValue);
|
||||
keys[i] = static_cast<uint32_t>(random_key);
|
||||
if (dictionary->FindEntry(keys[i]) != Dictionary::kNotFound) continue;
|
||||
if (dictionary->FindEntry(keys[i]) != NumberDictionary::kNotFound) continue;
|
||||
|
||||
dictionary = Dictionary::Add(dictionary, keys[i], fake_value, fake_details);
|
||||
dictionary =
|
||||
NumberDictionary::Add(dictionary, keys[i], fake_value, fake_details);
|
||||
}
|
||||
|
||||
// Now try querying existing keys.
|
||||
for (int i = 0; i < kKeysCount; i++) {
|
||||
int entry = dictionary->FindEntry(keys[i]);
|
||||
CHECK_NE(Dictionary::kNotFound, entry);
|
||||
CHECK_NE(NumberDictionary::kNotFound, entry);
|
||||
|
||||
Handle<Object> key(Smi::FromInt(keys[i]), isolate);
|
||||
Handle<Object> expected_entry(Smi::FromInt(entry), isolate);
|
||||
@ -735,7 +734,7 @@ void TestNumberDictionaryLookup() {
|
||||
for (int i = 0; i < kKeysCount;) {
|
||||
int random_key = rand_gen.NextInt(Smi::kMaxValue);
|
||||
int entry = dictionary->FindEntry(random_key);
|
||||
if (entry != Dictionary::kNotFound) continue;
|
||||
if (entry != NumberDictionary::kNotFound) continue;
|
||||
i++;
|
||||
|
||||
Handle<Object> key(Smi::FromInt(random_key), isolate);
|
||||
@ -743,16 +742,6 @@ void TestNumberDictionaryLookup() {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(SeededNumberDictionaryLookup) {
|
||||
TestNumberDictionaryLookup<SeededNumberDictionary>();
|
||||
}
|
||||
|
||||
TEST(UnseededNumberDictionaryLookup) {
|
||||
TestNumberDictionaryLookup<UnseededNumberDictionary>();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void AddProperties(Handle<JSObject> object, Handle<Name> names[],
|
||||
|
@ -57,8 +57,7 @@ TEST(Object, StructListOrder) {
|
||||
typedef TestWithIsolate ObjectWithIsolate;
|
||||
|
||||
TEST_F(ObjectWithIsolate, DictionaryGrowth) {
|
||||
Handle<SeededNumberDictionary> dict =
|
||||
SeededNumberDictionary::New(isolate(), 1);
|
||||
Handle<NumberDictionary> dict = NumberDictionary::New(isolate(), 1);
|
||||
Handle<Object> value = isolate()->factory()->null_value();
|
||||
PropertyDetails details = PropertyDetails::Empty();
|
||||
|
||||
@ -68,48 +67,48 @@ TEST_F(ObjectWithIsolate, DictionaryGrowth) {
|
||||
uint32_t i = 1;
|
||||
// 3 elements fit into the initial capacity.
|
||||
for (; i <= 3; i++) {
|
||||
dict = SeededNumberDictionary::Add(dict, i, value, details);
|
||||
dict = NumberDictionary::Add(dict, i, value, details);
|
||||
CHECK_EQ(4, dict->Capacity());
|
||||
}
|
||||
// 4th element triggers growth.
|
||||
DCHECK_EQ(4, i);
|
||||
for (; i <= 5; i++) {
|
||||
dict = SeededNumberDictionary::Add(dict, i, value, details);
|
||||
dict = NumberDictionary::Add(dict, i, value, details);
|
||||
CHECK_EQ(8, dict->Capacity());
|
||||
}
|
||||
// 6th element triggers growth.
|
||||
DCHECK_EQ(6, i);
|
||||
for (; i <= 11; i++) {
|
||||
dict = SeededNumberDictionary::Add(dict, i, value, details);
|
||||
dict = NumberDictionary::Add(dict, i, value, details);
|
||||
CHECK_EQ(16, dict->Capacity());
|
||||
}
|
||||
// 12th element triggers growth.
|
||||
DCHECK_EQ(12, i);
|
||||
for (; i <= 21; i++) {
|
||||
dict = SeededNumberDictionary::Add(dict, i, value, details);
|
||||
dict = NumberDictionary::Add(dict, i, value, details);
|
||||
CHECK_EQ(32, dict->Capacity());
|
||||
}
|
||||
// 22nd element triggers growth.
|
||||
DCHECK_EQ(22, i);
|
||||
for (; i <= 43; i++) {
|
||||
dict = SeededNumberDictionary::Add(dict, i, value, details);
|
||||
dict = NumberDictionary::Add(dict, i, value, details);
|
||||
CHECK_EQ(64, dict->Capacity());
|
||||
}
|
||||
// 44th element triggers growth.
|
||||
DCHECK_EQ(44, i);
|
||||
for (; i <= 50; i++) {
|
||||
dict = SeededNumberDictionary::Add(dict, i, value, details);
|
||||
dict = NumberDictionary::Add(dict, i, value, details);
|
||||
CHECK_EQ(128, dict->Capacity());
|
||||
}
|
||||
|
||||
// If we grow by larger chunks, the next (sufficiently big) power of 2 is
|
||||
// chosen as the capacity.
|
||||
dict = SeededNumberDictionary::New(isolate(), 1);
|
||||
dict = SeededNumberDictionary::EnsureCapacity(dict, 65);
|
||||
dict = NumberDictionary::New(isolate(), 1);
|
||||
dict = NumberDictionary::EnsureCapacity(dict, 65);
|
||||
CHECK_EQ(128, dict->Capacity());
|
||||
|
||||
dict = SeededNumberDictionary::New(isolate(), 1);
|
||||
dict = SeededNumberDictionary::EnsureCapacity(dict, 30);
|
||||
dict = NumberDictionary::New(isolate(), 1);
|
||||
dict = NumberDictionary::EnsureCapacity(dict, 30);
|
||||
CHECK_EQ(64, dict->Capacity());
|
||||
}
|
||||
|
||||
|
@ -223,15 +223,10 @@ consts_misc = [
|
||||
{ 'name': 'namedictionary_prefix_start_index',
|
||||
'value': 'NameDictionary::kPrefixStartIndex' },
|
||||
|
||||
{ 'name': 'seedednumberdictionaryshape_prefix_size',
|
||||
'value': 'SeededNumberDictionaryShape::kPrefixSize' },
|
||||
{ 'name': 'seedednumberdictionaryshape_entry_size',
|
||||
'value': 'SeededNumberDictionaryShape::kEntrySize' },
|
||||
|
||||
{ 'name': 'unseedednumberdictionaryshape_prefix_size',
|
||||
'value': 'UnseededNumberDictionaryShape::kPrefixSize' },
|
||||
{ 'name': 'unseedednumberdictionaryshape_entry_size',
|
||||
'value': 'UnseededNumberDictionaryShape::kEntrySize' }
|
||||
{ 'name': 'numberdictionaryshape_prefix_size',
|
||||
'value': 'NumberDictionaryShape::kPrefixSize' },
|
||||
{ 'name': 'numberdictionaryshape_entry_size',
|
||||
'value': 'NumberDictionaryShape::kEntrySize' },
|
||||
];
|
||||
|
||||
#
|
||||
|
@ -204,75 +204,74 @@ KNOWN_MAPS = {
|
||||
0x02e81: (172, "OrderedHashTableMap"),
|
||||
0x02ed1: (172, "NameDictionaryMap"),
|
||||
0x02f21: (172, "GlobalDictionaryMap"),
|
||||
0x02f71: (172, "SeededNumberDictionaryMap"),
|
||||
0x02fc1: (172, "UnseededNumberDictionaryMap"),
|
||||
0x03011: (171, "SloppyArgumentsElementsMap"),
|
||||
0x03061: (180, "SmallOrderedHashMapMap"),
|
||||
0x030b1: (181, "SmallOrderedHashSetMap"),
|
||||
0x03101: (189, "JSMessageObjectMap"),
|
||||
0x03151: (137, "BytecodeArrayMap"),
|
||||
0x031a1: (171, "ModuleInfoMap"),
|
||||
0x031f1: (177, "NoClosuresCellMap"),
|
||||
0x03241: (177, "OneClosureCellMap"),
|
||||
0x03291: (177, "ManyClosuresCellMap"),
|
||||
0x032e1: (175, "PropertyArrayMap"),
|
||||
0x03331: (130, "BigIntMap"),
|
||||
0x03381: (64, "StringMap"),
|
||||
0x033d1: (73, "ConsOneByteStringMap"),
|
||||
0x03421: (65, "ConsStringMap"),
|
||||
0x03471: (77, "ThinOneByteStringMap"),
|
||||
0x034c1: (69, "ThinStringMap"),
|
||||
0x03511: (67, "SlicedStringMap"),
|
||||
0x03561: (75, "SlicedOneByteStringMap"),
|
||||
0x035b1: (66, "ExternalStringMap"),
|
||||
0x03601: (82, "ExternalStringWithOneByteDataMap"),
|
||||
0x03651: (74, "ExternalOneByteStringMap"),
|
||||
0x036a1: (98, "ShortExternalStringMap"),
|
||||
0x036f1: (114, "ShortExternalStringWithOneByteDataMap"),
|
||||
0x03741: (0, "InternalizedStringMap"),
|
||||
0x03791: (2, "ExternalInternalizedStringMap"),
|
||||
0x037e1: (18, "ExternalInternalizedStringWithOneByteDataMap"),
|
||||
0x03831: (10, "ExternalOneByteInternalizedStringMap"),
|
||||
0x03881: (34, "ShortExternalInternalizedStringMap"),
|
||||
0x038d1: (50, "ShortExternalInternalizedStringWithOneByteDataMap"),
|
||||
0x03921: (42, "ShortExternalOneByteInternalizedStringMap"),
|
||||
0x03971: (106, "ShortExternalOneByteStringMap"),
|
||||
0x039c1: (140, "FixedUint8ArrayMap"),
|
||||
0x03a11: (139, "FixedInt8ArrayMap"),
|
||||
0x03a61: (142, "FixedUint16ArrayMap"),
|
||||
0x03ab1: (141, "FixedInt16ArrayMap"),
|
||||
0x03b01: (144, "FixedUint32ArrayMap"),
|
||||
0x03b51: (143, "FixedInt32ArrayMap"),
|
||||
0x03ba1: (145, "FixedFloat32ArrayMap"),
|
||||
0x03bf1: (146, "FixedFloat64ArrayMap"),
|
||||
0x03c41: (147, "FixedUint8ClampedArrayMap"),
|
||||
0x03c91: (158, "ScriptMap"),
|
||||
0x03ce1: (182, "CodeDataContainerMap"),
|
||||
0x03d31: (173, "FeedbackVectorMap"),
|
||||
0x03d81: (171, "DebugEvaluateContextMap"),
|
||||
0x03dd1: (171, "ScriptContextTableMap"),
|
||||
0x03e21: (192, "ExternalMap"),
|
||||
0x03e71: (106, "NativeSourceStringMap"),
|
||||
0x03ec1: (165, "Tuple2Map"),
|
||||
0x03f11: (153, "InterceptorInfoMap"),
|
||||
0x03f61: (150, "AccessorInfoMap"),
|
||||
0x03fb1: (151, "AccessorPairMap"),
|
||||
0x04001: (152, "AccessCheckInfoMap"),
|
||||
0x04051: (154, "FunctionTemplateInfoMap"),
|
||||
0x040a1: (155, "ObjectTemplateInfoMap"),
|
||||
0x040f1: (156, "AllocationSiteMap"),
|
||||
0x04141: (157, "AllocationMementoMap"),
|
||||
0x04191: (159, "AliasedArgumentsEntryMap"),
|
||||
0x041e1: (160, "PromiseResolveThenableJobInfoMap"),
|
||||
0x04231: (161, "PromiseReactionJobInfoMap"),
|
||||
0x04281: (162, "DebugInfoMap"),
|
||||
0x042d1: (163, "StackFrameInfoMap"),
|
||||
0x04321: (164, "PrototypeInfoMap"),
|
||||
0x04371: (166, "Tuple3Map"),
|
||||
0x043c1: (167, "ContextExtensionMap"),
|
||||
0x04411: (168, "ModuleMap"),
|
||||
0x04461: (169, "ModuleInfoEntryMap"),
|
||||
0x044b1: (170, "AsyncGeneratorRequestMap"),
|
||||
0x02f71: (172, "NumberDictionaryMap"),
|
||||
0x02fc1: (171, "SloppyArgumentsElementsMap"),
|
||||
0x03011: (180, "SmallOrderedHashMapMap"),
|
||||
0x03061: (181, "SmallOrderedHashSetMap"),
|
||||
0x030b1: (189, "JSMessageObjectMap"),
|
||||
0x03101: (137, "BytecodeArrayMap"),
|
||||
0x03151: (171, "ModuleInfoMap"),
|
||||
0x031a1: (177, "NoClosuresCellMap"),
|
||||
0x031f1: (177, "OneClosureCellMap"),
|
||||
0x03241: (177, "ManyClosuresCellMap"),
|
||||
0x03291: (175, "PropertyArrayMap"),
|
||||
0x032e1: (130, "BigIntMap"),
|
||||
0x03331: (64, "StringMap"),
|
||||
0x03381: (73, "ConsOneByteStringMap"),
|
||||
0x033d1: (65, "ConsStringMap"),
|
||||
0x03421: (77, "ThinOneByteStringMap"),
|
||||
0x03471: (69, "ThinStringMap"),
|
||||
0x034c1: (67, "SlicedStringMap"),
|
||||
0x03511: (75, "SlicedOneByteStringMap"),
|
||||
0x03561: (66, "ExternalStringMap"),
|
||||
0x035b1: (82, "ExternalStringWithOneByteDataMap"),
|
||||
0x03601: (74, "ExternalOneByteStringMap"),
|
||||
0x03651: (98, "ShortExternalStringMap"),
|
||||
0x036a1: (114, "ShortExternalStringWithOneByteDataMap"),
|
||||
0x036f1: (0, "InternalizedStringMap"),
|
||||
0x03741: (2, "ExternalInternalizedStringMap"),
|
||||
0x03791: (18, "ExternalInternalizedStringWithOneByteDataMap"),
|
||||
0x037e1: (10, "ExternalOneByteInternalizedStringMap"),
|
||||
0x03831: (34, "ShortExternalInternalizedStringMap"),
|
||||
0x03881: (50, "ShortExternalInternalizedStringWithOneByteDataMap"),
|
||||
0x038d1: (42, "ShortExternalOneByteInternalizedStringMap"),
|
||||
0x03921: (106, "ShortExternalOneByteStringMap"),
|
||||
0x03971: (140, "FixedUint8ArrayMap"),
|
||||
0x039c1: (139, "FixedInt8ArrayMap"),
|
||||
0x03a11: (142, "FixedUint16ArrayMap"),
|
||||
0x03a61: (141, "FixedInt16ArrayMap"),
|
||||
0x03ab1: (144, "FixedUint32ArrayMap"),
|
||||
0x03b01: (143, "FixedInt32ArrayMap"),
|
||||
0x03b51: (145, "FixedFloat32ArrayMap"),
|
||||
0x03ba1: (146, "FixedFloat64ArrayMap"),
|
||||
0x03bf1: (147, "FixedUint8ClampedArrayMap"),
|
||||
0x03c41: (158, "ScriptMap"),
|
||||
0x03c91: (182, "CodeDataContainerMap"),
|
||||
0x03ce1: (173, "FeedbackVectorMap"),
|
||||
0x03d31: (171, "DebugEvaluateContextMap"),
|
||||
0x03d81: (171, "ScriptContextTableMap"),
|
||||
0x03dd1: (192, "ExternalMap"),
|
||||
0x03e21: (106, "NativeSourceStringMap"),
|
||||
0x03e71: (165, "Tuple2Map"),
|
||||
0x03ec1: (153, "InterceptorInfoMap"),
|
||||
0x03f11: (150, "AccessorInfoMap"),
|
||||
0x03f61: (151, "AccessorPairMap"),
|
||||
0x03fb1: (152, "AccessCheckInfoMap"),
|
||||
0x04001: (154, "FunctionTemplateInfoMap"),
|
||||
0x04051: (155, "ObjectTemplateInfoMap"),
|
||||
0x040a1: (156, "AllocationSiteMap"),
|
||||
0x040f1: (157, "AllocationMementoMap"),
|
||||
0x04141: (159, "AliasedArgumentsEntryMap"),
|
||||
0x04191: (160, "PromiseResolveThenableJobInfoMap"),
|
||||
0x041e1: (161, "PromiseReactionJobInfoMap"),
|
||||
0x04231: (162, "DebugInfoMap"),
|
||||
0x04281: (163, "StackFrameInfoMap"),
|
||||
0x042d1: (164, "PrototypeInfoMap"),
|
||||
0x04321: (166, "Tuple3Map"),
|
||||
0x04371: (167, "ContextExtensionMap"),
|
||||
0x043c1: (168, "ModuleMap"),
|
||||
0x04411: (169, "ModuleInfoEntryMap"),
|
||||
0x04461: (170, "AsyncGeneratorRequestMap"),
|
||||
}
|
||||
|
||||
# List of known V8 objects.
|
||||
|
Loading…
Reference in New Issue
Block a user