Commit ac66ba62 authored by Simon Zünd's avatar Simon Zünd Committed by Commit Bot

Implement SetProperty stub

This CL adds a SetProperty method to the KeyedStoreGenericGenerator
that mirrors what "KeyedStoreGeneric" does (used for
KeyedStoreIC_MegaMorphic). This new SetProperty method is then used
in the SetProperty stub.

Change-Id: I72a684238ef6c3b8c4db8ba957d5b79238f7e495
Reviewed-on: https://chromium-review.googlesource.com/1164945
Commit-Queue: Simon Zünd <szuend@google.com>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55005}
parent b0fc9db5
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "src/code-stub-assembler.h" #include "src/code-stub-assembler.h"
#include "src/heap/heap-inl.h" #include "src/heap/heap-inl.h"
#include "src/ic/accessor-assembler.h" #include "src/ic/accessor-assembler.h"
#include "src/ic/keyed-store-generic.h"
#include "src/macro-assembler.h" #include "src/macro-assembler.h"
#include "src/objects/debug-objects.h" #include "src/objects/debug-objects.h"
#include "src/objects/shared-function-info.h" #include "src/objects/shared-function-info.h"
...@@ -1265,10 +1266,8 @@ TF_BUILTIN(SetProperty, CodeStubAssembler) { ...@@ -1265,10 +1266,8 @@ TF_BUILTIN(SetProperty, CodeStubAssembler) {
TNode<Object> key = CAST(Parameter(Descriptor::kKey)); TNode<Object> key = CAST(Parameter(Descriptor::kKey));
TNode<Object> value = CAST(Parameter(Descriptor::kValue)); TNode<Object> value = CAST(Parameter(Descriptor::kValue));
// TODO(szuend): Add implementation similar to KeyedStoreGeneric(). KeyedStoreGenericGenerator::SetProperty(state(), context, receiver, key,
value, LanguageMode::kStrict);
TailCallRuntime(Runtime::kSetProperty, context, receiver, key, value,
SmiConstant(LanguageMode::kStrict));
} }
} // namespace internal } // namespace internal
......
...@@ -35,6 +35,14 @@ class KeyedStoreGenericAssembler : public AccessorAssembler { ...@@ -35,6 +35,14 @@ class KeyedStoreGenericAssembler : public AccessorAssembler {
TNode<BoolT> is_simple_receiver, TNode<Name> unique_name, TNode<BoolT> is_simple_receiver, TNode<Name> unique_name,
TNode<Object> value, LanguageMode language_mode); TNode<Object> value, LanguageMode language_mode);
// [[Set]], but more generic than the above. This impl does essentially the
// same as "KeyedStoreGeneric" but does not use feedback slot and uses a
// hardcoded LanguageMode instead of trying to deduce it from the feedback
// slot's kind.
void SetProperty(TNode<Context> context, TNode<Object> receiver,
TNode<Object> key, TNode<Object> value,
LanguageMode language_mode);
private: private:
enum UpdateLength { enum UpdateLength {
kDontChangeLength, kDontChangeLength,
...@@ -44,6 +52,12 @@ class KeyedStoreGenericAssembler : public AccessorAssembler { ...@@ -44,6 +52,12 @@ class KeyedStoreGenericAssembler : public AccessorAssembler {
enum UseStubCache { kUseStubCache, kDontUseStubCache }; enum UseStubCache { kUseStubCache, kDontUseStubCache };
// Helper that is used by the public KeyedStoreGeneric and by SetProperty.
void KeyedStoreGeneric(TNode<Context> context, TNode<Object> receiver,
TNode<Object> key, TNode<Object> value,
Maybe<LanguageMode> language_mode, TNode<Smi> slot,
TNode<FeedbackVector> vector);
void EmitGenericElementStore(Node* receiver, Node* receiver_map, void EmitGenericElementStore(Node* receiver, Node* receiver_map,
Node* instance_type, Node* intptr_index, Node* instance_type, Node* intptr_index,
Node* value, Node* context, Label* slow); Node* value, Node* context, Label* slow);
...@@ -119,6 +133,14 @@ void KeyedStoreGenericGenerator::SetProperty( ...@@ -119,6 +133,14 @@ void KeyedStoreGenericGenerator::SetProperty(
language_mode); language_mode);
} }
void KeyedStoreGenericGenerator::SetProperty(
compiler::CodeAssemblerState* state, TNode<Context> context,
TNode<Object> receiver, TNode<Object> key, TNode<Object> value,
LanguageMode language_mode) {
KeyedStoreGenericAssembler assembler(state);
assembler.SetProperty(context, receiver, key, value, language_mode);
}
void KeyedStoreGenericAssembler::BranchIfPrototypesHaveNonFastElements( void KeyedStoreGenericAssembler::BranchIfPrototypesHaveNonFastElements(
Node* receiver_map, Label* non_fast_elements, Label* only_fast_elements) { Node* receiver_map, Label* non_fast_elements, Label* only_fast_elements) {
VARIABLE(var_map, MachineRepresentation::kTagged); VARIABLE(var_map, MachineRepresentation::kTagged);
...@@ -879,30 +901,24 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore( ...@@ -879,30 +901,24 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore(
} }
} }
void KeyedStoreGenericAssembler::KeyedStoreGeneric() { // Helper that is used by the public KeyedStoreGeneric and by SetProperty.
typedef StoreWithVectorDescriptor Descriptor; void KeyedStoreGenericAssembler::KeyedStoreGeneric(
TNode<Context> context, TNode<Object> receiver, TNode<Object> key,
Node* receiver = Parameter(Descriptor::kReceiver); TNode<Object> value, Maybe<LanguageMode> language_mode, TNode<Smi> slot,
Node* name = Parameter(Descriptor::kName); TNode<FeedbackVector> vector) {
Node* value = Parameter(Descriptor::kValue); TVARIABLE(WordT, var_index);
Node* slot = Parameter(Descriptor::kSlot); TVARIABLE(Object, var_unique, key);
Node* vector = Parameter(Descriptor::kVector);
Node* context = Parameter(Descriptor::kContext);
VARIABLE(var_index, MachineType::PointerRepresentation());
VARIABLE(var_unique, MachineRepresentation::kTagged);
var_unique.Bind(name); // Dummy initialization.
Label if_index(this), if_unique_name(this), not_internalized(this), Label if_index(this), if_unique_name(this), not_internalized(this),
slow(this); slow(this);
GotoIf(TaggedIsSmi(receiver), &slow); GotoIf(TaggedIsSmi(receiver), &slow);
Node* receiver_map = LoadMap(receiver); TNode<Map> receiver_map = LoadMap(CAST(receiver));
TNode<Int32T> instance_type = LoadMapInstanceType(receiver_map); TNode<Int32T> instance_type = LoadMapInstanceType(receiver_map);
// Receivers requiring non-standard element accesses (interceptors, access // Receivers requiring non-standard element accesses (interceptors, access
// checks, strings and string wrappers, proxies) are handled in the runtime. // checks, strings and string wrappers, proxies) are handled in the runtime.
GotoIf(IsCustomElementsReceiverInstanceType(instance_type), &slow); GotoIf(IsCustomElementsReceiverInstanceType(instance_type), &slow);
TryToName(name, &if_index, &var_index, &if_unique_name, &var_unique, &slow, TryToName(key, &if_index, &var_index, &if_unique_name, &var_unique, &slow,
&not_internalized); &not_internalized);
BIND(&if_index); BIND(&if_index);
...@@ -917,13 +933,15 @@ void KeyedStoreGenericAssembler::KeyedStoreGeneric() { ...@@ -917,13 +933,15 @@ void KeyedStoreGenericAssembler::KeyedStoreGeneric() {
Comment("key is unique name"); Comment("key is unique name");
StoreICParameters p(context, receiver, var_unique.value(), value, slot, StoreICParameters p(context, receiver, var_unique.value(), value, slot,
vector); vector);
EmitGenericPropertyStore(receiver, receiver_map, &p, &slow); ExitPoint direct_exit(this);
EmitGenericPropertyStore(CAST(receiver), receiver_map, &p, &direct_exit,
&slow, language_mode);
} }
BIND(&not_internalized); BIND(&not_internalized);
{ {
if (FLAG_internalize_on_the_fly) { if (FLAG_internalize_on_the_fly) {
TryInternalizeString(name, &if_index, &var_index, &if_unique_name, TryInternalizeString(key, &if_index, &var_index, &if_unique_name,
&var_unique, &slow, &slow); &var_unique, &slow, &slow);
} else { } else {
Goto(&slow); Goto(&slow);
...@@ -933,18 +951,45 @@ void KeyedStoreGenericAssembler::KeyedStoreGeneric() { ...@@ -933,18 +951,45 @@ void KeyedStoreGenericAssembler::KeyedStoreGeneric() {
BIND(&slow); BIND(&slow);
{ {
Comment("KeyedStoreGeneric_slow"); Comment("KeyedStoreGeneric_slow");
VARIABLE(var_language_mode, MachineRepresentation::kTaggedSigned, if (language_mode.IsJust()) {
SmiConstant(LanguageMode::kStrict)); TailCallRuntime(Runtime::kSetProperty, context, receiver, key, value,
Label call_runtime(this); SmiConstant(language_mode.FromJust()));
BranchIfStrictMode(vector, slot, &call_runtime); } else {
var_language_mode.Bind(SmiConstant(LanguageMode::kSloppy)); TVARIABLE(Smi, var_language_mode, SmiConstant(LanguageMode::kStrict));
Goto(&call_runtime); Label call_runtime(this);
BIND(&call_runtime); BranchIfStrictMode(vector, slot, &call_runtime);
TailCallRuntime(Runtime::kSetProperty, context, receiver, name, value, var_language_mode = SmiConstant(LanguageMode::kSloppy);
var_language_mode.value()); Goto(&call_runtime);
BIND(&call_runtime);
TailCallRuntime(Runtime::kSetProperty, context, receiver, key, value,
var_language_mode.value());
}
} }
} }
void KeyedStoreGenericAssembler::KeyedStoreGeneric() {
typedef StoreWithVectorDescriptor Descriptor;
TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver));
TNode<Object> name = CAST(Parameter(Descriptor::kName));
TNode<Object> value = CAST(Parameter(Descriptor::kValue));
TNode<Smi> slot = CAST(Parameter(Descriptor::kSlot));
TNode<FeedbackVector> vector = CAST(Parameter(Descriptor::kVector));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
KeyedStoreGeneric(context, receiver, name, value, Nothing<LanguageMode>(),
slot, vector);
}
void KeyedStoreGenericAssembler::SetProperty(TNode<Context> context,
TNode<Object> receiver,
TNode<Object> key,
TNode<Object> value,
LanguageMode language_mode) {
KeyedStoreGeneric(context, receiver, key, value, Just(language_mode),
TNode<Smi>(), TNode<FeedbackVector>());
}
void KeyedStoreGenericAssembler::StoreIC_Uninitialized() { void KeyedStoreGenericAssembler::StoreIC_Uninitialized() {
typedef StoreWithVectorDescriptor Descriptor; typedef StoreWithVectorDescriptor Descriptor;
......
...@@ -23,6 +23,13 @@ class KeyedStoreGenericGenerator { ...@@ -23,6 +23,13 @@ class KeyedStoreGenericGenerator {
TNode<Context> context, TNode<JSReceiver> receiver, TNode<Context> context, TNode<JSReceiver> receiver,
TNode<BoolT> is_simple_receiver, TNode<Name> name, TNode<BoolT> is_simple_receiver, TNode<Name> name,
TNode<Object> value, LanguageMode language_mode); TNode<Object> value, LanguageMode language_mode);
// Same as above but more generic. I.e. the receiver can by anything and the
// key does not have to be unique. Essentially the same as KeyedStoreGeneric.
static void SetProperty(compiler::CodeAssemblerState* state,
TNode<Context> context, TNode<Object> receiver,
TNode<Object> key, TNode<Object> value,
LanguageMode language_mode);
}; };
class StoreICUninitializedGenerator { class StoreICUninitializedGenerator {
......
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