Allow inlining of named function expressions containing ThisFunction reference.

Named function expression have an implicit local variable that
refers to the current function (ThisFunction). Before we only could inline
anonymous function expressions like:

A.prototype.foo = function() {}

as opposed to

A.prototype.foo = function foo() {}

This change enables inlining function of expressions like this.
Review URL: http://codereview.chromium.org/8346032

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9699 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
fschneider@chromium.org 2011-10-19 11:41:22 +00:00
parent e5f23399b4
commit 2791cd5a2c
9 changed files with 22 additions and 7 deletions

View File

@ -1276,7 +1276,9 @@ class LPushArgument: public LTemplateInstruction<0, 1, 0> {
class LThisFunction: public LTemplateInstruction<1, 0, 0> {
public:
DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function")
DECLARE_HYDROGEN_ACCESSOR(ThisFunction)
};

View File

@ -2786,7 +2786,7 @@ void LCodeGen::DoPushArgument(LPushArgument* instr) {
void LCodeGen::DoThisFunction(LThisFunction* instr) {
Register result = ToRegister(instr->result());
__ ldr(result, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
LoadHeapObject(result, instr->hydrogen()->closure());
}

View File

@ -465,7 +465,7 @@ bool FunctionLiteral::IsInlineable() const {
bool ThisFunction::IsInlineable() const {
return false;
return true;
}

View File

@ -1347,7 +1347,7 @@ class HPushArgument: public HUnaryOperation {
class HThisFunction: public HTemplateInstruction<0> {
public:
HThisFunction() {
explicit HThisFunction(Handle<JSFunction> closure) : closure_(closure) {
set_representation(Representation::Tagged());
SetFlag(kUseGVN);
}
@ -1356,10 +1356,18 @@ class HThisFunction: public HTemplateInstruction<0> {
return Representation::None();
}
Handle<JSFunction> closure() const { return closure_; }
DECLARE_CONCRETE_INSTRUCTION(ThisFunction)
protected:
virtual bool DataEquals(HValue* other) { return true; }
virtual bool DataEquals(HValue* other) {
HThisFunction* b = HThisFunction::cast(other);
return *closure() == *b->closure();
}
private:
Handle<JSFunction> closure_;
};

View File

@ -6001,7 +6001,8 @@ void HGraphBuilder::VisitThisFunction(ThisFunction* expr) {
ASSERT(!HasStackOverflow());
ASSERT(current_block() != NULL);
ASSERT(current_block()->HasPredecessor());
HThisFunction* self = new(zone()) HThisFunction;
HThisFunction* self = new(zone()) HThisFunction(
function_state()->compilation_info()->closure());
return ast_context()->ReturnInstruction(self, expr->id());
}

View File

@ -2626,7 +2626,7 @@ void LCodeGen::DoPushArgument(LPushArgument* instr) {
void LCodeGen::DoThisFunction(LThisFunction* instr) {
Register result = ToRegister(instr->result());
__ mov(result, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
LoadHeapObject(result, instr->hydrogen()->closure());
}

View File

@ -1311,7 +1311,9 @@ class LPushArgument: public LTemplateInstruction<0, 1, 0> {
class LThisFunction: public LTemplateInstruction<1, 0, 0> {
public:
DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function")
DECLARE_HYDROGEN_ACCESSOR(ThisFunction)
};

View File

@ -2572,7 +2572,7 @@ void LCodeGen::DoPushArgument(LPushArgument* instr) {
void LCodeGen::DoThisFunction(LThisFunction* instr) {
Register result = ToRegister(instr->result());
__ movq(result, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
LoadHeapObject(result, instr->hydrogen()->closure());
}

View File

@ -1276,7 +1276,9 @@ class LPushArgument: public LTemplateInstruction<0, 1, 0> {
class LThisFunction: public LTemplateInstruction<1, 0, 0> {
public:
DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function")
DECLARE_HYDROGEN_ACCESSOR(ThisFunction)
};