Bug 1185106 - Part 0.1: Refactor JSOP_DEFFUN. r=efaust,jandem,till,h4writer

MozReview-Commit-ID: 8XpAiHEzWVm
This commit is contained in:
Mariusz Kierski 2016-07-17 10:22:33 +09:00
Родитель 5c16f7080d
Коммит 8f8d409007
9 изменённых файлов: 41 добавлений и 55 удалений

Просмотреть файл

@ -6942,6 +6942,13 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
MOZ_ASSERT(pn->getOp() == JSOP_FUNWITHPROTO || pn->getOp() == JSOP_LAMBDA);
pn->setOp(JSOP_FUNWITHPROTO);
}
if (pn->getOp() == JSOP_DEFFUN) {
if (!emitIndex32(JSOP_LAMBDA, index))
return false;
return emit1(JSOP_DEFFUN);
}
return emitIndex32(pn->getOp(), index);
}
@ -6972,7 +6979,9 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
MOZ_ASSERT(sc->isGlobalContext() || sc->isEvalContext());
MOZ_ASSERT(pn->getOp() == JSOP_NOP);
switchToPrologue();
if (!emitIndex32(JSOP_DEFFUN, index))
if (!emitIndex32(JSOP_LAMBDA, index))
return false;
if (!emit1(JSOP_DEFFUN))
return false;
if (!updateSourceCoordNotes(pn->pn_pos.begin))
return false;

Просмотреть файл

