[CSA][cleanup] TNodify TryToName, TryToIntPtr and TryInternalizeString.
BUG=v8:6949,v8:9396 Change-Id: Icd65e16f6b5b41ad56d1b8767a73e8ca15d05b74 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1807365 Commit-Queue: Ross McIlroy <rmcilroy@chromium.org> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Sathya Gunasekaran <gsathya@chromium.org> Cr-Commit-Position: refs/heads/master@{#63845}
This commit is contained in:
parent
1f3b2d4ec2
commit
11b819c679
@ -531,8 +531,8 @@ TF_BUILTIN(DeleteProperty, DeletePropertyBaseAssembler) {
|
||||
TNode<Smi> language_mode = CAST(Parameter(Descriptor::kLanguageMode));
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
|
||||
VARIABLE(var_index, MachineType::PointerRepresentation());
|
||||
VARIABLE(var_unique, MachineRepresentation::kTagged, key);
|
||||
TVARIABLE(IntPtrT, var_index);
|
||||
TVARIABLE(Name, var_unique);
|
||||
Label if_index(this), if_unique_name(this), if_notunique(this),
|
||||
if_notfound(this), slow(this), if_proxy(this);
|
||||
|
||||
@ -553,8 +553,7 @@ TF_BUILTIN(DeleteProperty, DeletePropertyBaseAssembler) {
|
||||
BIND(&if_unique_name);
|
||||
{
|
||||
Comment("key is unique name");
|
||||
TNode<Name> unique = CAST(var_unique.value());
|
||||
CheckForAssociatedProtector(unique, &slow);
|
||||
CheckForAssociatedProtector(var_unique.value(), &slow);
|
||||
|
||||
Label dictionary(this), dont_delete(this);
|
||||
GotoIf(IsDictionaryMap(receiver_map), &dictionary);
|
||||
@ -569,8 +568,8 @@ TF_BUILTIN(DeleteProperty, DeletePropertyBaseAssembler) {
|
||||
|
||||
TNode<NameDictionary> properties =
|
||||
CAST(LoadSlowProperties(CAST(receiver)));
|
||||
DeleteDictionaryProperty(receiver, properties, unique, context,
|
||||
&dont_delete, &if_notfound);
|
||||
DeleteDictionaryProperty(receiver, properties, var_unique.value(),
|
||||
context, &dont_delete, &if_notfound);
|
||||
}
|
||||
|
||||
BIND(&dont_delete);
|
||||
@ -586,7 +585,7 @@ TF_BUILTIN(DeleteProperty, DeletePropertyBaseAssembler) {
|
||||
{
|
||||
// If the string was not found in the string table, then no object can
|
||||
// have a property with that name.
|
||||
TryInternalizeString(key, &if_index, &var_index, &if_unique_name,
|
||||
TryInternalizeString(CAST(key), &if_index, &var_index, &if_unique_name,
|
||||
&var_unique, &if_notfound, &slow);
|
||||
}
|
||||
|
||||
|
@ -385,7 +385,7 @@ TF_BUILTIN(ObjectPrototypeHasOwnProperty, ObjectBuiltinsAssembler) {
|
||||
|
||||
{
|
||||
TVARIABLE(IntPtrT, var_index);
|
||||
TVARIABLE(Object, var_unique); // TODO(6949): Should be Name.
|
||||
TVARIABLE(Name, var_unique);
|
||||
|
||||
Label if_index(this), if_unique_name(this), if_notunique_name(this);
|
||||
TryToName(key, &if_index, &var_index, &if_unique_name, &var_unique,
|
||||
@ -408,7 +408,7 @@ TF_BUILTIN(ObjectPrototypeHasOwnProperty, ObjectBuiltinsAssembler) {
|
||||
BIND(&if_notunique_name);
|
||||
{
|
||||
Label not_in_string_table(this);
|
||||
TryInternalizeString(key, &if_index, &var_index, &if_unique_name,
|
||||
TryInternalizeString(CAST(key), &if_index, &var_index, &if_unique_name,
|
||||
&var_unique, ¬_in_string_table, &call_runtime);
|
||||
|
||||
BIND(¬_in_string_table);
|
||||
@ -1375,7 +1375,7 @@ TF_BUILTIN(ObjectGetOwnPropertyDescriptor, ObjectBuiltinsAssembler) {
|
||||
GotoIf(IsSpecialReceiverInstanceType(instance_type), &call_runtime);
|
||||
{
|
||||
TVARIABLE(IntPtrT, var_index, IntPtrConstant(0));
|
||||
TVARIABLE(Object, var_name); // TODO(6949) Should be Name
|
||||
TVARIABLE(Name, var_name);
|
||||
|
||||
TryToName(key, &if_keyisindex, &var_index, &if_iskeyunique, &var_name,
|
||||
&call_runtime, &if_notunique_name);
|
||||
@ -1383,8 +1383,9 @@ TF_BUILTIN(ObjectGetOwnPropertyDescriptor, ObjectBuiltinsAssembler) {
|
||||
BIND(&if_notunique_name);
|
||||
{
|
||||
Label not_in_string_table(this);
|
||||
TryInternalizeString(key, &if_keyisindex, &var_index, &if_iskeyunique,
|
||||
&var_name, ¬_in_string_table, &call_runtime);
|
||||
TryInternalizeString(CAST(key), &if_keyisindex, &var_index,
|
||||
&if_iskeyunique, &var_name, ¬_in_string_table,
|
||||
&call_runtime);
|
||||
|
||||
BIND(¬_in_string_table);
|
||||
{
|
||||
|
@ -8422,89 +8422,110 @@ void CodeStubAssembler::Use(Label* label) {
|
||||
GotoIf(Word32Equal(Int32Constant(0), Int32Constant(1)), label);
|
||||
}
|
||||
|
||||
void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex,
|
||||
Variable* var_index, Label* if_keyisunique,
|
||||
Variable* var_unique, Label* if_bailout,
|
||||
void CodeStubAssembler::TryToName(SloppyTNode<Object> key, Label* if_keyisindex,
|
||||
TVariable<IntPtrT>* var_index,
|
||||
Label* if_keyisunique,
|
||||
TVariable<Name>* var_unique,
|
||||
Label* if_bailout,
|
||||
Label* if_notinternalized) {
|
||||
DCHECK_EQ(MachineType::PointerRepresentation(), var_index->rep());
|
||||
DCHECK_EQ(MachineRepresentation::kTagged, var_unique->rep());
|
||||
Comment("TryToName");
|
||||
|
||||
Label if_hascachedindex(this), if_keyisnotindex(this), if_thinstring(this),
|
||||
if_keyisother(this, Label::kDeferred);
|
||||
Label if_keyisnotindex(this);
|
||||
// Handle Smi and HeapNumber keys.
|
||||
var_index->Bind(TryToIntptr(key, &if_keyisnotindex));
|
||||
*var_index = TryToIntptr(key, &if_keyisnotindex);
|
||||
Goto(if_keyisindex);
|
||||
|
||||
BIND(&if_keyisnotindex);
|
||||
TNode<Map> key_map = LoadMap(key);
|
||||
var_unique->Bind(key);
|
||||
// Symbols are unique.
|
||||
GotoIf(IsSymbolMap(key_map), if_keyisunique);
|
||||
TNode<Uint16T> key_instance_type = LoadMapInstanceType(key_map);
|
||||
// Miss if |key| is not a String.
|
||||
STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE);
|
||||
GotoIfNot(IsStringInstanceType(key_instance_type), &if_keyisother);
|
||||
{
|
||||
Label if_symbol(this), if_string(this),
|
||||
if_keyisother(this, Label::kDeferred);
|
||||
TNode<HeapObject> key_heap_object = CAST(key);
|
||||
TNode<Map> key_map = LoadMap(key_heap_object);
|
||||
|
||||
// |key| is a String. Check if it has a cached array index.
|
||||
TNode<Uint32T> hash = LoadNameHashField(key);
|
||||
GotoIf(IsClearWord32(hash, Name::kDoesNotContainCachedArrayIndexMask),
|
||||
&if_hascachedindex);
|
||||
// No cached array index. If the string knows that it contains an index,
|
||||
// then it must be an uncacheable index. Handle this case in the runtime.
|
||||
GotoIf(IsClearWord32(hash, Name::kIsNotArrayIndexMask), if_bailout);
|
||||
// Check if we have a ThinString.
|
||||
GotoIf(InstanceTypeEqual(key_instance_type, THIN_STRING_TYPE),
|
||||
&if_thinstring);
|
||||
GotoIf(InstanceTypeEqual(key_instance_type, THIN_ONE_BYTE_STRING_TYPE),
|
||||
&if_thinstring);
|
||||
// Finally, check if |key| is internalized.
|
||||
STATIC_ASSERT(kNotInternalizedTag != 0);
|
||||
GotoIf(IsSetWord32(key_instance_type, kIsNotInternalizedMask),
|
||||
if_notinternalized != nullptr ? if_notinternalized : if_bailout);
|
||||
Goto(if_keyisunique);
|
||||
GotoIf(IsSymbolMap(key_map), &if_symbol);
|
||||
|
||||
BIND(&if_thinstring);
|
||||
var_unique->Bind(
|
||||
LoadObjectField<String>(CAST(key), ThinString::kActualOffset));
|
||||
Goto(if_keyisunique);
|
||||
// Miss if |key| is not a String.
|
||||
STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE);
|
||||
TNode<Uint16T> key_instance_type = LoadMapInstanceType(key_map);
|
||||
Branch(IsStringInstanceType(key_instance_type), &if_string, &if_keyisother);
|
||||
|
||||
BIND(&if_hascachedindex);
|
||||
var_index->Bind(DecodeWordFromWord32<Name::ArrayIndexValueBits>(hash));
|
||||
Goto(if_keyisindex);
|
||||
// Symbols are unique.
|
||||
BIND(&if_symbol);
|
||||
{
|
||||
*var_unique = CAST(key);
|
||||
Goto(if_keyisunique);
|
||||
}
|
||||
|
||||
BIND(&if_keyisother);
|
||||
GotoIfNot(InstanceTypeEqual(key_instance_type, ODDBALL_TYPE), if_bailout);
|
||||
var_unique->Bind(LoadObjectField(key, Oddball::kToStringOffset));
|
||||
Goto(if_keyisunique);
|
||||
BIND(&if_string);
|
||||
{
|
||||
Label if_hascachedindex(this), if_thinstring(this);
|
||||
|
||||
// |key| is a String. Check if it has a cached array index.
|
||||
TNode<String> key_string = CAST(key);
|
||||
TNode<Uint32T> hash = LoadNameHashField(key_string);
|
||||
GotoIf(IsClearWord32(hash, Name::kDoesNotContainCachedArrayIndexMask),
|
||||
&if_hascachedindex);
|
||||
// No cached array index. If the string knows that it contains an index,
|
||||
// then it must be an uncacheable index. Handle this case in the runtime.
|
||||
GotoIf(IsClearWord32(hash, Name::kIsNotArrayIndexMask), if_bailout);
|
||||
// Check if we have a ThinString.
|
||||
GotoIf(InstanceTypeEqual(key_instance_type, THIN_STRING_TYPE),
|
||||
&if_thinstring);
|
||||
GotoIf(InstanceTypeEqual(key_instance_type, THIN_ONE_BYTE_STRING_TYPE),
|
||||
&if_thinstring);
|
||||
// Finally, check if |key| is internalized.
|
||||
STATIC_ASSERT(kNotInternalizedTag != 0);
|
||||
GotoIf(IsSetWord32(key_instance_type, kIsNotInternalizedMask),
|
||||
if_notinternalized != nullptr ? if_notinternalized : if_bailout);
|
||||
|
||||
*var_unique = key_string;
|
||||
Goto(if_keyisunique);
|
||||
|
||||
BIND(&if_thinstring);
|
||||
*var_unique =
|
||||
LoadObjectField<String>(key_string, ThinString::kActualOffset);
|
||||
Goto(if_keyisunique);
|
||||
|
||||
BIND(&if_hascachedindex);
|
||||
*var_index =
|
||||
Signed(DecodeWordFromWord32<Name::ArrayIndexValueBits>(hash));
|
||||
Goto(if_keyisindex);
|
||||
}
|
||||
|
||||
BIND(&if_keyisother);
|
||||
{
|
||||
GotoIfNot(InstanceTypeEqual(key_instance_type, ODDBALL_TYPE), if_bailout);
|
||||
*var_unique =
|
||||
LoadObjectField<String>(key_heap_object, Oddball::kToStringOffset);
|
||||
Goto(if_keyisunique);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CodeStubAssembler::TryInternalizeString(
|
||||
Node* string, Label* if_index, Variable* var_index, Label* if_internalized,
|
||||
Variable* var_internalized, Label* if_not_internalized, Label* if_bailout) {
|
||||
DCHECK(var_index->rep() == MachineType::PointerRepresentation());
|
||||
DCHECK_EQ(var_internalized->rep(), MachineRepresentation::kTagged);
|
||||
CSA_SLOW_ASSERT(this, IsString(string));
|
||||
SloppyTNode<String> string, Label* if_index, TVariable<IntPtrT>* var_index,
|
||||
Label* if_internalized, TVariable<Name>* var_internalized,
|
||||
Label* if_not_internalized, Label* if_bailout) {
|
||||
TNode<ExternalReference> function =
|
||||
ExternalConstant(ExternalReference::try_internalize_string_function());
|
||||
TNode<ExternalReference> const isolate_ptr =
|
||||
ExternalConstant(ExternalReference::isolate_address(isolate()));
|
||||
Node* result =
|
||||
CallCFunction(function, MachineType::AnyTagged(),
|
||||
std::make_pair(MachineType::Pointer(), isolate_ptr),
|
||||
std::make_pair(MachineType::AnyTagged(), string));
|
||||
TNode<Object> result =
|
||||
CAST(CallCFunction(function, MachineType::AnyTagged(),
|
||||
std::make_pair(MachineType::Pointer(), isolate_ptr),
|
||||
std::make_pair(MachineType::AnyTagged(), string)));
|
||||
Label internalized(this);
|
||||
GotoIf(TaggedIsNotSmi(result), &internalized);
|
||||
TNode<IntPtrT> word_result = SmiUntag(result);
|
||||
TNode<IntPtrT> word_result = SmiUntag(CAST(result));
|
||||
GotoIf(IntPtrEqual(word_result, IntPtrConstant(ResultSentinel::kNotFound)),
|
||||
if_not_internalized);
|
||||
GotoIf(IntPtrEqual(word_result, IntPtrConstant(ResultSentinel::kUnsupported)),
|
||||
if_bailout);
|
||||
var_index->Bind(word_result);
|
||||
*var_index = word_result;
|
||||
Goto(if_index);
|
||||
|
||||
BIND(&internalized);
|
||||
var_internalized->Bind(result);
|
||||
*var_internalized = CAST(result);
|
||||
Goto(if_internalized);
|
||||
}
|
||||
|
||||
@ -10004,8 +10025,8 @@ void CodeStubAssembler::TryPrototypeChainLookup(
|
||||
GotoIf(InstanceTypeEqual(instance_type, JS_PROXY_TYPE), if_proxy);
|
||||
}
|
||||
|
||||
VARIABLE(var_index, MachineType::PointerRepresentation());
|
||||
VARIABLE(var_unique, MachineRepresentation::kTagged);
|
||||
TVARIABLE(IntPtrT, var_index);
|
||||
TVARIABLE(Name, var_unique);
|
||||
|
||||
Label if_keyisindex(this), if_iskeyunique(this);
|
||||
TryToName(key, &if_keyisindex, &var_index, &if_iskeyunique, &var_unique,
|
||||
@ -10433,14 +10454,16 @@ TNode<Map> CodeStubAssembler::LoadReceiverMap(SloppyTNode<Object> receiver) {
|
||||
[=] { return LoadMap(UncheckedCast<HeapObject>(receiver)); });
|
||||
}
|
||||
|
||||
TNode<IntPtrT> CodeStubAssembler::TryToIntptr(Node* key, Label* miss) {
|
||||
TNode<IntPtrT> CodeStubAssembler::TryToIntptr(SloppyTNode<Object> key,
|
||||
Label* miss) {
|
||||
TVARIABLE(IntPtrT, var_intptr_key);
|
||||
Label done(this, &var_intptr_key), key_is_smi(this);
|
||||
GotoIf(TaggedIsSmi(key), &key_is_smi);
|
||||
|
||||
// Try to convert a heap number to a Smi.
|
||||
GotoIfNot(IsHeapNumber(key), miss);
|
||||
GotoIfNot(IsHeapNumber(CAST(key)), miss);
|
||||
{
|
||||
TNode<Float64T> value = LoadHeapNumberValue(key);
|
||||
TNode<Float64T> value = LoadHeapNumberValue(CAST(key));
|
||||
TNode<Int32T> int_value = RoundFloat64ToInt32(value);
|
||||
GotoIfNot(Float64Equal(value, ChangeInt32ToFloat64(int_value)), miss);
|
||||
var_intptr_key = ChangeInt32ToIntPtr(int_value);
|
||||
@ -10449,7 +10472,7 @@ TNode<IntPtrT> CodeStubAssembler::TryToIntptr(Node* key, Label* miss) {
|
||||
|
||||
BIND(&key_is_smi);
|
||||
{
|
||||
var_intptr_key = SmiUntag(key);
|
||||
var_intptr_key = SmiUntag(CAST(key));
|
||||
Goto(&done);
|
||||
}
|
||||
|
||||
|
@ -2872,8 +2872,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
// Note: If |key| does not yet have a hash, |if_notinternalized| will be taken
|
||||
// even if |key| is an array index. |if_keyisunique| will never
|
||||
// be taken for array indices.
|
||||
void TryToName(Node* key, Label* if_keyisindex, Variable* var_index,
|
||||
Label* if_keyisunique, Variable* var_unique, Label* if_bailout,
|
||||
void TryToName(SloppyTNode<Object> key, Label* if_keyisindex,
|
||||
TVariable<IntPtrT>* var_index, Label* if_keyisunique,
|
||||
TVariable<Name>* var_unique, Label* if_bailout,
|
||||
Label* if_notinternalized = nullptr);
|
||||
|
||||
// Performs a hash computation and string table lookup for the given string,
|
||||
@ -2885,8 +2886,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
// - |if_not_internalized| if the string is not in the string table (but
|
||||
// does not add it).
|
||||
// - |if_bailout| for unsupported cases (e.g. uncachable array index).
|
||||
void TryInternalizeString(Node* string, Label* if_index, Variable* var_index,
|
||||
Label* if_internalized, Variable* var_internalized,
|
||||
void TryInternalizeString(SloppyTNode<String> string, Label* if_index,
|
||||
TVariable<IntPtrT>* var_index,
|
||||
Label* if_internalized,
|
||||
TVariable<Name>* var_internalized,
|
||||
Label* if_not_internalized, Label* if_bailout);
|
||||
|
||||
// Calculates array index for given dictionary entry and entry field.
|
||||
@ -3726,7 +3729,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
Node* receiver, Label* if_bailout,
|
||||
GetOwnPropertyMode mode = kCallJSGetter);
|
||||
|
||||
TNode<IntPtrT> TryToIntptr(Node* key, Label* miss);
|
||||
TNode<IntPtrT> TryToIntptr(SloppyTNode<Object> key, Label* miss);
|
||||
|
||||
void BranchIfPrototypesHaveNoElements(Node* receiver_map,
|
||||
Label* definitely_no_elements,
|
||||
|
@ -539,8 +539,8 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase(
|
||||
|
||||
BIND(&proxy);
|
||||
{
|
||||
VARIABLE(var_index, MachineType::PointerRepresentation());
|
||||
VARIABLE(var_unique, MachineRepresentation::kTagged);
|
||||
TVARIABLE(IntPtrT, var_index);
|
||||
TVARIABLE(Name, var_unique);
|
||||
|
||||
Label if_index(this), if_unique_name(this),
|
||||
to_name_failed(this, Label::kDeferred);
|
||||
@ -1624,8 +1624,8 @@ void AccessorAssembler::HandleStoreICProtoHandler(
|
||||
void AccessorAssembler::HandleStoreToProxy(const StoreICParameters* p,
|
||||
Node* proxy, Label* miss,
|
||||
ElementSupport support_elements) {
|
||||
VARIABLE(var_index, MachineType::PointerRepresentation());
|
||||
VARIABLE(var_unique, MachineRepresentation::kTagged);
|
||||
TVARIABLE(IntPtrT, var_index);
|
||||
TVARIABLE(Name, var_unique);
|
||||
|
||||
Label if_index(this), if_unique_name(this),
|
||||
to_name_failed(this, Label::kDeferred);
|
||||
@ -2927,13 +2927,13 @@ void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p,
|
||||
// We might have a name in feedback, and a weak fixed array in the next
|
||||
// slot.
|
||||
Comment("KeyedLoadIC_try_polymorphic_name");
|
||||
TVARIABLE(Object, var_name, p->name());
|
||||
TVARIABLE(Name, var_name);
|
||||
TVARIABLE(IntPtrT, var_index);
|
||||
Label if_polymorphic_name(this, &var_name), if_internalized(this),
|
||||
if_notinternalized(this, Label::kDeferred);
|
||||
Label if_polymorphic_name(this), feedback_matches(this),
|
||||
if_internalized(this), if_notinternalized(this, Label::kDeferred);
|
||||
|
||||
// Fast-case: The recorded {feedback} matches the {name}.
|
||||
GotoIf(TaggedEqual(strong_feedback, p->name()), &if_polymorphic_name);
|
||||
GotoIf(TaggedEqual(strong_feedback, p->name()), &feedback_matches);
|
||||
|
||||
// Try to internalize the {name} if it isn't already.
|
||||
TryToName(p->name(), &miss, &var_index, &if_internalized, &var_name, &miss,
|
||||
@ -2948,16 +2948,15 @@ void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p,
|
||||
|
||||
BIND(&if_notinternalized);
|
||||
{
|
||||
// Try to internalize the {name}.
|
||||
TNode<ExternalReference> function = ExternalConstant(
|
||||
ExternalReference::try_internalize_string_function());
|
||||
TNode<ExternalReference> const isolate_ptr =
|
||||
ExternalConstant(ExternalReference::isolate_address(isolate()));
|
||||
var_name = CAST(
|
||||
CallCFunction(function, MachineType::AnyTagged(),
|
||||
std::make_pair(MachineType::Pointer(), isolate_ptr),
|
||||
std::make_pair(MachineType::AnyTagged(), p->name())));
|
||||
Goto(&if_internalized);
|
||||
TVARIABLE(IntPtrT, var_index);
|
||||
TryInternalizeString(CAST(p->name()), &miss, &var_index, &if_internalized,
|
||||
&var_name, &miss, &miss);
|
||||
}
|
||||
|
||||
BIND(&feedback_matches);
|
||||
{
|
||||
var_name = CAST(p->name());
|
||||
Goto(&if_polymorphic_name);
|
||||
}
|
||||
|
||||
BIND(&if_polymorphic_name);
|
||||
@ -2983,71 +2982,84 @@ void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p,
|
||||
}
|
||||
|
||||
void AccessorAssembler::KeyedLoadICGeneric(const LoadICParameters* p) {
|
||||
TVARIABLE(IntPtrT, var_index);
|
||||
TVARIABLE(Object, var_unique, p->name());
|
||||
Label if_index(this), if_unique_name(this), if_notunique(this),
|
||||
if_other(this, Label::kDeferred), if_runtime(this, Label::kDeferred);
|
||||
Label if_runtime(this, Label::kDeferred);
|
||||
|
||||
Node* receiver = p->receiver();
|
||||
GotoIf(TaggedIsSmi(receiver), &if_runtime);
|
||||
GotoIf(IsNullOrUndefined(receiver), &if_runtime);
|
||||
|
||||
TryToName(p->name(), &if_index, &var_index, &if_unique_name, &var_unique,
|
||||
&if_other, &if_notunique);
|
||||
|
||||
BIND(&if_other);
|
||||
{
|
||||
TNode<Name> name =
|
||||
CAST(CallBuiltin(Builtins::kToName, p->context(), p->name()));
|
||||
var_unique = name;
|
||||
TryToName(name, &if_index, &var_index, &if_unique_name, &var_unique,
|
||||
&if_runtime, &if_notunique);
|
||||
}
|
||||
TVARIABLE(IntPtrT, var_index);
|
||||
TVARIABLE(Name, var_unique);
|
||||
Label if_index(this), if_unique_name(this), if_notunique(this),
|
||||
maybe_internalize_on_the_fly(this), if_other(this, Label::kDeferred);
|
||||
|
||||
BIND(&if_index);
|
||||
{
|
||||
TNode<Map> receiver_map = LoadMap(receiver);
|
||||
TNode<Uint16T> instance_type = LoadMapInstanceType(receiver_map);
|
||||
GenericElementLoad(receiver, receiver_map, instance_type, var_index.value(),
|
||||
&if_runtime);
|
||||
}
|
||||
TryToName(p->name(), &if_index, &var_index, &if_unique_name, &var_unique,
|
||||
&if_other, &if_notunique);
|
||||
|
||||
BIND(&if_unique_name);
|
||||
{
|
||||
LoadICParameters pp(p, var_unique.value());
|
||||
TNode<Map> receiver_map = LoadMap(receiver);
|
||||
TNode<Uint16T> instance_type = LoadMapInstanceType(receiver_map);
|
||||
GenericPropertyLoad(receiver, receiver_map, instance_type, &pp,
|
||||
&if_runtime);
|
||||
}
|
||||
BIND(&if_unique_name);
|
||||
{
|
||||
LoadICParameters pp(p, var_unique.value());
|
||||
TNode<Map> receiver_map = LoadMap(receiver);
|
||||
TNode<Uint16T> instance_type = LoadMapInstanceType(receiver_map);
|
||||
GenericPropertyLoad(receiver, receiver_map, instance_type, &pp,
|
||||
&if_runtime);
|
||||
}
|
||||
|
||||
BIND(&if_notunique);
|
||||
{
|
||||
if (FLAG_internalize_on_the_fly) {
|
||||
// Ideally we could return undefined directly here if the name is not
|
||||
// found in the string table, i.e. it was never internalized, but that
|
||||
// invariant doesn't hold with named property interceptors (at this
|
||||
// point), so we take the {if_runtime} path instead.
|
||||
Label if_in_string_table(this);
|
||||
TryInternalizeString(var_unique.value(), &if_index, &var_index,
|
||||
&if_in_string_table, &var_unique, &if_runtime,
|
||||
&if_runtime);
|
||||
{
|
||||
TVARIABLE(String, var_name);
|
||||
|
||||
BIND(&if_in_string_table);
|
||||
BIND(&if_other);
|
||||
{
|
||||
// TODO(bmeurer): We currently use a version of GenericPropertyLoad
|
||||
// here, where we don't try to probe the megamorphic stub cache after
|
||||
// successfully internalizing the incoming string. Past experiments
|
||||
// with this have shown that it causes too much traffic on the stub
|
||||
// cache. We may want to re-evaluate that in the future.
|
||||
LoadICParameters pp(p, var_unique.value());
|
||||
TNode<Map> receiver_map = LoadMap(receiver);
|
||||
TNode<Uint16T> instance_type = LoadMapInstanceType(receiver_map);
|
||||
GenericPropertyLoad(receiver, receiver_map, instance_type, &pp,
|
||||
&if_runtime, kDontUseStubCache);
|
||||
var_name =
|
||||
CAST(CallBuiltin(Builtins::kToName, p->context(), p->name()));
|
||||
TryToName(var_name.value(), &if_index, &var_index, &if_unique_name,
|
||||
&var_unique, &if_runtime, &maybe_internalize_on_the_fly);
|
||||
}
|
||||
} else {
|
||||
Goto(&if_runtime);
|
||||
|
||||
BIND(&if_notunique);
|
||||
{
|
||||
var_name = CAST(p->name());
|
||||
Goto(&maybe_internalize_on_the_fly);
|
||||
}
|
||||
|
||||
BIND(&maybe_internalize_on_the_fly);
|
||||
{
|
||||
if (FLAG_internalize_on_the_fly) {
|
||||
// Ideally we could return undefined directly here if the name is not
|
||||
// found in the string table, i.e. it was never internalized, but that
|
||||
// invariant doesn't hold with named property interceptors (at this
|
||||
// point), so we take the {if_runtime} path instead.
|
||||
Label if_in_string_table(this);
|
||||
TryInternalizeString(var_name.value(), &if_index, &var_index,
|
||||
&if_in_string_table, &var_unique, &if_runtime,
|
||||
&if_runtime);
|
||||
|
||||
BIND(&if_in_string_table);
|
||||
{
|
||||
// TODO(bmeurer): We currently use a version of GenericPropertyLoad
|
||||
// here, where we don't try to probe the megamorphic stub cache
|
||||
// after successfully internalizing the incoming string. Past
|
||||
// experiments with this have shown that it causes too much traffic
|
||||
// on the stub cache. We may want to re-evaluate that in the future.
|
||||
LoadICParameters pp(p, var_unique.value());
|
||||
TNode<Map> receiver_map = LoadMap(receiver);
|
||||
TNode<Uint16T> instance_type = LoadMapInstanceType(receiver_map);
|
||||
GenericPropertyLoad(receiver, receiver_map, instance_type, &pp,
|
||||
&if_runtime, kDontUseStubCache);
|
||||
}
|
||||
} else {
|
||||
Goto(&if_runtime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BIND(&if_index);
|
||||
{
|
||||
TNode<Map> receiver_map = LoadMap(receiver);
|
||||
TNode<Uint16T> instance_type = LoadMapInstanceType(receiver_map);
|
||||
GenericElementLoad(receiver, receiver_map, instance_type,
|
||||
var_index.value(), &if_runtime);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3057,7 +3069,7 @@ void AccessorAssembler::KeyedLoadICGeneric(const LoadICParameters* p) {
|
||||
IncrementCounter(isolate()->counters()->ic_keyed_load_generic_slow(), 1);
|
||||
// TODO(jkummerow): Should we use the GetProperty TF stub instead?
|
||||
TailCallRuntime(Runtime::kGetProperty, p->context(), p->receiver(),
|
||||
var_unique.value());
|
||||
p->name());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -988,7 +988,7 @@ void KeyedStoreGenericAssembler::KeyedStoreGeneric(
|
||||
TNode<Context> context, TNode<Object> receiver_maybe_smi, TNode<Object> key,
|
||||
TNode<Object> value, Maybe<LanguageMode> language_mode) {
|
||||
TVARIABLE(IntPtrT, var_index);
|
||||
TVARIABLE(Object, var_unique, key);
|
||||
TVARIABLE(Name, var_unique);
|
||||
Label if_index(this), if_unique_name(this), not_internalized(this),
|
||||
slow(this);
|
||||
|
||||
@ -1023,7 +1023,7 @@ void KeyedStoreGenericAssembler::KeyedStoreGeneric(
|
||||
BIND(¬_internalized);
|
||||
{
|
||||
if (FLAG_internalize_on_the_fly) {
|
||||
TryInternalizeString(key, &if_index, &var_index, &if_unique_name,
|
||||
TryInternalizeString(CAST(key), &if_index, &var_index, &if_unique_name,
|
||||
&var_unique, &slow, &slow);
|
||||
} else {
|
||||
Goto(&slow);
|
||||
|
@ -495,7 +495,7 @@ TEST(TryToName) {
|
||||
Label if_keyisindex(&m), if_keyisunique(&m), if_bailout(&m);
|
||||
{
|
||||
TYPED_VARIABLE_DEF(IntPtrT, var_index, &m);
|
||||
TYPED_VARIABLE_DEF(Object, var_unique, &m);
|
||||
TYPED_VARIABLE_DEF(Name, var_unique, &m);
|
||||
|
||||
m.TryToName(key, &if_keyisindex, &var_index, &if_keyisunique, &var_unique,
|
||||
&if_bailout);
|
||||
|
Loading…
Reference in New Issue
Block a user