Commit 596c292a authored by Mythri's avatar Mythri Committed by Commit Bot

[ic] Update KeyedStoreIC to handle no feedback vector case

The megamorphic case in the KeyedStoreIC doesn't use/update any feedback.
We could use this path to fast path some of the keyed stores instead of
misssing to the runtime when the feedback vector is not available. This
cl, moves the check for feedback vector from the bytecode handler to the
KeyedStoreIC and calls the KeyedStoreIC_Megamorphic builtin when there is
no valid feedback vector. This will help improve the performance of no
feedback/jitless case.

Bug: v8:8293
Change-Id: I71c128b355d47ac20e50fc836f4bc2cf0aab1154
Reviewed-on: https://chromium-review.googlesource.com/c/1460946
Commit-Queue: Mythri Alle <mythria@chromium.org>
Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59590}
parent 3b4caded
......@@ -211,7 +211,7 @@ namespace internal {
/* Handlers */ \
TFH(KeyedLoadIC_PolymorphicName, LoadWithVector) \
TFH(KeyedLoadIC_Slow, LoadWithVector) \
TFH(KeyedStoreIC_Megamorphic, StoreWithVector) \
TFH(KeyedStoreIC_Megamorphic, Store) \
TFH(KeyedStoreIC_Slow, StoreWithVector) \
TFH(LoadGlobalIC_Slow, LoadWithVector) \
TFH(LoadIC_FunctionPrototype, LoadWithVector) \
......
......@@ -2982,11 +2982,14 @@ void AccessorAssembler::KeyedStoreIC(const StoreICParameters* p) {
Label if_handler(this, &var_handler),
try_polymorphic(this, Label::kDeferred),
try_megamorphic(this, Label::kDeferred),
no_feedback(this, Label::kDeferred),
try_polymorphic_name(this, Label::kDeferred);
Node* receiver_map = LoadReceiverMap(p->receiver);
GotoIf(IsDeprecatedMap(receiver_map), &miss);
GotoIf(IsUndefined(p->vector), &no_feedback);
// Check monomorphic case.
TNode<MaybeObject> feedback =
TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler,
......@@ -3013,11 +3016,15 @@ void AccessorAssembler::KeyedStoreIC(const StoreICParameters* p) {
{
// Check megamorphic case.
Comment("KeyedStoreIC_try_megamorphic");
GotoIfNot(
Branch(
WordEqual(strong_feedback, LoadRoot(RootIndex::kmegamorphic_symbol)),
&try_polymorphic_name);
&no_feedback, &try_polymorphic_name);
}
BIND(&no_feedback);
{
TailCallBuiltin(Builtins::kKeyedStoreIC_Megamorphic, p->context,
p->receiver, p->name, p->value, p->slot, p->vector);
p->receiver, p->name, p->value, p->slot);
}
BIND(&try_polymorphic_name);
......
......@@ -2463,12 +2463,24 @@ RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Miss) {
// Runtime functions don't follow the IC's calling convention.
Handle<Object> value = args.at(0);
Handle<Smi> slot = args.at<Smi>(1);
Handle<FeedbackVector> vector = args.at<FeedbackVector>(2);
Handle<HeapObject> maybe_vector = args.at<HeapObject>(2);
Handle<Object> receiver = args.at(3);
Handle<Object> key = args.at(4);
FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value());
FeedbackSlotKind kind = vector->GetKind(vector_slot);
// When the feedback vector is not valid the slot can only be of type
// StoreKeyed. Storing in array literals falls back to
// StoreInArrayLiterIC_Miss. This function is also used from store handlers
// installed in feedback vectors. In such cases, we need to get the kind from
// feedback vector slot since the handlers are used for both for StoreKeyed
// and StoreInArrayLiteral kinds.
FeedbackSlotKind kind = FeedbackSlotKind::kStoreKeyedStrict;
Handle<FeedbackVector> vector = Handle<FeedbackVector>();
if (!maybe_vector->IsUndefined()) {
DCHECK(maybe_vector->IsFeedbackVector());
vector = Handle<FeedbackVector>::cast(maybe_vector);
kind = vector->GetKind(vector_slot);
}
// The elements store stubs miss into this function, but they are shared by
// different ICs.
......@@ -2487,20 +2499,6 @@ RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Miss) {
}
}
RUNTIME_FUNCTION(Runtime_KeyedStoreICNoFeedback_Miss) {
HandleScope scope(isolate);
DCHECK_EQ(3, args.length());
// Runtime functions don't follow the IC's calling convention.
Handle<Object> value = args.at(0);
Handle<Object> receiver = args.at(1);
Handle<Object> key = args.at(2);
// TODO(mythria): Replace StoreKeyedStrict/Sloppy with StoreKeyed.
KeyedStoreIC ic(isolate, Handle<FeedbackVector>(), FeedbackSlot(),
FeedbackSlotKind::kStoreKeyedStrict);
RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value));
}
RUNTIME_FUNCTION(Runtime_StoreInArrayLiteralIC_Miss) {
HandleScope scope(isolate);
DCHECK_EQ(5, args.length());
......
......@@ -60,8 +60,7 @@ class KeyedStoreGenericAssembler : public AccessorAssembler {
// 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);
Maybe<LanguageMode> language_mode);
void EmitGenericElementStore(Node* receiver, Node* receiver_map,
Node* instance_type, Node* intptr_index,
......@@ -957,8 +956,7 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore(
// Helper that is used by the public KeyedStoreGeneric and by SetProperty.
void KeyedStoreGenericAssembler::KeyedStoreGeneric(
TNode<Context> context, TNode<Object> receiver, TNode<Object> key,
TNode<Object> value, Maybe<LanguageMode> language_mode, TNode<Smi> slot,
TNode<FeedbackVector> vector) {
TNode<Object> value, Maybe<LanguageMode> language_mode) {
TVARIABLE(IntPtrT, var_index);
TVARIABLE(Object, var_unique, key);
Label if_index(this), if_unique_name(this), not_internalized(this),
......@@ -984,8 +982,8 @@ void KeyedStoreGenericAssembler::KeyedStoreGeneric(
BIND(&if_unique_name);
{
Comment("key is unique name");
StoreICParameters p(context, receiver, var_unique.value(), value, slot,
vector);
StoreICParameters p(context, receiver, var_unique.value(), value, nullptr,
nullptr);
ExitPoint direct_exit(this);
EmitGenericPropertyStore(CAST(receiver), receiver_map, &p, &direct_exit,
&slow, language_mode);
......@@ -1016,17 +1014,14 @@ void KeyedStoreGenericAssembler::KeyedStoreGeneric(
}
void KeyedStoreGenericAssembler::KeyedStoreGeneric() {
typedef StoreWithVectorDescriptor Descriptor;
typedef StoreDescriptor 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);
KeyedStoreGeneric(context, receiver, name, value, Nothing<LanguageMode>());
}
void KeyedStoreGenericAssembler::SetProperty(TNode<Context> context,
......@@ -1034,8 +1029,7 @@ void KeyedStoreGenericAssembler::SetProperty(TNode<Context> context,
TNode<Object> key,
TNode<Object> value,
LanguageMode language_mode) {
KeyedStoreGeneric(context, receiver, key, value, Just(language_mode),
TNode<Smi>(), TNode<FeedbackVector>());
KeyedStoreGeneric(context, receiver, key, value, Just(language_mode));
}
void KeyedStoreGenericAssembler::StoreIC_Uninitialized() {
......
......@@ -668,20 +668,9 @@ IGNITION_HANDLER(StaKeyedProperty, InterpreterAssembler) {
Node* maybe_vector = LoadFeedbackVectorUnchecked();
Node* context = GetContext();
Label no_feedback(this, Label::kDeferred), end(this);
VARIABLE(var_result, MachineRepresentation::kTagged);
GotoIf(IsUndefined(maybe_vector), &no_feedback);
var_result.Bind(CallBuiltin(Builtins::kKeyedStoreIC, context, object, name,
value, smi_slot, maybe_vector));
Goto(&end);
Bind(&no_feedback);
var_result.Bind(CallRuntime(Runtime::kKeyedStoreICNoFeedback_Miss, context,
value, object, name));
Goto(&end);
Bind(&end);
// To avoid special logic in the deoptimizer to re-materialize the value in
// the accumulator, we overwrite the accumulator after the IC call. It
// doesn't really matter what we write to the accumulator here, since we
......
......@@ -556,7 +556,6 @@ namespace internal {
F(ElementsTransitionAndStoreIC_Miss, 6, 1) \
F(KeyedLoadIC_Miss, 4, 1) \
F(KeyedStoreIC_Miss, 5, 1) \
F(KeyedStoreICNoFeedback_Miss, 3, 1) \
F(StoreInArrayLiteralIC_Miss, 5, 1) \
F(KeyedStoreIC_Slow, 3, 1) \
F(LoadAccessorProperty, 4, 1) \
......
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