@ -2750,15 +2750,14 @@ static const VMFunction DefFunOperationInfo =
bool
BaselineCompiler::emit_JSOP_DEFFUN()
{
RootedFunction fun(cx, script->getFunction(GET_UINT32_INDEX(pc)));
frame.syncStack(0);
masm.loadPtr(frame.addressOfEnvironmentChain(), R0.scratchReg());
frame.popRegsAndSync(1);
masm.unboxObject(R0, R0.scratchReg());
masm.loadPtr(frame.addressOfEnvironmentChain(), R1.scratchReg());
prepareVMCall();
pushArg(ImmGCPtr(fun));
pushArg(R0.scratchReg());
pushArg(R1.scratchReg());
pushArg(ImmGCPtr(script));
return callVM(DefFunOperationInfo);

Просмотреть файл

@ -4694,7 +4694,8 @@ CodeGenerator::visitDefFun(LDefFun* lir)
{
Register envChain = ToRegister(lir->environmentChain());
pushArg(ImmGCPtr(lir->mir()->fun()));
Register fun = ToRegister(lir->fun());
pushArg(fun);
pushArg(envChain);
pushArg(ImmGCPtr(current->mir()->info().script()));

Просмотреть файл

@ -13442,13 +13442,9 @@ IonBuilder::jsop_deflexical(uint32_t index)
bool
IonBuilder::jsop_deffun(uint32_t index)
{
JSFunction* fun = script()->getFunction(index);
if (IsAsmJSModule(fun))
return abort("asm.js module function");
MOZ_ASSERT(analysis().usesEnvironmentChain());
MDefFun* deffun = MDefFun::New(alloc(), fun, current->environmentChain());
MDefFun* deffun = MDefFun::New(alloc(), current->pop(), current->environmentChain());
current->add(deffun);
return resumeAfter(deffun);

Просмотреть файл

@ -207,7 +207,11 @@ LIRGenerator::visitDefLexical(MDefLexical* ins)
void
LIRGenerator::visitDefFun(MDefFun* ins)
{
LDefFun* lir = new(alloc()) LDefFun(useRegisterAtStart(ins->environmentChain()));
MDefinition* fun = ins->fun();
MOZ_ASSERT(fun->type() == MIRType::Object);
LDefFun* lir = new(alloc()) LDefFun(useRegisterAtStart(fun),
useRegisterAtStart(ins->environmentChain()));
add(lir, ins);
assignSafepoint(lir, ins);
}

Просмотреть файл

@ -8106,31 +8106,22 @@ class MDefLexical
};
class MDefFun
: public MUnaryInstruction,
public NoTypePolicy::Data
: public MBinaryInstruction,
public ObjectPolicy<0>::Data
{
CompilerFunction fun_;
private:
MDefFun(JSFunction* fun, MDefinition* envChain)
: MUnaryInstruction(envChain),
fun_(fun)
MDefFun(MDefinition* fun, MDefinition* envChain)
: MBinaryInstruction(fun, envChain)
{}
public:
INSTRUCTION_HEADER(DefFun)
TRIVIAL_NEW_WRAPPERS
NAMED_OPERANDS((0, environmentChain))
NAMED_OPERANDS((0, fun), (1, environmentChain))
JSFunction* fun() const {
return fun_;
}
bool possiblyCalls() const override {
return true;
}
bool appendRoots(MRootList& roots) const override {
return roots.append(fun_);
}
};
class MRegExp : public MNullaryInstruction

Просмотреть файл

@ -1550,19 +1550,23 @@ class LDefLexical : public LCallInstructionHelper<0, 0, 0>
}
};
class LDefFun : public LCallInstructionHelper<0, 1, 0>
class LDefFun : public LCallInstructionHelper<0, 2, 0>
{
public:
LIR_HEADER(DefFun)
explicit LDefFun(const LAllocation& envChain)
LDefFun(const LAllocation& fun, const LAllocation& envChain)
{
setOperand(0, envChain);
setOperand(0, fun);
setOperand(1, envChain);
}
const LAllocation* environmentChain() {
const LAllocation* fun() {
return getOperand(0);
}
const LAllocation* environmentChain() {
return getOperand(1);
}
MDefFun* mir() const {
return mir_->toDefFun();
}

Просмотреть файл

@ -3446,9 +3446,10 @@ CASE(JSOP_DEFFUN)
* a compound statement (not at the top statement level of global code, or
* at the top level of a function body).
*/
ReservedRooted<JSFunction*> fun(&rootFunction0, script->getFunction(GET_UINT32_INDEX(REGS.pc)));
ReservedRooted<JSFunction*> fun(&rootFunction0, &REGS.sp[-1].toObject().as<JSFunction>());
if (!DefFunOperation(cx, script, REGS.fp()->environmentChain(), fun))
goto error;
REGS.sp--;
}
END_CASE(JSOP_DEFFUN)
@ -4330,27 +4331,8 @@ js::LambdaArrow(JSContext* cx, HandleFunction fun, HandleObject parent, HandleVa
bool
js::DefFunOperation(JSContext* cx, HandleScript script, HandleObject envChain,
HandleFunction funArg)
HandleFunction fun)
{
/*
* If static link is not current scope, clone fun's object to link to the
* current scope via parent. We do this to enable sharing of compiled
* functions among multiple equivalent scopes, amortizing the cost of
* compilation over a number of executions. Examples include XUL scripts
* and event handlers shared among Firefox or other Mozilla app chrome
* windows, and user-defined JS functions precompiled and then shared among
* requests in server-side JS.
*/
RootedFunction fun(cx, funArg);
if (fun->isNative() || fun->environment() != envChain) {
fun = CloneFunctionObjectIfNotSingleton(cx, fun, envChain, nullptr, TenuredObject);
if (!fun)
return false;
} else {
MOZ_ASSERT(script->treatAsRunOnce());
MOZ_ASSERT(!script->functionNonDelazifying());
}
/*
* We define the function as a property of the variable object and not the
* current scope chain even for the case of function expression statements

Просмотреть файл

@ -1300,10 +1300,10 @@
* scripts where use of dynamic scoping inhibits optimization.
* Category: Variables and Scopes
* Type: Variables
* Operands: uint32_t funcIndex
* Stack: =>
* Operands:
* Stack: fun =>
*/ \
macro(JSOP_DEFFUN, 127,"deffun", NULL, 5, 0, 0, JOF_OBJECT) \
macro(JSOP_DEFFUN, 127,"deffun", NULL, 1, 1, 0, JOF_BYTE) \
/* Defines the new constant binding on global lexical scope.
*
* Throws if a binding with the same name already exists on the scope, or