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
class LThisFunction: public LTemplateInstruction<1, 0, 0> {
+ public:
DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function")
+ DECLARE_HYDROGEN_ACCESSOR(ThisFunction)
};
void LCodeGen::DoThisFunction(LThisFunction* instr) {
Register result = ToRegister(instr->result());
- __ ldr(result, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+ LoadHeapObject(result, instr->hydrogen()->closure());
}
bool ThisFunction::IsInlineable() const {
- return false;
+ return true;
}
class HThisFunction: public HTemplateInstruction<0> {
public:
- HThisFunction() {
+ explicit HThisFunction(Handle<JSFunction> closure) : closure_(closure) {
set_representation(Representation::Tagged());
SetFlag(kUseGVN);
}
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_;
};
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());
}
void LCodeGen::DoThisFunction(LThisFunction* instr) {
Register result = ToRegister(instr->result());
- __ mov(result, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
+ LoadHeapObject(result, instr->hydrogen()->closure());
}
class LThisFunction: public LTemplateInstruction<1, 0, 0> {
+ public:
DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function")
+ DECLARE_HYDROGEN_ACCESSOR(ThisFunction)
};
void LCodeGen::DoThisFunction(LThisFunction* instr) {
Register result = ToRegister(instr->result());
- __ movq(result, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
+ LoadHeapObject(result, instr->hydrogen()->closure());
}
class LThisFunction: public LTemplateInstruction<1, 0, 0> {
+ public:
DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function")
+ DECLARE_HYDROGEN_ACCESSOR(ThisFunction)
};