From: kmillikin@chromium.org Date: Tue, 31 May 2011 11:54:46 +0000 (+0000) Subject: Support optimization of named function literals. X-Git-Tag: upstream/4.7.83~19271 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=00f2ff321ef2699b6720959d6035e473273e8634;p=platform%2Fupstream%2Fv8.git Support optimization of named function literals. Introduce a Hydrogen value for the value denoted by the function name. R=fschneider@chromium.org,mnaganov@chromium.org BUG= TEST= Review URL: http://codereview.chromium.org/7083024 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8121 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc index d4c2ac1..a3b6b95 100644 --- a/src/arm/lithium-arm.cc +++ b/src/arm/lithium-arm.cc @@ -1195,6 +1195,11 @@ LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { } +LInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) { + return instr->HasNoUses() ? NULL : DefineAsRegister(new LThisFunction); +} + + LInstruction* LChunkBuilder::DoContext(HContext* instr) { return instr->HasNoUses() ? NULL : DefineAsRegister(new LContext); } diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h index 1dbdd19..817d780 100644 --- a/src/arm/lithium-arm.h +++ b/src/arm/lithium-arm.h @@ -169,6 +169,7 @@ class LCodeGen; V(StringLength) \ V(SubI) \ V(TaggedToI) \ + V(ThisFunction) \ V(Throw) \ V(ToFastProperties) \ V(Typeof) \ @@ -1440,6 +1441,11 @@ class LPushArgument: public LTemplateInstruction<0, 1, 0> { }; +class LThisFunction: public LTemplateInstruction<1, 0, 0> { + DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function") +}; + + class LContext: public LTemplateInstruction<1, 0, 0> { public: DECLARE_CONCRETE_INSTRUCTION(Context, "context") diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc index 85eb90b..973145c 100644 --- a/src/arm/lithium-codegen-arm.cc +++ b/src/arm/lithium-codegen-arm.cc @@ -2801,6 +2801,12 @@ void LCodeGen::DoPushArgument(LPushArgument* instr) { } +void LCodeGen::DoThisFunction(LThisFunction* instr) { + Register result = ToRegister(instr->result()); + __ ldr(result, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); +} + + void LCodeGen::DoContext(LContext* instr) { Register result = ToRegister(instr->result()); __ mov(result, cp); diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h index 40da1b9..48662be 100644 --- a/src/hydrogen-instructions.h +++ b/src/hydrogen-instructions.h @@ -101,15 +101,14 @@ class LChunkBuilder; V(EnterInlined) \ V(ExternalArrayLength) \ V(FixedArrayLength) \ - V(ToInt32) \ V(ForceRepresentation) \ V(FunctionLiteral) \ V(GetCachedArrayIndex) \ V(GlobalObject) \ V(GlobalReceiver) \ V(Goto) \ - V(HasInstanceType) \ V(HasCachedArrayIndex) \ + V(HasInstanceType) \ V(In) \ V(InstanceOf) \ V(InstanceOfKnownGlobal) \ @@ -152,8 +151,8 @@ class LChunkBuilder; V(StoreGlobalCell) \ V(StoreGlobalGeneric) \ V(StoreKeyedFastElement) \ - V(StoreKeyedSpecializedArrayElement) \ V(StoreKeyedGeneric) \ + V(StoreKeyedSpecializedArrayElement) \ V(StoreNamedField) \ V(StoreNamedGeneric) \ V(StringAdd) \ @@ -162,8 +161,10 @@ class LChunkBuilder; V(StringLength) \ V(Sub) \ V(Test) \ + V(ThisFunction) \ V(Throw) \ V(ToFastProperties) \ + V(ToInt32) \ V(Typeof) \ V(TypeofIs) \ V(UnaryMathOperation) \ @@ -1302,6 +1303,24 @@ class HPushArgument: public HUnaryOperation { }; +class HThisFunction: public HTemplateInstruction<0> { + public: + HThisFunction() { + set_representation(Representation::Tagged()); + SetFlag(kUseGVN); + } + + virtual Representation RequiredInputRepresentation(int index) const { + return Representation::None(); + } + + DECLARE_CONCRETE_INSTRUCTION(ThisFunction) + + protected: + virtual bool DataEquals(HValue* other) { return true; } +}; + + class HContext: public HTemplateInstruction<0> { public: HContext() { @@ -1313,7 +1332,7 @@ class HContext: public HTemplateInstruction<0> { return Representation::None(); } - DECLARE_CONCRETE_INSTRUCTION(Context); + DECLARE_CONCRETE_INSTRUCTION(Context) protected: virtual bool DataEquals(HValue* other) { return true; } diff --git a/src/hydrogen.cc b/src/hydrogen.cc index 429d902..363fe82 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -2308,9 +2308,6 @@ HInstruction* HGraphBuilder::PreProcessCall(HCall* call) { void HGraphBuilder::SetupScope(Scope* scope) { - // We don't yet handle the function name for named function expressions. - if (scope->function() != NULL) return Bailout("named function expression"); - HConstant* undefined_constant = new(zone()) HConstant( isolate()->factory()->undefined_value(), Representation::Tagged()); AddInstruction(undefined_constant); @@ -5361,7 +5358,8 @@ void HGraphBuilder::VisitThisFunction(ThisFunction* expr) { ASSERT(!HasStackOverflow()); ASSERT(current_block() != NULL); ASSERT(current_block()->HasPredecessor()); - return Bailout("ThisFunction"); + HThisFunction* self = new(zone()) HThisFunction; + return ast_context()->ReturnInstruction(self, expr->id()); } diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index 2f84f7d..b41049d 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -2689,6 +2689,12 @@ void LCodeGen::DoPushArgument(LPushArgument* instr) { } +void LCodeGen::DoThisFunction(LThisFunction* instr) { + Register result = ToRegister(instr->result()); + __ mov(result, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); +} + + void LCodeGen::DoContext(LContext* instr) { Register result = ToRegister(instr->result()); __ mov(result, Operand(ebp, StandardFrameConstants::kContextOffset)); diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc index ea25343..1a9316c 100644 --- a/src/ia32/lithium-ia32.cc +++ b/src/ia32/lithium-ia32.cc @@ -1203,6 +1203,11 @@ LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { } +LInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) { + return instr->HasNoUses() ? NULL : DefineAsRegister(new LThisFunction); +} + + LInstruction* LChunkBuilder::DoContext(HContext* instr) { return instr->HasNoUses() ? NULL : DefineAsRegister(new LContext); } diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h index 5904791..37f87cd 100644 --- a/src/ia32/lithium-ia32.h +++ b/src/ia32/lithium-ia32.h @@ -163,6 +163,7 @@ class LCodeGen; V(StringLength) \ V(SubI) \ V(TaggedToI) \ + V(ThisFunction) \ V(Throw) \ V(ToFastProperties) \ V(Typeof) \ @@ -1471,6 +1472,11 @@ class LPushArgument: public LTemplateInstruction<0, 1, 0> { }; +class LThisFunction: public LTemplateInstruction<1, 0, 0> { + DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function") +}; + + class LContext: public LTemplateInstruction<1, 0, 0> { public: DECLARE_CONCRETE_INSTRUCTION(Context, "context") diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index c79f5e5..98ac81e 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -2693,6 +2693,12 @@ void LCodeGen::DoPushArgument(LPushArgument* instr) { } +void LCodeGen::DoThisFunction(LThisFunction* instr) { + Register result = ToRegister(instr->result()); + __ movq(result, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); +} + + void LCodeGen::DoContext(LContext* instr) { Register result = ToRegister(instr->result()); __ movq(result, rsi); diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc index 8ac7307..517870f 100644 --- a/src/x64/lithium-x64.cc +++ b/src/x64/lithium-x64.cc @@ -1191,6 +1191,11 @@ LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { } +LInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) { + return instr->HasNoUses() ? NULL : DefineAsRegister(new LThisFunction); +} + + LInstruction* LChunkBuilder::DoContext(HContext* instr) { return instr->HasNoUses() ? NULL : DefineAsRegister(new LContext); } diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h index e2f33b1..c0d989d 100644 --- a/src/x64/lithium-x64.h +++ b/src/x64/lithium-x64.h @@ -169,6 +169,7 @@ class LCodeGen; V(StringLength) \ V(SubI) \ V(TaggedToI) \ + V(ThisFunction) \ V(Throw) \ V(ToFastProperties) \ V(Typeof) \ @@ -1441,6 +1442,11 @@ class LPushArgument: public LTemplateInstruction<0, 1, 0> { }; +class LThisFunction: public LTemplateInstruction<1, 0, 0> { + DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function") +}; + + class LContext: public LTemplateInstruction<1, 0, 0> { public: DECLARE_CONCRETE_INSTRUCTION(Context, "context") diff --git a/test/cctest/cctest.status b/test/cctest/cctest.status index 01a8222..62bc82f 100644 --- a/test/cctest/cctest.status +++ b/test/cctest/cctest.status @@ -36,6 +36,9 @@ test-debug/DebuggerAgent: PASS, (PASS || FAIL) if $system == linux # BUG(382): Weird test. Can't guarantee that it never times out. test-api/ApplyInterruption: PASS || TIMEOUT +# BUG(1417): Crashes with --stress-opt --always-opt. +test-log/Issue23768: PASS || CRASH + # These tests always fail. They are here to test test.py. If # they don't fail then test.py has failed. test-serialize/TestThatAlwaysFails: FAIL