From 8faca47ef205733c8069b060624a1dfd7cc1e1f6 Mon Sep 17 00:00:00 2001 From: "mvstanton@chromium.org" Date: Wed, 8 Oct 2014 09:15:09 +0000 Subject: [PATCH] Updates to maintain flag --vector-ics Experimental feature vector-ics needs some maintenance. R=yangguo@chromium.org Review URL: https://codereview.chromium.org/638523003 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24458 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/debug-arm.cc | 6 ++++- src/arm/full-codegen-arm.cc | 8 +++++- src/arm64/debug-arm64.cc | 6 ++++- src/arm64/full-codegen-arm64.cc | 8 +++++- src/ast.cc | 11 ++++++++- src/ast.h | 17 ++++++++++++- src/code-stubs.cc | 10 +++++--- src/code-stubs.h | 44 +++++++++++++++++++++++++-------- src/ia32/builtins-ia32.cc | 22 ++++++++++------- src/ia32/debug-ia32.cc | 6 ++++- src/ia32/full-codegen-ia32.cc | 8 +++++- src/ic/ic.cc | 20 ++++++++------- src/ic/ic.h | 3 +-- src/mips/debug-mips.cc | 6 ++++- src/mips/full-codegen-mips.cc | 8 +++++- src/x64/builtins-x64.cc | 19 ++++++++------ src/x64/debug-x64.cc | 6 ++++- src/x64/full-codegen-x64.cc | 9 ++++++- 18 files changed, 164 insertions(+), 53 deletions(-) diff --git a/src/arm/debug-arm.cc b/src/arm/debug-arm.cc index 6d7d6b8ace..c9100576d2 100644 --- a/src/arm/debug-arm.cc +++ b/src/arm/debug-arm.cc @@ -178,7 +178,11 @@ void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) { // Calling convention for IC load (from ic-arm.cc). Register receiver = LoadDescriptor::ReceiverRegister(); Register name = LoadDescriptor::NameRegister(); - Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0); + RegList regs = receiver.bit() | name.bit(); + if (FLAG_vector_ics) { + regs |= VectorLoadICTrampolineDescriptor::SlotRegister().bit(); + } + Generate_DebugBreakCallHelper(masm, regs, 0); } diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc index 660c10fe62..8f16786487 100644 --- a/src/arm/full-codegen-arm.cc +++ b/src/arm/full-codegen-arm.cc @@ -1364,7 +1364,13 @@ void FullCodeGenerator::EmitLoadHomeObject(SuperReference* expr) { Handle home_object_symbol(isolate()->heap()->home_object_symbol()); __ Move(LoadDescriptor::NameRegister(), home_object_symbol); - CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId()); + if (FLAG_vector_ics) { + __ mov(VectorLoadICDescriptor::SlotRegister(), + Operand(Smi::FromInt(expr->HomeObjectFeedbackSlot()))); + CallLoadIC(NOT_CONTEXTUAL); + } else { + CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId()); + } __ cmp(r0, Operand(isolate()->factory()->undefined_value())); Label done; diff --git a/src/arm64/debug-arm64.cc b/src/arm64/debug-arm64.cc index f57d5b5ab2..dae5a28434 100644 --- a/src/arm64/debug-arm64.cc +++ b/src/arm64/debug-arm64.cc @@ -238,7 +238,11 @@ void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) { // Calling convention for IC load (from ic-arm.cc). Register receiver = LoadDescriptor::ReceiverRegister(); Register name = LoadDescriptor::NameRegister(); - Generate_DebugBreakCallHelper(masm, receiver.Bit() | name.Bit(), 0, x10); + RegList regs = receiver.Bit() | name.Bit(); + if (FLAG_vector_ics) { + regs |= VectorLoadICTrampolineDescriptor::SlotRegister().Bit(); + } + Generate_DebugBreakCallHelper(masm, regs, 0, x10); } diff --git a/src/arm64/full-codegen-arm64.cc b/src/arm64/full-codegen-arm64.cc index eeaef5f296..c5d6113517 100644 --- a/src/arm64/full-codegen-arm64.cc +++ b/src/arm64/full-codegen-arm64.cc @@ -1350,7 +1350,13 @@ void FullCodeGenerator::EmitLoadHomeObject(SuperReference* expr) { Handle home_object_symbol(isolate()->heap()->home_object_symbol()); __ Mov(LoadDescriptor::NameRegister(), Operand(home_object_symbol)); - CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId()); + if (FLAG_vector_ics) { + __ Mov(VectorLoadICDescriptor::SlotRegister(), + Smi::FromInt(expr->HomeObjectFeedbackSlot())); + CallLoadIC(NOT_CONTEXTUAL); + } else { + CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId()); + } __ Mov(x10, Operand(isolate()->factory()->undefined_value())); __ cmp(x0, x10); diff --git a/src/ast.cc b/src/ast.cc index 6deaae51c8..55a5ca18cf 100644 --- a/src/ast.cc +++ b/src/ast.cc @@ -1026,6 +1026,14 @@ CaseClause::CaseClause(Zone* zone, Expression* label, set_dont_turbofan_reason(k##NodeType); \ add_flag(kDontSelfOptimize); \ } +#define DONT_TURBOFAN_NODE_WITH_FEEDBACK_SLOTS(NodeType) \ + void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \ + increase_node_count(); \ + add_slot_node(node); \ + set_dont_crankshaft_reason(k##NodeType); \ + set_dont_turbofan_reason(k##NodeType); \ + add_flag(kDontSelfOptimize); \ + } #define DONT_SELFOPTIMIZE_NODE(NodeType) \ void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \ increase_node_count(); \ @@ -1100,7 +1108,8 @@ DONT_TURBOFAN_NODE(ForOfStatement) DONT_TURBOFAN_NODE(TryCatchStatement) DONT_TURBOFAN_NODE(TryFinallyStatement) DONT_TURBOFAN_NODE(ClassLiteral) -DONT_TURBOFAN_NODE(SuperReference) + +DONT_TURBOFAN_NODE_WITH_FEEDBACK_SLOTS(SuperReference) DONT_SELFOPTIMIZE_NODE(DoWhileStatement) DONT_SELFOPTIMIZE_NODE(WhileStatement) diff --git a/src/ast.h b/src/ast.h index 11dda68879..c75938e22d 100644 --- a/src/ast.h +++ b/src/ast.h @@ -2591,13 +2591,28 @@ class SuperReference FINAL : public Expression { TypeFeedbackId HomeObjectFeedbackId() { return reuse(id()); } + // Type feedback information. + virtual int ComputeFeedbackSlotCount() { return FLAG_vector_ics ? 1 : 0; } + virtual void SetFirstFeedbackSlot(int slot) { + homeobject_feedback_slot_ = slot; + } + + int HomeObjectFeedbackSlot() { + DCHECK(!FLAG_vector_ics || + homeobject_feedback_slot_ != kInvalidFeedbackSlot); + return homeobject_feedback_slot_; + } + protected: SuperReference(Zone* zone, VariableProxy* this_var, int pos, IdGen* id_gen) - : Expression(zone, pos, id_gen), this_var_(this_var) { + : Expression(zone, pos, id_gen), + this_var_(this_var), + homeobject_feedback_slot_(kInvalidFeedbackSlot) { DCHECK(this_var->is_this()); } VariableProxy* this_var_; + int homeobject_feedback_slot_; }; diff --git a/src/code-stubs.cc b/src/code-stubs.cc index 195b315ea5..357324b903 100644 --- a/src/code-stubs.cc +++ b/src/code-stubs.cc @@ -592,6 +592,9 @@ void HandlerStub::InitializeDescriptor(CodeStubDescriptor* descriptor) { CallInterfaceDescriptor HandlerStub::GetCallInterfaceDescriptor() { if (kind() == Code::LOAD_IC || kind() == Code::KEYED_LOAD_IC) { + if (FLAG_vector_ics) { + return VectorLoadICDescriptor(isolate()); + } return LoadDescriptor(isolate()); } else { DCHECK_EQ(Code::STORE_IC, kind()); @@ -627,14 +630,13 @@ static void InitializeVectorLoadStub(Isolate* isolate, void VectorLoadStub::InitializeDescriptor(CodeStubDescriptor* descriptor) { InitializeVectorLoadStub(isolate(), descriptor, - FUNCTION_ADDR(VectorLoadIC_MissFromStubFailure)); + FUNCTION_ADDR(LoadIC_MissFromStubFailure)); } void VectorKeyedLoadStub::InitializeDescriptor(CodeStubDescriptor* descriptor) { - InitializeVectorLoadStub( - isolate(), descriptor, - FUNCTION_ADDR(VectorKeyedLoadIC_MissFromStubFailure)); + InitializeVectorLoadStub(isolate(), descriptor, + FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure)); } diff --git a/src/code-stubs.h b/src/code-stubs.h index fc34ed0591..9f6e9de984 100644 --- a/src/code-stubs.h +++ b/src/code-stubs.h @@ -857,7 +857,13 @@ class FunctionPrototypeStub : public PlatformCodeStub { // TODO(mvstanton): only the receiver register is accessed. When this is // translated to a hydrogen code stub, a new CallInterfaceDescriptor // should be created that just uses that register for more efficient code. - DEFINE_CALL_INTERFACE_DESCRIPTOR(Load); + virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE { + if (FLAG_vector_ics) { + return VectorLoadICDescriptor(isolate()); + } + return LoadDescriptor(isolate()); + } + DEFINE_PLATFORM_CODE_STUB(FunctionPrototype, PlatformCodeStub); }; @@ -1819,7 +1825,13 @@ class LoadDictionaryElementStub : public HydrogenCodeStub { explicit LoadDictionaryElementStub(Isolate* isolate) : HydrogenCodeStub(isolate) {} - DEFINE_CALL_INTERFACE_DESCRIPTOR(Load); + virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE { + if (FLAG_vector_ics) { + return VectorLoadICDescriptor(isolate()); + } + return LoadDescriptor(isolate()); + } + DEFINE_HYDROGEN_CODE_STUB(LoadDictionaryElement, HydrogenCodeStub); }; @@ -1831,7 +1843,11 @@ class KeyedLoadGenericStub : public HydrogenCodeStub { virtual Code::Kind GetCodeKind() const { return Code::KEYED_LOAD_IC; } virtual InlineCacheState GetICState() const { return GENERIC; } + // Since KeyedLoadGeneric stub doesn't miss (simply calls runtime), it + // doesn't need to use the VectorLoadICDescriptor for the case when + // flag --vector-ics is true. DEFINE_CALL_INTERFACE_DESCRIPTOR(Load); + DEFINE_HYDROGEN_CODE_STUB(KeyedLoadGeneric, HydrogenCodeStub); }; @@ -1845,9 +1861,7 @@ class LoadICTrampolineStub : public PlatformCodeStub { virtual Code::Kind GetCodeKind() const OVERRIDE { return Code::LOAD_IC; } - virtual InlineCacheState GetICState() const FINAL OVERRIDE { - return GENERIC; - } + virtual InlineCacheState GetICState() const FINAL OVERRIDE { return DEFAULT; } virtual ExtraICState GetExtraICState() const FINAL OVERRIDE { return static_cast(minor_key_); @@ -1893,7 +1907,13 @@ class MegamorphicLoadStub : public HydrogenCodeStub { return static_cast(sub_minor_key()); } - DEFINE_CALL_INTERFACE_DESCRIPTOR(Load); + virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE { + if (FLAG_vector_ics) { + return VectorLoadICDescriptor(isolate()); + } + return LoadDescriptor(isolate()); + } + DEFINE_HYDROGEN_CODE_STUB(MegamorphicLoad, HydrogenCodeStub); }; @@ -1907,9 +1927,7 @@ class VectorLoadStub : public HydrogenCodeStub { virtual Code::Kind GetCodeKind() const OVERRIDE { return Code::LOAD_IC; } - virtual InlineCacheState GetICState() const FINAL OVERRIDE { - return GENERIC; - } + virtual InlineCacheState GetICState() const FINAL OVERRIDE { return DEFAULT; } virtual ExtraICState GetExtraICState() const FINAL OVERRIDE { return static_cast(sub_minor_key()); @@ -2003,7 +2021,13 @@ class LoadFastElementStub : public HydrogenCodeStub { class ElementsKindBits: public BitField {}; class IsJSArrayBits: public BitField {}; - DEFINE_CALL_INTERFACE_DESCRIPTOR(Load); + virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE { + if (FLAG_vector_ics) { + return VectorLoadICDescriptor(isolate()); + } + return LoadDescriptor(isolate()); + } + DEFINE_HYDROGEN_CODE_STUB(LoadFastElement, HydrogenCodeStub); }; diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc index c24e77f317..eeddcd2900 100644 --- a/src/ia32/builtins-ia32.cc +++ b/src/ia32/builtins-ia32.cc @@ -1002,17 +1002,21 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { __ bind(&loop); __ mov(receiver, Operand(ebp, kArgumentsOffset)); // load arguments - // Use inline caching to speed up access to arguments. if (FLAG_vector_ics) { - __ mov(VectorLoadICDescriptor::SlotRegister(), - Immediate(Smi::FromInt(0))); + // TODO(mvstanton): Vector-based ics need additional infrastructure to + // be embedded here. For now, just call the runtime. + __ push(receiver); + __ push(key); + __ CallRuntime(Runtime::kGetProperty, 2); + } else { + // Use inline caching to speed up access to arguments. + Handle ic = CodeFactory::KeyedLoadIC(masm->isolate()).code(); + __ call(ic, RelocInfo::CODE_TARGET); + // It is important that we do not have a test instruction after the + // call. A test instruction after the call is used to indicate that + // we have generated an inline version of the keyed load. In this + // case, we know that we are not generating a test instruction next. } - Handle ic = CodeFactory::KeyedLoadIC(masm->isolate()).code(); - __ call(ic, RelocInfo::CODE_TARGET); - // It is important that we do not have a test instruction after the - // call. A test instruction after the call is used to indicate that - // we have generated an inline version of the keyed load. In this - // case, we know that we are not generating a test instruction next. // Push the nth argument. __ push(eax); diff --git a/src/ia32/debug-ia32.cc b/src/ia32/debug-ia32.cc index 4331b088fb..34b33b2c17 100644 --- a/src/ia32/debug-ia32.cc +++ b/src/ia32/debug-ia32.cc @@ -182,7 +182,11 @@ void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) { // Register state for IC load call (from ic-ia32.cc). Register receiver = LoadDescriptor::ReceiverRegister(); Register name = LoadDescriptor::NameRegister(); - Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0, false); + RegList regs = receiver.bit() | name.bit(); + if (FLAG_vector_ics) { + regs |= VectorLoadICTrampolineDescriptor::SlotRegister().bit(); + } + Generate_DebugBreakCallHelper(masm, regs, 0, false); } diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc index 39d4d7644e..f7addef20b 100644 --- a/src/ia32/full-codegen-ia32.cc +++ b/src/ia32/full-codegen-ia32.cc @@ -1287,7 +1287,13 @@ void FullCodeGenerator::EmitLoadHomeObject(SuperReference* expr) { Handle home_object_symbol(isolate()->heap()->home_object_symbol()); __ mov(LoadDescriptor::NameRegister(), home_object_symbol); - CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId()); + if (FLAG_vector_ics) { + __ mov(VectorLoadICDescriptor::SlotRegister(), + Immediate(Smi::FromInt(expr->HomeObjectFeedbackSlot()))); + CallLoadIC(NOT_CONTEXTUAL); + } else { + CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId()); + } __ cmp(eax, isolate()->factory()->undefined_value()); Label done; diff --git a/src/ic/ic.cc b/src/ic/ic.cc index 52e3496c38..63f2ffa9d9 100644 --- a/src/ic/ic.cc +++ b/src/ic/ic.cc @@ -2647,15 +2647,17 @@ RUNTIME_FUNCTION(LoadElementWithInterceptor) { } -RUNTIME_FUNCTION(VectorLoadIC_MissFromStubFailure) { - // TODO(mvstanton): To be enabled when ICs can accept a vector and slot - return NULL; -} - - -RUNTIME_FUNCTION(VectorKeyedLoadIC_MissFromStubFailure) { - // TODO(mvstanton): To be enabled when ICs can accept a vector and slot - return NULL; +RUNTIME_FUNCTION(LoadIC_MissFromStubFailure) { + TimerEventScope timer(isolate); + HandleScope scope(isolate); + DCHECK(args.length() == 2); + LoadIC ic(IC::EXTRA_CALL_FRAME, isolate); + Handle receiver = args.at(0); + Handle key = args.at(1); + ic.UpdateState(receiver, key); + Handle result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); + return *result; } diff --git a/src/ic/ic.h b/src/ic/ic.h index e1facd6358..295d9b83c7 100644 --- a/src/ic/ic.h +++ b/src/ic/ic.h @@ -680,8 +680,7 @@ DECLARE_RUNTIME_FUNCTION(BinaryOpIC_Miss); DECLARE_RUNTIME_FUNCTION(BinaryOpIC_MissWithAllocationSite); DECLARE_RUNTIME_FUNCTION(CompareNilIC_Miss); DECLARE_RUNTIME_FUNCTION(ToBooleanIC_Miss); -DECLARE_RUNTIME_FUNCTION(VectorLoadIC_MissFromStubFailure); -DECLARE_RUNTIME_FUNCTION(VectorKeyedLoadIC_MissFromStubFailure); +DECLARE_RUNTIME_FUNCTION(LoadIC_MissFromStubFailure); // Support functions for callbacks handlers. DECLARE_RUNTIME_FUNCTION(StoreCallbackProperty); diff --git a/src/mips/debug-mips.cc b/src/mips/debug-mips.cc index 96a146715f..5b3591c81b 100644 --- a/src/mips/debug-mips.cc +++ b/src/mips/debug-mips.cc @@ -187,7 +187,11 @@ void DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) { void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) { Register receiver = LoadDescriptor::ReceiverRegister(); Register name = LoadDescriptor::NameRegister(); - Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0); + RegList regs = receiver.bit() | name.bit(); + if (FLAG_vector_ics) { + regs |= VectorLoadICTrampolineDescriptor::SlotRegister().bit(); + } + Generate_DebugBreakCallHelper(masm, regs, 0); } diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc index 6cd81a6efe..91572da75b 100644 --- a/src/mips/full-codegen-mips.cc +++ b/src/mips/full-codegen-mips.cc @@ -1351,7 +1351,13 @@ void FullCodeGenerator::EmitLoadHomeObject(SuperReference* expr) { Handle home_object_symbol(isolate()->heap()->home_object_symbol()); __ li(LoadDescriptor::NameRegister(), home_object_symbol); - CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId()); + if (FLAG_vector_ics) { + __ li(VectorLoadICDescriptor::SlotRegister(), + Operand(Smi::FromInt(expr->HomeObjectFeedbackSlot()))); + CallLoadIC(NOT_CONTEXTUAL); + } else { + CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId()); + } Label done; __ Branch(&done, ne, v0, Operand(isolate()->factory()->undefined_value())); diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc index 194d8a6b2e..64ba35115b 100644 --- a/src/x64/builtins-x64.cc +++ b/src/x64/builtins-x64.cc @@ -1075,14 +1075,19 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { // Use inline caching to speed up access to arguments. if (FLAG_vector_ics) { - __ Move(VectorLoadICDescriptor::SlotRegister(), Smi::FromInt(0)); + // TODO(mvstanton): Vector-based ics need additional infrastructure to + // be embedded here. For now, just call the runtime. + __ Push(receiver); + __ Push(key); + __ CallRuntime(Runtime::kGetProperty, 2); + } else { + Handle ic = CodeFactory::KeyedLoadIC(masm->isolate()).code(); + __ Call(ic, RelocInfo::CODE_TARGET); + // It is important that we do not have a test instruction after the + // call. A test instruction after the call is used to indicate that + // we have generated an inline version of the keyed load. In this + // case, we know that we are not generating a test instruction next. } - Handle ic = CodeFactory::KeyedLoadIC(masm->isolate()).code(); - __ Call(ic, RelocInfo::CODE_TARGET); - // It is important that we do not have a test instruction after the - // call. A test instruction after the call is used to indicate that - // we have generated an inline version of the keyed load. In this - // case, we know that we are not generating a test instruction next. // Push the nth argument. __ Push(rax); diff --git a/src/x64/debug-x64.cc b/src/x64/debug-x64.cc index c8b7c2246a..c8f9456f75 100644 --- a/src/x64/debug-x64.cc +++ b/src/x64/debug-x64.cc @@ -164,7 +164,11 @@ void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) { // Register state for IC load call (from ic-x64.cc). Register receiver = LoadDescriptor::ReceiverRegister(); Register name = LoadDescriptor::NameRegister(); - Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0, false); + RegList regs = receiver.bit() | name.bit(); + if (FLAG_vector_ics) { + regs |= VectorLoadICTrampolineDescriptor::SlotRegister().bit(); + } + Generate_DebugBreakCallHelper(masm, regs, 0, false); } diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc index d351ff420e..3d1116e8db 100644 --- a/src/x64/full-codegen-x64.cc +++ b/src/x64/full-codegen-x64.cc @@ -1321,7 +1321,14 @@ void FullCodeGenerator::EmitLoadHomeObject(SuperReference* expr) { Handle home_object_symbol(isolate()->heap()->home_object_symbol()); __ Move(LoadDescriptor::NameRegister(), home_object_symbol); - CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId()); + if (FLAG_vector_ics) { + __ Move(VectorLoadICDescriptor::SlotRegister(), + Smi::FromInt(expr->HomeObjectFeedbackSlot())); + CallLoadIC(NOT_CONTEXTUAL); + } else { + CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId()); + } + __ Cmp(rax, isolate()->factory()->undefined_value()); Label done;