Commit 3055139a authored by Frank Emrich's avatar Frank Emrich Committed by Commit Bot

[dict-proto] Add support for ordered property dicts, pt.4

This CL adds partial support for objects whose slow mode dictionaries
are OrderedNameDictionaries. This is the case for all slow mode objects
if V8_DICT_MODE_PROTOTYPES is enabled.

Specifically, this CL contains minor changes to CSA code, short of
actually performing ordered dictionary lookups using CSA
implementations of these lookups.

Bug: v8:7569
Change-Id: I0dab0f21000ca3b9b170ace58787ec639d587e64
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2540590
Commit-Queue: Frank Emrich <emrich@google.com>
Reviewed-by: 's avatarMarja Hölttä <marja@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarDominik Inführ <dinfuehr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#71304}
parent 43d888f4
...@@ -395,6 +395,11 @@ extern enum PrimitiveType { kString, kBoolean, kSymbol, kNumber } ...@@ -395,6 +395,11 @@ extern enum PrimitiveType { kString, kBoolean, kSymbol, kNumber }
const kNameDictionaryInitialCapacity: const kNameDictionaryInitialCapacity:
constexpr int32 generates 'NameDictionary::kInitialCapacity'; constexpr int32 generates 'NameDictionary::kInitialCapacity';
const kOrderedNameDictionaryInitialCapacity:
constexpr int32 generates 'OrderedNameDictionary::kInitialCapacity';
const kDictModePrototypes:
constexpr bool generates 'V8_DICT_MODE_PROTOTYPES_BOOL';
type TheHole extends Oddball; type TheHole extends Oddball;
type Null extends Oddball; type Null extends Oddball;
...@@ -614,6 +619,8 @@ extern macro SpeciesConstructor(implicit context: Context)( ...@@ -614,6 +619,8 @@ extern macro SpeciesConstructor(implicit context: Context)(
extern macro ConstructorBuiltinsAssembler::IsDictionaryMap(Map): bool; extern macro ConstructorBuiltinsAssembler::IsDictionaryMap(Map): bool;
extern macro CodeStubAssembler::AllocateNameDictionary(constexpr int32): extern macro CodeStubAssembler::AllocateNameDictionary(constexpr int32):
NameDictionary; NameDictionary;
extern macro CodeStubAssembler::AllocateOrderedNameDictionary(constexpr int32):
OrderedNameDictionary;
extern builtin ToObject(Context, JSAny): JSReceiver; extern builtin ToObject(Context, JSAny): JSReceiver;
extern macro ToObject_Inline(Context, JSAny): JSReceiver; extern macro ToObject_Inline(Context, JSAny): JSReceiver;
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "src/codegen/code-stub-assembler.h" #include "src/codegen/code-stub-assembler.h"
#include "src/codegen/interface-descriptors.h" #include "src/codegen/interface-descriptors.h"
#include "src/codegen/macro-assembler.h" #include "src/codegen/macro-assembler.h"
#include "src/common/globals.h"
#include "src/logging/counters.h" #include "src/logging/counters.h"
#include "src/objects/objects-inl.h" #include "src/objects/objects-inl.h"
...@@ -281,7 +282,12 @@ TNode<JSObject> ConstructorBuiltinsAssembler::FastNewObject( ...@@ -281,7 +282,12 @@ TNode<JSObject> ConstructorBuiltinsAssembler::FastNewObject(
} }
BIND(&allocate_properties); BIND(&allocate_properties);
{ {
properties = AllocateNameDictionary(NameDictionary::kInitialCapacity); if (V8_DICT_MODE_PROTOTYPES_BOOL) {
properties = AllocateOrderedNameDictionary(
OrderedNameDictionary::kInitialCapacity);
} else {
properties = AllocateNameDictionary(NameDictionary::kInitialCapacity);
}
Goto(&instantiate_map); Goto(&instantiate_map);
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "src/builtins/builtins-utils-gen.h" #include "src/builtins/builtins-utils-gen.h"
#include "src/builtins/builtins.h" #include "src/builtins/builtins.h"
#include "src/codegen/code-stub-assembler.h" #include "src/codegen/code-stub-assembler.h"
#include "src/common/globals.h"
#include "src/heap/factory-inl.h" #include "src/heap/factory-inl.h"
#include "src/ic/accessor-assembler.h" #include "src/ic/accessor-assembler.h"
#include "src/ic/keyed-store-generic.h" #include "src/ic/keyed-store-generic.h"
...@@ -1068,7 +1069,12 @@ TF_BUILTIN(ObjectCreate, ObjectBuiltinsAssembler) { ...@@ -1068,7 +1069,12 @@ TF_BUILTIN(ObjectCreate, ObjectBuiltinsAssembler) {
BIND(&null_proto); BIND(&null_proto);
{ {
map = LoadSlowObjectWithNullPrototypeMap(native_context); map = LoadSlowObjectWithNullPrototypeMap(native_context);
properties = AllocateNameDictionary(NameDictionary::kInitialCapacity); if (V8_DICT_MODE_PROTOTYPES_BOOL) {
properties = AllocateOrderedNameDictionary(
OrderedNameDictionary::kInitialCapacity);
} else {
properties = AllocateNameDictionary(NameDictionary::kInitialCapacity);
}
Goto(&instantiate_map); Goto(&instantiate_map);
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "src/builtins/builtins-utils-gen.h" #include "src/builtins/builtins-utils-gen.h"
#include "src/builtins/builtins-utils.h" #include "src/builtins/builtins-utils.h"
#include "src/builtins/builtins.h" #include "src/builtins/builtins.h"
#include "src/common/globals.h"
#include "src/logging/counters.h" #include "src/logging/counters.h"
#include "src/objects/js-proxy.h" #include "src/objects/js-proxy.h"
#include "src/objects/objects-inl.h" #include "src/objects/objects-inl.h"
...@@ -51,8 +52,10 @@ TNode<JSProxy> ProxiesCodeStubAssembler::AllocateProxy( ...@@ -51,8 +52,10 @@ TNode<JSProxy> ProxiesCodeStubAssembler::AllocateProxy(
BIND(&create_proxy); BIND(&create_proxy);
TNode<HeapObject> proxy = Allocate(JSProxy::kSize); TNode<HeapObject> proxy = Allocate(JSProxy::kSize);
StoreMapNoWriteBarrier(proxy, map.value()); StoreMapNoWriteBarrier(proxy, map.value());
StoreObjectFieldRoot(proxy, JSProxy::kPropertiesOrHashOffset, RootIndex empty_dict = V8_DICT_MODE_PROTOTYPES_BOOL
RootIndex::kEmptyPropertyDictionary); ? RootIndex::kEmptyOrderedPropertyDictionary
: RootIndex::kEmptyPropertyDictionary;
StoreObjectFieldRoot(proxy, JSProxy::kPropertiesOrHashOffset, empty_dict);
StoreObjectFieldNoWriteBarrier(proxy, JSProxy::kTargetOffset, target); StoreObjectFieldNoWriteBarrier(proxy, JSProxy::kTargetOffset, target);
StoreObjectFieldNoWriteBarrier(proxy, JSProxy::kHandlerOffset, handler); StoreObjectFieldNoWriteBarrier(proxy, JSProxy::kHandlerOffset, handler);
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "src/codegen/code-factory.h" #include "src/codegen/code-factory.h"
#include "src/codegen/code-stub-assembler.h" #include "src/codegen/code-stub-assembler.h"
#include "src/codegen/macro-assembler.h" #include "src/codegen/macro-assembler.h"
#include "src/common/globals.h"
#include "src/execution/protectors.h" #include "src/execution/protectors.h"
#include "src/heap/factory-inl.h" #include "src/heap/factory-inl.h"
#include "src/logging/counters.h" #include "src/logging/counters.h"
...@@ -289,8 +290,14 @@ TNode<JSRegExpResult> RegExpBuiltinsAssembler::ConstructNewResultFromMatchInfo( ...@@ -289,8 +290,14 @@ TNode<JSRegExpResult> RegExpBuiltinsAssembler::ConstructNewResultFromMatchInfo(
TNode<IntPtrT> num_properties = WordSar(names_length, 1); TNode<IntPtrT> num_properties = WordSar(names_length, 1);
TNode<NativeContext> native_context = LoadNativeContext(context); TNode<NativeContext> native_context = LoadNativeContext(context);
TNode<Map> map = LoadSlowObjectWithNullPrototypeMap(native_context); TNode<Map> map = LoadSlowObjectWithNullPrototypeMap(native_context);
TNode<NameDictionary> properties = TNode<HeapObject> properties;
AllocateNameDictionary(num_properties, kAllowLargeObjectAllocation); if (V8_DICT_MODE_PROTOTYPES_BOOL) {
// AllocateOrderedNameDictionary always uses kAllowLargeObjectAllocation.
properties = AllocateOrderedNameDictionary(num_properties);
} else {
properties =
AllocateNameDictionary(num_properties, kAllowLargeObjectAllocation);
}
TNode<JSObject> group_object = AllocateJSObjectFromMap(map, properties); TNode<JSObject> group_object = AllocateJSObjectFromMap(map, properties);
StoreObjectField(result, JSRegExpResult::kGroupsOffset, group_object); StoreObjectField(result, JSRegExpResult::kGroupsOffset, group_object);
...@@ -325,7 +332,7 @@ TNode<JSRegExpResult> RegExpBuiltinsAssembler::ConstructNewResultFromMatchInfo( ...@@ -325,7 +332,7 @@ TNode<JSRegExpResult> RegExpBuiltinsAssembler::ConstructNewResultFromMatchInfo(
// - Receiver is extensible // - Receiver is extensible
// - Receiver has no interceptors // - Receiver has no interceptors
Label add_dictionary_property_slow(this, Label::kDeferred); Label add_dictionary_property_slow(this, Label::kDeferred);
Add<NameDictionary>(properties, name, capture, Add<NameDictionary>(CAST(properties), name, capture,
&add_dictionary_property_slow); &add_dictionary_property_slow);
var_i = i_plus_2; var_i = i_plus_2;
......
...@@ -94,12 +94,17 @@ transitioning builtin CreateObjectWithoutProperties(implicit context: Context)( ...@@ -94,12 +94,17 @@ transitioning builtin CreateObjectWithoutProperties(implicit context: Context)(
prototype: JSAny): JSAny { prototype: JSAny): JSAny {
try { try {
let map: Map; let map: Map;
let properties: NameDictionary|EmptyFixedArray; let properties: NameDictionary|OrderedNameDictionary|EmptyFixedArray;
typeswitch (prototype) { typeswitch (prototype) {
case (Null): { case (Null): {
map = *NativeContextSlot( map = *NativeContextSlot(
ContextSlot::SLOW_OBJECT_WITH_NULL_PROTOTYPE_MAP); ContextSlot::SLOW_OBJECT_WITH_NULL_PROTOTYPE_MAP);
properties = AllocateNameDictionary(kNameDictionaryInitialCapacity); if (kDictModePrototypes) {
properties = AllocateOrderedNameDictionary(
kOrderedNameDictionaryInitialCapacity);
} else {
properties = AllocateNameDictionary(kNameDictionaryInitialCapacity);
}
} }
case (prototype: JSReceiver): { case (prototype: JSReceiver): {
properties = kEmptyFixedArray; properties = kEmptyFixedArray;
......
...@@ -1590,10 +1590,26 @@ TNode<HeapObject> CodeStubAssembler::LoadSlowProperties( ...@@ -1590,10 +1590,26 @@ TNode<HeapObject> CodeStubAssembler::LoadSlowProperties(
TNode<JSReceiver> object) { TNode<JSReceiver> object) {
CSA_SLOW_ASSERT(this, IsDictionaryMap(LoadMap(object))); CSA_SLOW_ASSERT(this, IsDictionaryMap(LoadMap(object)));
TNode<Object> properties = LoadJSReceiverPropertiesOrHash(object); TNode<Object> properties = LoadJSReceiverPropertiesOrHash(object);
return Select<HeapObject>( NodeGenerator<HeapObject> make_empty = [=]() -> TNode<HeapObject> {
TaggedIsSmi(properties), if (V8_DICT_MODE_PROTOTYPES_BOOL) {
[=] { return EmptyPropertyDictionaryConstant(); }, return EmptyOrderedPropertyDictionaryConstant();
[=] { return CAST(properties); }); } else {
return EmptyPropertyDictionaryConstant();
}
};
NodeGenerator<HeapObject> cast_properties = [=] {
TNode<HeapObject> dict = CAST(properties);
if (V8_DICT_MODE_PROTOTYPES_BOOL) {
CSA_ASSERT(this, Word32Or(IsOrderedNameDictionary(dict),
IsGlobalDictionary(dict)));
} else {
CSA_ASSERT(this,
Word32Or(IsNameDictionary(dict), IsGlobalDictionary(dict)));
}
return dict;
};
return Select<HeapObject>(TaggedIsSmi(properties), make_empty,
cast_properties);
} }
TNode<Object> CodeStubAssembler::LoadJSArgumentsObjectLength( TNode<Object> CodeStubAssembler::LoadJSArgumentsObjectLength(
...@@ -1763,7 +1779,8 @@ TNode<IntPtrT> CodeStubAssembler::LoadJSReceiverIdentityHash( ...@@ -1763,7 +1779,8 @@ TNode<IntPtrT> CodeStubAssembler::LoadJSReceiverIdentityHash(
SloppyTNode<Object> receiver, Label* if_no_hash) { SloppyTNode<Object> receiver, Label* if_no_hash) {
TVARIABLE(IntPtrT, var_hash); TVARIABLE(IntPtrT, var_hash);
Label done(this), if_smi(this), if_property_array(this), Label done(this), if_smi(this), if_property_array(this),
if_property_dictionary(this), if_fixed_array(this); if_ordered_property_dictionary(this), if_property_dictionary(this),
if_fixed_array(this);
TNode<Object> properties_or_hash = TNode<Object> properties_or_hash =
LoadObjectField(TNode<HeapObject>::UncheckedCast(receiver), LoadObjectField(TNode<HeapObject>::UncheckedCast(receiver),
...@@ -1776,6 +1793,11 @@ TNode<IntPtrT> CodeStubAssembler::LoadJSReceiverIdentityHash( ...@@ -1776,6 +1793,11 @@ TNode<IntPtrT> CodeStubAssembler::LoadJSReceiverIdentityHash(
GotoIf(InstanceTypeEqual(properties_instance_type, PROPERTY_ARRAY_TYPE), GotoIf(InstanceTypeEqual(properties_instance_type, PROPERTY_ARRAY_TYPE),
&if_property_array); &if_property_array);
if (V8_DICT_MODE_PROTOTYPES_BOOL) {
GotoIf(InstanceTypeEqual(properties_instance_type,
ORDERED_NAME_DICTIONARY_TYPE),
&if_ordered_property_dictionary);
}
Branch(InstanceTypeEqual(properties_instance_type, NAME_DICTIONARY_TYPE), Branch(InstanceTypeEqual(properties_instance_type, NAME_DICTIONARY_TYPE),
&if_property_dictionary, &if_fixed_array); &if_property_dictionary, &if_fixed_array);
...@@ -1799,6 +1821,14 @@ TNode<IntPtrT> CodeStubAssembler::LoadJSReceiverIdentityHash( ...@@ -1799,6 +1821,14 @@ TNode<IntPtrT> CodeStubAssembler::LoadJSReceiverIdentityHash(
DecodeWord<PropertyArray::HashField>(length_and_hash)); DecodeWord<PropertyArray::HashField>(length_and_hash));
Goto(&done); Goto(&done);
} }
if (V8_DICT_MODE_PROTOTYPES_BOOL) {
BIND(&if_ordered_property_dictionary);
{
var_hash = SmiUntag(CAST(LoadFixedArrayElement(
CAST(properties), OrderedNameDictionary::HashIndex())));
Goto(&done);
}
}
BIND(&if_property_dictionary); BIND(&if_property_dictionary);
{ {
...@@ -3522,8 +3552,9 @@ void CodeStubAssembler::InitializeJSObjectFromMap( ...@@ -3522,8 +3552,9 @@ void CodeStubAssembler::InitializeJSObjectFromMap(
StoreObjectFieldRoot(object, JSObject::kPropertiesOrHashOffset, StoreObjectFieldRoot(object, JSObject::kPropertiesOrHashOffset,
RootIndex::kEmptyFixedArray); RootIndex::kEmptyFixedArray);
} else { } else {
CSA_ASSERT(this, Word32Or(Word32Or(IsPropertyArray(*properties), CSA_ASSERT(this, Word32Or(Word32Or(Word32Or(IsPropertyArray(*properties),
IsNameDictionary(*properties)), IsNameDictionary(*properties)),
IsOrderedNameDictionary(*properties)),
IsEmptyFixedArray(*properties))); IsEmptyFixedArray(*properties)));
StoreObjectFieldNoWriteBarrier(object, JSObject::kPropertiesOrHashOffset, StoreObjectFieldNoWriteBarrier(object, JSObject::kPropertiesOrHashOffset,
*properties); *properties);
...@@ -6321,6 +6352,10 @@ TNode<BoolT> CodeStubAssembler::IsEphemeronHashTable(TNode<HeapObject> object) { ...@@ -6321,6 +6352,10 @@ TNode<BoolT> CodeStubAssembler::IsEphemeronHashTable(TNode<HeapObject> object) {
TNode<BoolT> CodeStubAssembler::IsNameDictionary(TNode<HeapObject> object) { TNode<BoolT> CodeStubAssembler::IsNameDictionary(TNode<HeapObject> object) {
return HasInstanceType(object, NAME_DICTIONARY_TYPE); return HasInstanceType(object, NAME_DICTIONARY_TYPE);
} }
TNode<BoolT> CodeStubAssembler::IsOrderedNameDictionary(
TNode<HeapObject> object) {
return HasInstanceType(object, ORDERED_NAME_DICTIONARY_TYPE);
}
TNode<BoolT> CodeStubAssembler::IsGlobalDictionary(TNode<HeapObject> object) { TNode<BoolT> CodeStubAssembler::IsGlobalDictionary(TNode<HeapObject> object) {
return HasInstanceType(object, GLOBAL_DICTIONARY_TYPE); return HasInstanceType(object, GLOBAL_DICTIONARY_TYPE);
...@@ -8032,6 +8067,27 @@ template void CodeStubAssembler::Add<NameDictionary>(TNode<NameDictionary>, ...@@ -8032,6 +8067,27 @@ template void CodeStubAssembler::Add<NameDictionary>(TNode<NameDictionary>,
TNode<Name>, TNode<Object>, TNode<Name>, TNode<Object>,
Label*); Label*);
template <class Dictionary>
TNode<Smi> CodeStubAssembler::GetNumberOfElements(
TNode<Dictionary> dictionary) {
return CAST(
LoadFixedArrayElement(dictionary, Dictionary::kNumberOfElementsIndex));
}
template <>
TNode<Smi> CodeStubAssembler::GetNumberOfElements(
TNode<OrderedNameDictionary> dictionary) {
return CAST(LoadFixedArrayElement(
dictionary, OrderedNameDictionary::NumberOfElementsIndex()));
}
template TNode<Smi> CodeStubAssembler::GetNumberOfElements(
TNode<NameDictionary> dictionary);
template TNode<Smi> CodeStubAssembler::GetNumberOfElements(
TNode<NumberDictionary> dictionary);
template TNode<Smi> CodeStubAssembler::GetNumberOfElements(
TNode<GlobalDictionary> dictionary);
template <typename Array> template <typename Array>
void CodeStubAssembler::LookupLinear(TNode<Name> unique_name, void CodeStubAssembler::LookupLinear(TNode<Name> unique_name,
TNode<Array> array, TNode<Array> array,
...@@ -13259,13 +13315,32 @@ TNode<Map> CodeStubAssembler::CheckEnumCache(TNode<JSReceiver> receiver, ...@@ -13259,13 +13315,32 @@ TNode<Map> CodeStubAssembler::CheckEnumCache(TNode<JSReceiver> receiver,
{ {
// Avoid runtime-call for empty dictionary receivers. // Avoid runtime-call for empty dictionary receivers.
GotoIfNot(IsDictionaryMap(receiver_map), if_runtime); GotoIfNot(IsDictionaryMap(receiver_map), if_runtime);
TNode<HashTableBase> properties = TNode<Smi> length;
UncheckedCast<HashTableBase>(LoadSlowProperties(receiver)); TNode<HeapObject> properties = LoadSlowProperties(receiver);
CSA_ASSERT(this, Word32Or(IsNameDictionary(properties),
IsGlobalDictionary(properties))); if (V8_DICT_MODE_PROTOTYPES_BOOL) {
STATIC_ASSERT(static_cast<int>(NameDictionary::kNumberOfElementsIndex) == CSA_ASSERT(this, Word32Or(IsOrderedNameDictionary(properties),
static_cast<int>(GlobalDictionary::kNumberOfElementsIndex)); IsGlobalDictionary(properties)));
TNode<Smi> length = GetNumberOfElements(properties);
length = Select<Smi>(
IsOrderedNameDictionary(properties),
[=] {
return GetNumberOfElements(
UncheckedCast<OrderedNameDictionary>(properties));
},
[=] {
return GetNumberOfElements(
UncheckedCast<GlobalDictionary>(properties));
});
} else {
CSA_ASSERT(this, Word32Or(IsNameDictionary(properties),
IsGlobalDictionary(properties)));
STATIC_ASSERT(static_cast<int>(NameDictionary::kNumberOfElementsIndex) ==
static_cast<int>(GlobalDictionary::kNumberOfElementsIndex));
length = GetNumberOfElements(UncheckedCast<HashTableBase>(properties));
}
GotoIfNot(TaggedEqual(length, SmiConstant(0)), if_runtime); GotoIfNot(TaggedEqual(length, SmiConstant(0)), if_runtime);
// Check that there are no elements on the {receiver} and its prototype // Check that there are no elements on the {receiver} and its prototype
// chain. Given that we do not create an EnumCache for dict-mode objects, // chain. Given that we do not create an EnumCache for dict-mode objects,
......
...@@ -132,6 +132,8 @@ enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol }; ...@@ -132,6 +132,8 @@ enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol };
V(EmptyScopeInfo, empty_scope_info, EmptyScopeInfo) \ V(EmptyScopeInfo, empty_scope_info, EmptyScopeInfo) \
V(EmptyPropertyDictionary, empty_property_dictionary, \ V(EmptyPropertyDictionary, empty_property_dictionary, \
EmptyPropertyDictionary) \ EmptyPropertyDictionary) \
V(EmptyOrderedPropertyDictionary, empty_ordered_property_dictionary, \
EmptyOrderedPropertyDictionary) \
V(EmptySlowElementDictionary, empty_slow_element_dictionary, \ V(EmptySlowElementDictionary, empty_slow_element_dictionary, \
EmptySlowElementDictionary) \ EmptySlowElementDictionary) \
V(empty_string, empty_string, EmptyString) \ V(empty_string, empty_string, EmptyString) \
...@@ -2327,6 +2329,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler ...@@ -2327,6 +2329,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<BoolT> IsConstructor(TNode<HeapObject> object); TNode<BoolT> IsConstructor(TNode<HeapObject> object);
TNode<BoolT> IsDeprecatedMap(TNode<Map> map); TNode<BoolT> IsDeprecatedMap(TNode<Map> map);
TNode<BoolT> IsNameDictionary(TNode<HeapObject> object); TNode<BoolT> IsNameDictionary(TNode<HeapObject> object);
TNode<BoolT> IsOrderedNameDictionary(TNode<HeapObject> object);
TNode<BoolT> IsGlobalDictionary(TNode<HeapObject> object); TNode<BoolT> IsGlobalDictionary(TNode<HeapObject> object);
TNode<BoolT> IsExtensibleMap(TNode<Map> map); TNode<BoolT> IsExtensibleMap(TNode<Map> map);
TNode<BoolT> IsExtensibleNonPrototypeMap(TNode<Map> map); TNode<BoolT> IsExtensibleNonPrototypeMap(TNode<Map> map);
...@@ -2838,10 +2841,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler ...@@ -2838,10 +2841,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<IntPtrT> HashTableComputeCapacity(TNode<IntPtrT> at_least_space_for); TNode<IntPtrT> HashTableComputeCapacity(TNode<IntPtrT> at_least_space_for);
template <class Dictionary> template <class Dictionary>
TNode<Smi> GetNumberOfElements(TNode<Dictionary> dictionary) { TNode<Smi> GetNumberOfElements(TNode<Dictionary> dictionary);
return CAST(
LoadFixedArrayElement(dictionary, Dictionary::kNumberOfElementsIndex));
}
TNode<Smi> GetNumberDictionaryNumberOfElements( TNode<Smi> GetNumberDictionaryNumberOfElements(
TNode<NumberDictionary> dictionary) { TNode<NumberDictionary> dictionary) {
......
...@@ -1562,8 +1562,11 @@ Handle<JSObject> Factory::CopyJSObjectWithAllocationSite( ...@@ -1562,8 +1562,11 @@ Handle<JSObject> Factory::CopyJSObjectWithAllocationSite(
clone->set_raw_properties_or_hash(*prop); clone->set_raw_properties_or_hash(*prop);
} }
} else { } else {
Handle<FixedArray> properties( Handle<FixedArray> properties =
FixedArray::cast(source->property_dictionary()), isolate()); handle(V8_DICT_MODE_PROTOTYPES_BOOL
? FixedArray::cast(source->property_dictionary_ordered())
: FixedArray::cast(source->property_dictionary()),
isolate());
Handle<FixedArray> prop = CopyFixedArray(properties); Handle<FixedArray> prop = CopyFixedArray(properties);
clone->set_raw_properties_or_hash(*prop); clone->set_raw_properties_or_hash(*prop);
} }
......
...@@ -73,9 +73,15 @@ macro GetDerivedMap(implicit context: Context)( ...@@ -73,9 +73,15 @@ macro GetDerivedMap(implicit context: Context)(
macro AllocateFastOrSlowJSObjectFromMap(implicit context: Context)(map: Map): macro AllocateFastOrSlowJSObjectFromMap(implicit context: Context)(map: Map):
JSObject { JSObject {
let properties: EmptyFixedArray|NameDictionary = kEmptyFixedArray; let properties: EmptyFixedArray|NameDictionary|OrderedNameDictionary =
kEmptyFixedArray;
if (IsDictionaryMap(map)) { if (IsDictionaryMap(map)) {
properties = AllocateNameDictionary(kNameDictionaryInitialCapacity); if (kDictModePrototypes) {
properties =
AllocateOrderedNameDictionary(kOrderedNameDictionaryInitialCapacity);
} else {
properties = AllocateNameDictionary(kNameDictionaryInitialCapacity);
}
} }
return AllocateJSObjectFromMap( return AllocateJSObjectFromMap(
map, properties, kEmptyFixedArray, AllocationFlag::kNone, map, properties, kEmptyFixedArray, AllocationFlag::kNone,
...@@ -154,7 +160,11 @@ extern class JSStringIterator extends JSObject { ...@@ -154,7 +160,11 @@ extern class JSStringIterator extends JSObject {
extern macro AllocateJSObjectFromMap(Map): JSObject; extern macro AllocateJSObjectFromMap(Map): JSObject;
extern macro AllocateJSObjectFromMap( extern macro AllocateJSObjectFromMap(
Map, NameDictionary | EmptyFixedArray | PropertyArray): JSObject; Map,
NameDictionary | OrderedNameDictionary | EmptyFixedArray |
PropertyArray): JSObject;
extern macro AllocateJSObjectFromMap( extern macro AllocateJSObjectFromMap(
Map, NameDictionary | EmptyFixedArray | PropertyArray, FixedArray, Map,
constexpr AllocationFlag, constexpr SlackTrackingMode): JSObject; NameDictionary | OrderedNameDictionary | EmptyFixedArray | PropertyArray,
FixedArray, constexpr AllocationFlag,
constexpr SlackTrackingMode): JSObject;
...@@ -232,11 +232,11 @@ inline int SmallOrderedNameDictionary::Hash() { ...@@ -232,11 +232,11 @@ inline int SmallOrderedNameDictionary::Hash() {
inline void OrderedNameDictionary::SetHash(int hash) { inline void OrderedNameDictionary::SetHash(int hash) {
DCHECK(PropertyArray::HashField::is_valid(hash)); DCHECK(PropertyArray::HashField::is_valid(hash));
this->set(PrefixIndex(), Smi::FromInt(hash)); this->set(HashIndex(), Smi::FromInt(hash));
} }
inline int OrderedNameDictionary::Hash() { inline int OrderedNameDictionary::Hash() {
Object hash_obj = this->get(PrefixIndex()); Object hash_obj = this->get(HashIndex());
int hash = Smi::ToInt(hash_obj); int hash = Smi::ToInt(hash_obj);
DCHECK(PropertyArray::HashField::is_valid(hash)); DCHECK(PropertyArray::HashField::is_valid(hash));
return hash; return hash;
......
...@@ -831,6 +831,8 @@ class V8_EXPORT_PRIVATE OrderedNameDictionary ...@@ -831,6 +831,8 @@ class V8_EXPORT_PRIVATE OrderedNameDictionary
static const int kPropertyDetailsOffset = 2; static const int kPropertyDetailsOffset = 2;
static const int kPrefixSize = 1; static const int kPrefixSize = 1;
static constexpr int HashIndex() { return PrefixIndex(); }
static const bool kIsOrderedDictionaryType = true; static const bool kIsOrderedDictionaryType = true;
OBJECT_CONSTRUCTORS(OrderedNameDictionary, OBJECT_CONSTRUCTORS(OrderedNameDictionary,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment