зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1541404 part 1 - Move initEnvironmentChain from BaselineCompiler to BaselineCodeGen. r=djvj
Also has some other minor prologue-related changes. The interpreter code here is slightly less optimal than it could be, but that will be easier to address in follow-up changes. Differential Revision: https://phabricator.services.mozilla.com/D25930 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
2fcda12c4d
Коммит
fba2d34e37
|
@ -1005,18 +1005,89 @@ void BaselineCompilerCodeGen::emitPreInitEnvironmentChain(
|
|||
template <>
|
||||
void BaselineInterpreterCodeGen::emitPreInitEnvironmentChain(
|
||||
Register nonFunctionEnv) {
|
||||
MOZ_CRASH("NYI: interpreter emitPreInitEnvironmentChain");
|
||||
Label notFunction, done;
|
||||
masm.branchTestPtr(Assembler::NonZero, frame.addressOfCalleeToken(),
|
||||
Imm32(CalleeTokenScriptBit), ¬Function);
|
||||
{
|
||||
masm.storePtr(ImmPtr(nullptr), frame.addressOfEnvironmentChain());
|
||||
masm.jump(&done);
|
||||
}
|
||||
masm.bind(¬Function);
|
||||
{ masm.storePtr(nonFunctionEnv, frame.addressOfEnvironmentChain()); }
|
||||
masm.bind(&done);
|
||||
}
|
||||
|
||||
template <>
|
||||
bool BaselineCompilerCodeGen::initEnvironmentChain() {
|
||||
void BaselineCompilerCodeGen::emitInitFrameFields() {
|
||||
masm.store32(Imm32(0), frame.addressOfFlags());
|
||||
}
|
||||
|
||||
template <>
|
||||
void BaselineInterpreterCodeGen::emitInitFrameFields() {
|
||||
MOZ_CRASH("NYI: interpreter emitInitFrameFields");
|
||||
}
|
||||
|
||||
template <>
|
||||
template <typename F1, typename F2>
|
||||
bool BaselineCompilerCodeGen::initEnvironmentChainHelper(
|
||||
const F1& initFunctionEnv, const F2& initGlobalOrEvalEnv,
|
||||
Register scratch) {
|
||||
if (handler.function()) {
|
||||
return initFunctionEnv();
|
||||
}
|
||||
if (handler.module()) {
|
||||
return true;
|
||||
}
|
||||
return initGlobalOrEvalEnv();
|
||||
}
|
||||
|
||||
template <>
|
||||
template <typename F1, typename F2>
|
||||
bool BaselineInterpreterCodeGen::initEnvironmentChainHelper(
|
||||
const F1& initFunctionEnv, const F2& initGlobalOrEvalEnv,
|
||||
Register scratch) {
|
||||
// There are three cases:
|
||||
//
|
||||
// 1) Function script: use code emitted by initFunctionEnv.
|
||||
// 2) Module script: no-op.
|
||||
// 3) Global or eval script: use code emitted by initGlobalOrEvalEnv.
|
||||
|
||||
Label notFunction, done;
|
||||
masm.loadPtr(frame.addressOfCalleeToken(), scratch);
|
||||
masm.branchTestPtr(Assembler::NonZero, scratch, Imm32(CalleeTokenScriptBit),
|
||||
¬Function);
|
||||
{
|
||||
if (!initFunctionEnv()) {
|
||||
return false;
|
||||
}
|
||||
masm.jump(&done);
|
||||
}
|
||||
masm.bind(¬Function);
|
||||
{
|
||||
masm.andPtr(Imm32(uint32_t(CalleeTokenMask)), scratch);
|
||||
masm.branchTest32(Assembler::NonZero,
|
||||
Address(scratch, JSScript::offsetOfImmutableFlags()),
|
||||
Imm32(uint32_t(JSScript::ImmutableFlags::IsModule)),
|
||||
&done);
|
||||
{
|
||||
if (!initGlobalOrEvalEnv()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
masm.bind(&done);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
bool BaselineCodeGen<Handler>::initEnvironmentChain() {
|
||||
CallVMPhase phase = POST_INITIALIZE;
|
||||
if (handler.needsEarlyStackCheck()) {
|
||||
phase = CHECK_OVER_RECURSED;
|
||||
}
|
||||
|
||||
RootedFunction fun(cx, handler.function());
|
||||
if (fun) {
|
||||
auto initFunctionEnv = [this, phase]() {
|
||||
// Use callee->environment as env chain. Note that we do this also
|
||||
// for needsSomeEnvironmentObject functions, so that the env chain
|
||||
// slot is properly initialized if the call triggers GC.
|
||||
|
@ -1026,7 +1097,7 @@ bool BaselineCompilerCodeGen::initEnvironmentChain() {
|
|||
masm.loadPtr(Address(callee, JSFunction::offsetOfEnvironment()), scope);
|
||||
masm.storePtr(scope, frame.addressOfEnvironmentChain());
|
||||
|
||||
if (fun->needsFunctionEnvironmentObjects()) {
|
||||
auto initEnv = [this, phase]() {
|
||||
// Call into the VM to create the proper environment objects.
|
||||
prepareVMCall();
|
||||
|
||||
|
@ -1034,11 +1105,14 @@ bool BaselineCompilerCodeGen::initEnvironmentChain() {
|
|||
pushArg(R0.scratchReg());
|
||||
|
||||
using Fn = bool (*)(JSContext*, BaselineFrame*);
|
||||
if (!callVMNonOp<Fn, jit::InitFunctionEnvironmentObjects>(phase)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if (!handler.module()) {
|
||||
return callVMNonOp<Fn, jit::InitFunctionEnvironmentObjects>(phase);
|
||||
};
|
||||
return emitTestScriptFlag(
|
||||
JSScript::ImmutableFlags::NeedsFunctionEnvironmentObjects, true,
|
||||
initEnv, R2.scratchReg());
|
||||
};
|
||||
|
||||
auto initGlobalOrEvalEnv = [this, phase]() {
|
||||
// EnvironmentChain pointer in BaselineFrame has already been initialized
|
||||
// in prologue, but we need to check for redeclaration errors in global and
|
||||
// eval scripts.
|
||||
|
@ -1050,17 +1124,11 @@ bool BaselineCompilerCodeGen::initEnvironmentChain() {
|
|||
pushArg(R0.scratchReg());
|
||||
|
||||
using Fn = bool (*)(JSContext*, HandleObject, HandleScript);
|
||||
if (!callVMNonOp<Fn, js::CheckGlobalOrEvalDeclarationConflicts>(phase)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return callVMNonOp<Fn, js::CheckGlobalOrEvalDeclarationConflicts>(phase);
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool BaselineInterpreterCodeGen::initEnvironmentChain() {
|
||||
MOZ_CRASH("NYI: interpreter initEnvironmentChain");
|
||||
return initEnvironmentChainHelper(initFunctionEnv, initGlobalOrEvalEnv,
|
||||
R2.scratchReg());
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
|
@ -6055,8 +6123,8 @@ bool BaselineCodeGen<Handler>::emitPrologue() {
|
|||
// Initialize BaselineFrame. For eval scripts, the env chain
|
||||
// is passed in R1, so we have to be careful not to clobber it.
|
||||
|
||||
// Initialize BaselineFrame::flags.
|
||||
masm.store32(Imm32(0), frame.addressOfFlags());
|
||||
// Initialize BaselineFrame::flags and interpreter fields.
|
||||
emitInitFrameFields();
|
||||
|
||||
// Handle env chain pre-initialization (in case GC gets run
|
||||
// during stack check). For global and eval scripts, the env
|
||||
|
|
|
@ -476,11 +476,17 @@ class BaselineCodeGen {
|
|||
MOZ_MUST_USE bool emitStackCheck();
|
||||
MOZ_MUST_USE bool emitArgumentTypeChecks();
|
||||
MOZ_MUST_USE bool emitDebugPrologue();
|
||||
|
||||
template <typename F1, typename F2>
|
||||
MOZ_MUST_USE bool initEnvironmentChainHelper(const F1& initFunctionEnv,
|
||||
const F2& initGlobalOrEvalEnv,
|
||||
Register scratch);
|
||||
MOZ_MUST_USE bool initEnvironmentChain();
|
||||
|
||||
MOZ_MUST_USE bool emitTraceLoggerEnter();
|
||||
MOZ_MUST_USE bool emitTraceLoggerExit();
|
||||
|
||||
void emitInitFrameFields();
|
||||
void emitIsDebuggeeCheck();
|
||||
void emitInitializeLocals();
|
||||
void emitPreInitEnvironmentChain(Register nonFunctionEnv);
|
||||
|
|
Загрузка…
Ссылка в новой задаче