Commit 194c43a1 authored by jkummerow's avatar jkummerow Committed by Commit bot

[stubs] Port KeyedStoreIC dispatcher to TurboFan

BUG=

Review-Url: https://chromiumcodereview.appspot.com/2403483002
Cr-Commit-Position: refs/heads/master@{#40423}
parent 3c91cdea
......@@ -101,6 +101,10 @@ Callable CodeFactory::StoreICInOptimizedCode(Isolate* isolate,
// static
Callable CodeFactory::KeyedStoreIC(Isolate* isolate,
LanguageMode language_mode) {
if (FLAG_tf_store_ic_stub) {
KeyedStoreICTrampolineTFStub stub(isolate, StoreICState(language_mode));
return make_callable(stub);
}
KeyedStoreICTrampolineStub stub(isolate, StoreICState(language_mode));
return make_callable(stub);
}
......@@ -108,10 +112,23 @@ Callable CodeFactory::KeyedStoreIC(Isolate* isolate,
// static
Callable CodeFactory::KeyedStoreICInOptimizedCode(Isolate* isolate,
LanguageMode language_mode) {
if (FLAG_tf_store_ic_stub) {
KeyedStoreICTFStub stub(isolate, StoreICState(language_mode));
return make_callable(stub);
}
KeyedStoreICStub stub(isolate, StoreICState(language_mode));
return make_callable(stub);
}
// static
Callable CodeFactory::KeyedStoreIC_Megamorphic(Isolate* isolate,
LanguageMode language_mode) {
return Callable(language_mode == STRICT
? isolate->builtins()->KeyedStoreIC_Megamorphic_Strict()
: isolate->builtins()->KeyedStoreIC_Megamorphic(),
StoreWithVectorDescriptor(isolate));
}
// static
Callable CodeFactory::CompareIC(Isolate* isolate, Token::Value op) {
CompareICStub stub(isolate, op);
......
......@@ -50,6 +50,7 @@ class V8_EXPORT_PRIVATE CodeFactory final {
static Callable KeyedStoreIC(Isolate* isolate, LanguageMode mode);
static Callable KeyedStoreICInOptimizedCode(Isolate* isolate,
LanguageMode mode);
static Callable KeyedStoreIC_Megamorphic(Isolate* isolate, LanguageMode mode);
static Callable ResumeGenerator(Isolate* isolate);
......
......@@ -4728,6 +4728,48 @@ void CodeStubAssembler::HandlePolymorphicCase(
}
}
void CodeStubAssembler::HandleKeyedStorePolymorphicCase(
compiler::Node* receiver_map, compiler::Node* feedback, Label* if_handler,
Variable* var_handler, Label* if_transition_handler,
Variable* var_transition_map_cell, Label* if_miss) {
DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep());
DCHECK_EQ(MachineRepresentation::kTagged, var_transition_map_cell->rep());
const int kEntrySize = 3;
Variable var_index(this, MachineType::PointerRepresentation());
Label loop(this, &var_index);
var_index.Bind(IntPtrConstant(0));
Node* length = LoadAndUntagFixedArrayBaseLength(feedback);
Goto(&loop);
Bind(&loop);
{
Node* index = var_index.value();
GotoIf(UintPtrGreaterThanOrEqual(index, length), if_miss);
Node* cached_map = LoadWeakCellValue(
LoadFixedArrayElement(feedback, index, 0, INTPTR_PARAMETERS));
Label next_entry(this);
GotoIf(WordNotEqual(receiver_map, cached_map), &next_entry);
Node* maybe_transition_map_cell =
LoadFixedArrayElement(feedback, index, kPointerSize, INTPTR_PARAMETERS);
var_handler->Bind(LoadFixedArrayElement(feedback, index, 2 * kPointerSize,
INTPTR_PARAMETERS));
GotoIf(WordEqual(maybe_transition_map_cell,
LoadRoot(Heap::kUndefinedValueRootIndex)),
if_handler);
var_transition_map_cell->Bind(maybe_transition_map_cell);
Goto(if_transition_handler);
Bind(&next_entry);
var_index.Bind(IntPtrAdd(index, IntPtrConstant(kEntrySize)));
Goto(&loop);
}
}
compiler::Node* CodeStubAssembler::StubCachePrimaryOffset(compiler::Node* name,
compiler::Node* map) {
// See v8::internal::StubCache::PrimaryOffset().
......@@ -5569,6 +5611,85 @@ void CodeStubAssembler::StoreIC(const StoreICParameters* p) {
}
}
void CodeStubAssembler::KeyedStoreIC(const StoreICParameters* p,
LanguageMode language_mode) {
Variable var_handler(this, MachineRepresentation::kTagged);
// TODO(ishell): defer blocks when it works.
Label if_handler(this, &var_handler), try_polymorphic(this),
try_megamorphic(this /*, Label::kDeferred*/),
try_polymorphic_name(this /*, Label::kDeferred*/),
miss(this /*, Label::kDeferred*/);
Node* receiver_map = LoadReceiverMap(p->receiver);
// Check monomorphic case.
Node* feedback =
TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler,
&var_handler, &try_polymorphic);
Bind(&if_handler);
{
Comment("KeyedStoreIC_if_handler");
StoreWithVectorDescriptor descriptor(isolate());
TailCallStub(descriptor, var_handler.value(), p->context, p->receiver,
p->name, p->value, p->slot, p->vector);
}
Bind(&try_polymorphic);
{
// CheckPolymorphic case.
Comment("KeyedStoreIC_try_polymorphic");
GotoUnless(
WordEqual(LoadMap(feedback), LoadRoot(Heap::kFixedArrayMapRootIndex)),
&try_megamorphic);
Label if_transition_handler(this);
Variable var_transition_map_cell(this, MachineRepresentation::kTagged);
HandleKeyedStorePolymorphicCase(receiver_map, feedback, &if_handler,
&var_handler, &if_transition_handler,
&var_transition_map_cell, &miss);
Bind(&if_transition_handler);
Comment("KeyedStoreIC_polymorphic_transition");
Node* transition_map =
LoadWeakCellValue(var_transition_map_cell.value(), &miss);
StoreTransitionDescriptor descriptor(isolate());
TailCallStub(descriptor, var_handler.value(), p->context, p->receiver,
p->name, transition_map, p->value, p->slot, p->vector);
}
Bind(&try_megamorphic);
{
// Check megamorphic case.
Comment("KeyedStoreIC_try_megamorphic");
GotoUnless(
WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)),
&try_polymorphic_name);
TailCallStub(
CodeFactory::KeyedStoreIC_Megamorphic(isolate(), language_mode),
p->context, p->receiver, p->name, p->value, p->slot, p->vector);
}
Bind(&try_polymorphic_name);
{
// We might have a name in feedback, and a fixed array in the next slot.
Comment("KeyedStoreIC_try_polymorphic_name");
GotoUnless(WordEqual(feedback, p->name), &miss);
// If the name comparison succeeded, we know we have a FixedArray with
// at least one map/handler pair.
Node* offset = ElementOffsetFromIndex(
p->slot, FAST_HOLEY_ELEMENTS, SMI_PARAMETERS,
FixedArray::kHeaderSize + kPointerSize - kHeapObjectTag);
Node* array = Load(MachineType::AnyTagged(), p->vector, offset);
HandlePolymorphicCase(receiver_map, array, &if_handler, &var_handler, &miss,
1);
}
Bind(&miss);
{
Comment("KeyedStoreIC_miss");
TailCallRuntime(Runtime::kKeyedStoreIC_Miss, p->context, p->value, p->slot,
p->vector, p->receiver, p->name);
}
}
void CodeStubAssembler::LoadGlobalIC(const LoadICParameters* p) {
Label try_handler(this), miss(this);
Node* weak_cell =
......
......@@ -804,6 +804,12 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
compiler::Node* feedback, Label* if_handler,
Variable* var_handler, Label* if_miss,
int unroll_count);
void HandleKeyedStorePolymorphicCase(compiler::Node* receiver_map,
compiler::Node* feedback,
Label* if_handler, Variable* var_handler,
Label* if_transition_handler,
Variable* var_transition_map_cell,
Label* if_miss);
compiler::Node* StubCachePrimaryOffset(compiler::Node* name,
compiler::Node* map);
......@@ -886,6 +892,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
void KeyedLoadIC(const LoadICParameters* p);
void KeyedLoadICGeneric(const LoadICParameters* p);
void StoreIC(const StoreICParameters* p);
void KeyedStoreIC(const StoreICParameters* p, LanguageMode language_mode);
void TransitionElementsKind(compiler::Node* object, compiler::Node* map,
ElementsKind from_kind, ElementsKind to_kind,
......
......@@ -561,6 +561,37 @@ void StoreICStub::GenerateAssembly(CodeStubAssembler* assembler) const {
assembler->StoreIC(&p);
}
void KeyedStoreICTrampolineTFStub::GenerateAssembly(
CodeStubAssembler* assembler) const {
typedef compiler::Node Node;
Node* receiver = assembler->Parameter(Descriptor::kReceiver);
Node* name = assembler->Parameter(Descriptor::kName);
Node* value = assembler->Parameter(Descriptor::kValue);
Node* slot = assembler->Parameter(Descriptor::kSlot);
Node* context = assembler->Parameter(Descriptor::kContext);
Node* vector = assembler->LoadTypeFeedbackVectorForStub();
CodeStubAssembler::StoreICParameters p(context, receiver, name, value, slot,
vector);
assembler->KeyedStoreIC(&p, StoreICState::GetLanguageMode(GetExtraICState()));
}
void KeyedStoreICTFStub::GenerateAssembly(CodeStubAssembler* assembler) const {
typedef compiler::Node Node;
Node* receiver = assembler->Parameter(Descriptor::kReceiver);
Node* name = assembler->Parameter(Descriptor::kName);
Node* value = assembler->Parameter(Descriptor::kValue);
Node* slot = assembler->Parameter(Descriptor::kSlot);
Node* vector = assembler->Parameter(Descriptor::kVector);
Node* context = assembler->Parameter(Descriptor::kContext);
CodeStubAssembler::StoreICParameters p(context, receiver, name, value, slot,
vector);
assembler->KeyedStoreIC(&p, StoreICState::GetLanguageMode(GetExtraICState()));
}
void StoreMapStub::GenerateAssembly(CodeStubAssembler* assembler) const {
typedef compiler::Node Node;
......
......@@ -126,6 +126,7 @@ class ObjectLiteral;
V(StoreField) \
V(StoreGlobal) \
V(StoreIC) \
V(KeyedStoreICTF) \
V(StoreInterceptor) \
V(StoreMap) \
V(StoreTransition) \
......@@ -138,7 +139,8 @@ class ObjectLiteral;
V(LoadICTrampoline) \
V(LoadGlobalICTrampoline) \
V(KeyedLoadICTrampolineTF) \
V(StoreICTrampoline)
V(StoreICTrampoline) \
V(KeyedStoreICTrampolineTF)
// List of code stubs only used on ARM 32 bits platforms.
#if V8_TARGET_ARCH_ARM
......@@ -2077,6 +2079,17 @@ class KeyedStoreICTrampolineStub : public PlatformCodeStub {
DEFINE_PLATFORM_CODE_STUB(KeyedStoreICTrampoline, PlatformCodeStub);
};
class KeyedStoreICTrampolineTFStub : public StoreICTrampolineStub {
public:
KeyedStoreICTrampolineTFStub(Isolate* isolate, const StoreICState& state)
: StoreICTrampolineStub(isolate, state) {}
void GenerateAssembly(CodeStubAssembler* assembler) const override;
Code::Kind GetCodeKind() const override { return Code::KEYED_STORE_IC; }
DEFINE_CODE_STUB(KeyedStoreICTrampolineTF, StoreICTrampolineStub);
};
class CallICTrampolineStub : public PlatformCodeStub {
public:
......@@ -2182,6 +2195,17 @@ class KeyedStoreICStub : public PlatformCodeStub {
void GenerateImpl(MacroAssembler* masm, bool in_frame);
};
class KeyedStoreICTFStub : public StoreICStub {
public:
KeyedStoreICTFStub(Isolate* isolate, const StoreICState& state)
: StoreICStub(isolate, state) {}
void GenerateAssembly(CodeStubAssembler* assembler) const override;
Code::Kind GetCodeKind() const override { return Code::KEYED_STORE_IC; }
DEFINE_CODE_STUB(KeyedStoreICTF, StoreICStub);
};
class DoubleToIStub : public PlatformCodeStub {
public:
......
......@@ -711,6 +711,14 @@ Node* CodeAssembler::TailCallStub(Callable const& callable, Node* context,
arg4, result_size);
}
Node* CodeAssembler::TailCallStub(Callable const& callable, Node* context,
Node* arg1, Node* arg2, Node* arg3,
Node* arg4, Node* arg5, size_t result_size) {
Node* target = HeapConstant(callable.code());
return TailCallStub(callable.descriptor(), target, context, arg1, arg2, arg3,
arg4, arg5, result_size);
}
Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor,
Node* target, Node* context, Node* arg1,
size_t result_size) {
......@@ -798,6 +806,27 @@ Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor,
return raw_assembler_->TailCallN(call_descriptor, target, args);
}
Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor,
Node* target, Node* context, Node* arg1,
Node* arg2, Node* arg3, Node* arg4,
Node* arg5, Node* arg6, size_t result_size) {
CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
isolate(), zone(), descriptor, descriptor.GetStackParameterCount(),
CallDescriptor::kSupportsTailCalls, Operator::kNoProperties,
MachineType::AnyTagged(), result_size);
Node** args = zone()->NewArray<Node*>(7);
args[0] = arg1;
args[1] = arg2;
args[2] = arg3;
args[3] = arg4;
args[4] = arg5;
args[5] = arg6;
args[6] = context;
return raw_assembler_->TailCallN(call_descriptor, target, args);
}
Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor,
Node* target, Node* context, const Arg& arg1,
const Arg& arg2, const Arg& arg3,
......
......@@ -402,6 +402,10 @@ class V8_EXPORT_PRIVATE CodeAssembler {
Node* TailCallStub(Callable const& callable, Node* context, Node* arg1,
Node* arg2, Node* arg3, Node* arg4,
size_t result_size = 1);
Node* TailCallStub(Callable const& callable, Node* context, Node* arg1,
Node* arg2, Node* arg3, Node* arg4, Node* arg5,
size_t result_size = 1);
Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
Node* context, Node* arg1, size_t result_size = 1);
Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
......@@ -416,6 +420,10 @@ class V8_EXPORT_PRIVATE CodeAssembler {
Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
Node* context, Node* arg1, Node* arg2, Node* arg3,
Node* arg4, Node* arg5, size_t result_size = 1);
Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
Node* context, Node* arg1, Node* arg2, Node* arg3,
Node* arg4, Node* arg5, Node* arg6,
size_t result_size = 1);
Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
Node* context, const Arg& arg1, const Arg& arg2,
......
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