Bug 1522837 part 1 - Implement loadScript, emitInitializeLocals, storeFrameSizeAndPushDescriptor for BaselineInterpreterHandler. r=djvj

This also removes computeFullFrameSize because we don't really need it.

Differential Revision: https://phabricator.services.mozilla.com/D17644

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jan de Mooij 2019-02-03 10:06:39 +00:00
parent 60c4067b1c
commit aa34bcb168
3 changed files with 86 additions and 47 deletions

View File

@ -371,6 +371,36 @@ MethodStatus BaselineCompiler::compile() {
return Method_Compiled;
}
template <>
void BaselineCompilerCodeGen::loadScript(Register dest) {
masm.movePtr(ImmGCPtr(handler.script()), dest);
}
template <>
void BaselineInterpreterCodeGen::loadScript(Register dest) {
// TODO(bug 1522394): consider adding interpreterScript to BaselineFrame once
// we are able to run benchmarks.
masm.loadPtr(frame.addressOfCalleeToken(), dest);
Label notFunction, done;
masm.branchTestPtr(Assembler::NonZero, dest, Imm32(CalleeTokenScriptBit),
&notFunction);
{
// CalleeToken_Function or CalleeToken_FunctionConstructing.
masm.andPtr(Imm32(uint32_t(CalleeTokenMask)), dest);
masm.loadPtr(Address(dest, JSFunction::offsetOfScript()), dest);
masm.jump(&done);
}
masm.bind(&notFunction);
{
// CalleeToken_Script.
masm.andPtr(Imm32(uint32_t(CalleeTokenMask)), dest);
}
masm.bind(&done);
}
template <>
void BaselineCompilerCodeGen::emitInitializeLocals() {
// Initialize all locals to |undefined|. Lexical bindings are temporal
@ -413,7 +443,22 @@ void BaselineCompilerCodeGen::emitInitializeLocals() {
template <>
void BaselineInterpreterCodeGen::emitInitializeLocals() {
MOZ_CRASH("NYI: interpreter emitInitializeLocals");
// Push |undefined| for all locals.
Register scratch = R0.scratchReg();
loadScript(scratch);
masm.load32(Address(scratch, JSScript::offsetOfNfixed()), scratch);
Label top, done;
masm.bind(&top);
masm.branchTest32(Assembler::Zero, scratch, scratch, &done);
{
masm.pushValue(UndefinedValue());
masm.sub32(Imm32(1), scratch);
masm.jump(&top);
}
masm.bind(&done);
}
// On input:
@ -507,7 +552,8 @@ void BaselineCodeGen<Handler>::prepareVMCall() {
template <>
void BaselineCompilerCodeGen::storeFrameSizeAndPushDescriptor(
uint32_t frameBaseSize, uint32_t argSize, const Address& frameSizeAddr) {
uint32_t frameBaseSize, uint32_t argSize, const Address& frameSizeAddr,
Register scratch1, Register scratch2) {
uint32_t frameVals = frame.nlocals() + frame.stackDepth();
uint32_t frameFullSize = frameBaseSize + (frameVals * sizeof(Value));
@ -520,22 +566,22 @@ void BaselineCompilerCodeGen::storeFrameSizeAndPushDescriptor(
template <>
void BaselineInterpreterCodeGen::storeFrameSizeAndPushDescriptor(
uint32_t frameBaseSize, uint32_t argSize, const Address& frameSizeAddr) {
MOZ_CRASH("NYI: interpreter storeFrameSizeAndPushDescriptor");
}
uint32_t frameBaseSize, uint32_t argSize, const Address& frameSizeAddr,
Register scratch1, Register scratch2) {
// scratch1 = FramePointer + BaselineFrame::FramePointerOffset - StackPointer.
masm.computeEffectiveAddress(
Address(BaselineFrameReg, BaselineFrame::FramePointerOffset), scratch1);
masm.subStackPtrFrom(scratch1);
template <>
void BaselineCompilerCodeGen::computeFullFrameSize(uint32_t frameBaseSize,
Register dest) {
uint32_t frameVals = frame.nlocals() + frame.stackDepth();
uint32_t frameFullSize = frameBaseSize + (frameVals * sizeof(Value));
masm.move32(Imm32(frameFullSize), dest);
}
// Store the frame size without VMFunction arguments. Use
// computeEffectiveAddress instead of sub32 to avoid an extra move.
masm.computeEffectiveAddress(Address(scratch1, -int32_t(argSize)), scratch2);
masm.store32(scratch2, frameSizeAddr);
template <>
void BaselineInterpreterCodeGen::computeFullFrameSize(uint32_t frameBaseSize,
Register dest) {
MOZ_CRASH("NYI: interpreter computeFullFrameSize");
// Push frame descriptor based on the full frame size.
masm.makeFrameDescriptor(scratch1, FrameType::BaselineJS,
ExitFrameLayout::Size());
masm.push(scratch1);
}
template <typename Handler>
@ -572,29 +618,29 @@ bool BaselineCodeGen<Handler>::callVM(const VMFunction& fun,
uint32_t frameBaseSize =
BaselineFrame::FramePointerOffset + BaselineFrame::Size();
if (phase == POST_INITIALIZE) {
storeFrameSizeAndPushDescriptor(frameBaseSize, argSize, frameSizeAddress);
storeFrameSizeAndPushDescriptor(frameBaseSize, argSize, frameSizeAddress,
R0.scratchReg(), R1.scratchReg());
} else {
MOZ_ASSERT(phase == CHECK_OVER_RECURSED);
Label afterWrite;
Label writePostInitialize;
Label done, pushedFrameLocals;
// If OVER_RECURSED is set, then frame locals haven't been pushed yet.
masm.branchTest32(Assembler::Zero, frame.addressOfFlags(),
Imm32(BaselineFrame::OVER_RECURSED),
&writePostInitialize);
masm.move32(Imm32(frameBaseSize), ICTailCallReg);
masm.jump(&afterWrite);
masm.bind(&writePostInitialize);
computeFullFrameSize(frameBaseSize, ICTailCallReg);
masm.bind(&afterWrite);
masm.store32(ICTailCallReg, frameSizeAddress);
masm.add32(Imm32(argSize), ICTailCallReg);
masm.makeFrameDescriptor(ICTailCallReg, FrameType::BaselineJS,
ExitFrameLayout::Size());
masm.push(ICTailCallReg);
Imm32(BaselineFrame::OVER_RECURSED), &pushedFrameLocals);
{
masm.store32(Imm32(frameBaseSize), frameSizeAddress);
uint32_t descriptor =
MakeFrameDescriptor(frameBaseSize + argSize, FrameType::BaselineJS,
ExitFrameLayout::Size());
masm.push(Imm32(descriptor));
masm.jump(&done);
}
masm.bind(&pushedFrameLocals);
{
storeFrameSizeAndPushDescriptor(frameBaseSize, argSize, frameSizeAddress,
R0.scratchReg(), R1.scratchReg());
}
masm.bind(&done);
}
MOZ_ASSERT(fun.expectTailCall == NonTailCall);
// Perform the call.
@ -682,16 +728,6 @@ void BaselineInterpreterCodeGen::emitIsDebuggeeCheck() {
MOZ_CRASH("NYI: interpreter emitIsDebuggeeCheck");
}
template <>
void BaselineCompilerCodeGen::loadScript(Register dest) {
masm.movePtr(ImmGCPtr(handler.script()), dest);
}
template <>
void BaselineInterpreterCodeGen::loadScript(Register dest) {
MOZ_CRASH("NYI: interpreter loadScript");
}
template <>
void BaselineCompilerCodeGen::subtractScriptSlotsSize(Register reg,
Register scratch) {

View File

@ -341,8 +341,8 @@ class BaselineCodeGen {
void prepareVMCall();
void storeFrameSizeAndPushDescriptor(uint32_t frameBaseSize, uint32_t argSize,
const Address& frameSizeAddr);
void computeFullFrameSize(uint32_t frameBaseSize, Register dest);
const Address& frameSizeAddr,
Register scratch1, Register scratch2);
enum CallVMPhase { POST_INITIALIZE, CHECK_OVER_RECURSED };
bool callVM(const VMFunction& fun, CallVMPhase phase = POST_INITIALIZE);

View File

@ -16,13 +16,16 @@
namespace js {
namespace jit {
struct SafepointSlotEntry;
enum CalleeTokenTag {
CalleeToken_Function = 0x0, // untagged
CalleeToken_FunctionConstructing = 0x1,
CalleeToken_Script = 0x2
};
struct SafepointSlotEntry;
// Any CalleeToken with this bit set must be CalleeToken_Script.
static const uintptr_t CalleeTokenScriptBit = CalleeToken_Script;
static const uintptr_t CalleeTokenMask = ~uintptr_t(0x3);