Bug 1827914 - Merge some Baseline compiler and interpreter functions r=iain
When the bytecode will be shared (for now, just in the self-hosted case), it is the same as the BaselineInterpreter bytecode, so we reduce code duplication. One consequence is that scriptInternal() becomes less useful. If I keep it, I need to add an implementation for BaselineInterpreterHandler which would be identical to maybeScript(). Having three potential methods to get the script is confusing, and we already have a pattern of using maybeScript() when implementing combined compiler and interpreter methods. Differential Revision: https://phabricator.services.mozilla.com/D245768
This commit is contained in:
committed by
bthrall@mozilla.com
parent
f679ddb00d
commit
b0860647c2
@@ -494,27 +494,22 @@ static void LoadInlineValueOperand(MacroAssembler& masm, ValueOperand dest) {
|
||||
masm.loadUnalignedValue(Address(pc, sizeof(jsbytecode)), dest);
|
||||
}
|
||||
|
||||
template <>
|
||||
void BaselineCompilerCodeGen::loadScript(Register dest) {
|
||||
if (handler.isSelfHosted()) {
|
||||
template <typename Handler>
|
||||
void BaselineCodeGen<Handler>::loadScript(Register dest) {
|
||||
if (handler.realmIndependentJitcode()) {
|
||||
masm.loadPtr(frame.addressOfInterpreterScript(), dest);
|
||||
} else {
|
||||
masm.movePtr(ImmGCPtr(handler.scriptInternal()), dest);
|
||||
masm.movePtr(ImmGCPtr(handler.maybeScript()), dest);
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
void BaselineInterpreterCodeGen::loadScript(Register dest) {
|
||||
masm.loadPtr(frame.addressOfInterpreterScript(), dest);
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
void BaselineCodeGen<Handler>::loadJitScript(Register dest) {
|
||||
if (handler.isSelfHosted()) {
|
||||
if (handler.realmIndependentJitcode()) {
|
||||
loadScript(dest);
|
||||
masm.loadPtr(Address(dest, JSScript::offsetOfWarmUpData()), dest);
|
||||
} else {
|
||||
masm.movePtr(ImmPtr(handler.scriptInternal()->jitScript()), dest);
|
||||
masm.movePtr(ImmPtr(handler.maybeScript()->jitScript()), dest);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1022,39 +1017,30 @@ void BaselineInterpreterCodeGen::subtractScriptSlotsSize(Register reg,
|
||||
masm.subPtr(scratch, reg);
|
||||
}
|
||||
|
||||
template <>
|
||||
void BaselineCompilerCodeGen::loadGlobalLexicalEnvironment(Register dest) {
|
||||
MOZ_ASSERT(!handler.script()->hasNonSyntacticScope());
|
||||
masm.movePtr(ImmGCPtr(handler.globalLexicalEnvironment()), dest);
|
||||
template <typename Handler>
|
||||
void BaselineCodeGen<Handler>::loadGlobalLexicalEnvironment(Register dest) {
|
||||
if (handler.realmIndependentJitcode()) {
|
||||
masm.loadGlobalObjectData(dest);
|
||||
masm.loadPtr(Address(dest, GlobalObjectData::offsetOfLexicalEnvironment()),
|
||||
dest);
|
||||
} else {
|
||||
MOZ_ASSERT(!handler.maybeScript()->hasNonSyntacticScope());
|
||||
masm.movePtr(ImmGCPtr(handler.maybeGlobalLexicalEnvironment()), dest);
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
void BaselineInterpreterCodeGen::loadGlobalLexicalEnvironment(Register dest) {
|
||||
masm.loadGlobalObjectData(dest);
|
||||
masm.loadPtr(Address(dest, GlobalObjectData::offsetOfLexicalEnvironment()),
|
||||
dest);
|
||||
}
|
||||
|
||||
template <>
|
||||
void BaselineCompilerCodeGen::pushGlobalLexicalEnvironmentValue(
|
||||
template <typename Handler>
|
||||
void BaselineCodeGen<Handler>::pushGlobalLexicalEnvironmentValue(
|
||||
ValueOperand scratch) {
|
||||
if (handler.isSelfHosted()) {
|
||||
if (handler.realmIndependentJitcode()) {
|
||||
loadGlobalLexicalEnvironment(scratch.scratchReg());
|
||||
masm.tagValue(JSVAL_TYPE_OBJECT, scratch.scratchReg(), scratch);
|
||||
frame.push(scratch);
|
||||
} else {
|
||||
frame.push(ObjectValue(*handler.globalLexicalEnvironment()));
|
||||
frame.push(ObjectValue(*handler.maybeGlobalLexicalEnvironment()));
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
void BaselineInterpreterCodeGen::pushGlobalLexicalEnvironmentValue(
|
||||
ValueOperand scratch) {
|
||||
loadGlobalLexicalEnvironment(scratch.scratchReg());
|
||||
masm.tagValue(JSVAL_TYPE_OBJECT, scratch.scratchReg(), scratch);
|
||||
frame.push(scratch);
|
||||
}
|
||||
|
||||
template <>
|
||||
void BaselineCompilerCodeGen::loadGlobalThisValue(ValueOperand dest) {
|
||||
JSObject* thisObj = handler.globalThis();
|
||||
@@ -1070,20 +1056,15 @@ void BaselineInterpreterCodeGen::loadGlobalThisValue(ValueOperand dest) {
|
||||
masm.loadValue(Address(scratch, SlotOffset), dest);
|
||||
}
|
||||
|
||||
template <>
|
||||
void BaselineCompilerCodeGen::pushScriptArg() {
|
||||
if (handler.isSelfHosted()) {
|
||||
template <typename Handler>
|
||||
void BaselineCodeGen<Handler>::pushScriptArg() {
|
||||
if (handler.realmIndependentJitcode()) {
|
||||
pushArg(frame.addressOfInterpreterScript());
|
||||
} else {
|
||||
pushArg(ImmGCPtr(handler.scriptInternal()));
|
||||
pushArg(ImmGCPtr(handler.maybeScript()));
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
void BaselineInterpreterCodeGen::pushScriptArg() {
|
||||
pushArg(frame.addressOfInterpreterScript());
|
||||
}
|
||||
|
||||
template <>
|
||||
void BaselineCompilerCodeGen::pushBytecodePCArg() {
|
||||
pushArg(ImmPtr(handler.pc()));
|
||||
@@ -1168,12 +1149,11 @@ template <>
|
||||
void BaselineCompilerCodeGen::loadScriptGCThing(ScriptGCThingType type,
|
||||
Register dest,
|
||||
Register scratch) {
|
||||
if (handler.isSelfHosted()) {
|
||||
if (handler.realmIndependentJitcode()) {
|
||||
masm.move32(Imm32(GET_GCTHING_INDEX(handler.pc())), scratch);
|
||||
loadScriptGCThingInternal(type, dest, scratch);
|
||||
} else {
|
||||
gc::Cell* thing =
|
||||
GetScriptGCThing(handler.scriptInternal(), handler.pc(), type);
|
||||
gc::Cell* thing = GetScriptGCThing(handler.script(), handler.pc(), type);
|
||||
masm.movePtr(ImmGCPtr(thing), dest);
|
||||
}
|
||||
}
|
||||
@@ -1198,28 +1178,20 @@ void BaselineInterpreterCodeGen::loadScriptGCThing(ScriptGCThingType type,
|
||||
#endif
|
||||
}
|
||||
|
||||
template <>
|
||||
void BaselineCompilerCodeGen::pushScriptGCThingArg(ScriptGCThingType type,
|
||||
Register scratch1,
|
||||
Register scratch2) {
|
||||
if (handler.isSelfHosted()) {
|
||||
template <typename Handler>
|
||||
void BaselineCodeGen<Handler>::pushScriptGCThingArg(ScriptGCThingType type,
|
||||
Register scratch1,
|
||||
Register scratch2) {
|
||||
if (handler.realmIndependentJitcode()) {
|
||||
loadScriptGCThing(type, scratch1, scratch2);
|
||||
pushArg(scratch1);
|
||||
} else {
|
||||
gc::Cell* thing =
|
||||
GetScriptGCThing(handler.scriptInternal(), handler.pc(), type);
|
||||
GetScriptGCThing(handler.maybeScript(), handler.maybePC(), type);
|
||||
pushArg(ImmGCPtr(thing));
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
void BaselineInterpreterCodeGen::pushScriptGCThingArg(ScriptGCThingType type,
|
||||
Register scratch1,
|
||||
Register scratch2) {
|
||||
loadScriptGCThing(type, scratch1, scratch2);
|
||||
pushArg(scratch1);
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
void BaselineCodeGen<Handler>::pushScriptNameArg(Register scratch1,
|
||||
Register scratch2) {
|
||||
@@ -1292,7 +1264,8 @@ void BaselineCompilerCodeGen::emitInitFrameFields(Register nonFunctionEnv) {
|
||||
Register scratch2 = R2.scratchReg();
|
||||
MOZ_ASSERT(nonFunctionEnv != scratch && nonFunctionEnv != scratch2);
|
||||
|
||||
uint32_t flags = handler.isSelfHosted() ? BaselineFrame::SELF_HOSTED : 0;
|
||||
uint32_t flags =
|
||||
handler.realmIndependentJitcode() ? BaselineFrame::REALM_INDEPENDENT : 0;
|
||||
masm.store32(Imm32(flags), frame.addressOfFlags());
|
||||
|
||||
if (handler.function()) {
|
||||
@@ -1300,13 +1273,13 @@ void BaselineCompilerCodeGen::emitInitFrameFields(Register nonFunctionEnv) {
|
||||
masm.unboxObject(Address(scratch, JSFunction::offsetOfEnvironment()),
|
||||
scratch2);
|
||||
masm.storePtr(scratch2, frame.addressOfEnvironmentChain());
|
||||
if (handler.isSelfHosted()) {
|
||||
if (handler.realmIndependentJitcode()) {
|
||||
masm.loadPrivate(Address(scratch, JSFunction::offsetOfJitInfoOrScript()),
|
||||
scratch);
|
||||
masm.storePtr(scratch, frame.addressOfInterpreterScript());
|
||||
}
|
||||
} else {
|
||||
if (handler.isSelfHosted()) {
|
||||
if (handler.realmIndependentJitcode()) {
|
||||
masm.loadPtr(frame.addressOfCalleeToken(), scratch);
|
||||
masm.andPtr(Imm32(uint32_t(CalleeTokenMask)), scratch);
|
||||
masm.storePtr(scratch, frame.addressOfInterpreterScript());
|
||||
@@ -1328,8 +1301,8 @@ void BaselineCompilerCodeGen::emitInitFrameFields(Register nonFunctionEnv) {
|
||||
|
||||
// Otherwise, store this script's default ICSCript in the frame.
|
||||
masm.bind(¬Inlined);
|
||||
if (handler.isSelfHosted()) {
|
||||
// When self-hosted JitCode is reused in a new realm, the frames baked into
|
||||
if (handler.realmIndependentJitcode()) {
|
||||
// When JitCode is reused in a new realm, the frames baked into
|
||||
// the native bytecode need to refer to the IC list for the new JitScript or
|
||||
// they will execute the IC scripts using the IC stub fields from the wrong
|
||||
// script.
|
||||
@@ -1337,7 +1310,7 @@ void BaselineCompilerCodeGen::emitInitFrameFields(Register nonFunctionEnv) {
|
||||
masm.addPtr(Imm32(JitScript::offsetOfICScript()), scratch);
|
||||
masm.storePtr(scratch, frame.addressOfICScript());
|
||||
} else {
|
||||
masm.storePtr(ImmPtr(handler.scriptInternal()->jitScript()->icScript()),
|
||||
masm.storePtr(ImmPtr(handler.script()->jitScript()->icScript()),
|
||||
frame.addressOfICScript());
|
||||
}
|
||||
masm.bind(&done);
|
||||
@@ -1430,7 +1403,7 @@ bool BaselineCompilerCodeGen::initEnvironmentChain() {
|
||||
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
Register temp = regs.takeAny();
|
||||
Label done;
|
||||
if (!handler.isSelfHosted()) {
|
||||
if (!handler.realmIndependentJitcode()) {
|
||||
// Allocate a NamedLambdaObject and/or a CallObject. If the function needs
|
||||
// both, the NamedLambdaObject must enclose the CallObject. If one of the
|
||||
// allocations fails, we perform the whole operation in C++.
|
||||
@@ -2728,9 +2701,9 @@ bool BaselineInterpreterCodeGen::emit_Double() {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool BaselineCompilerCodeGen::emit_BigInt() {
|
||||
if (handler.isSelfHosted()) {
|
||||
template <typename Handler>
|
||||
bool BaselineCodeGen<Handler>::emit_BigInt() {
|
||||
if (handler.realmIndependentJitcode()) {
|
||||
frame.syncStack(0);
|
||||
Register scratch1 = R0.scratchReg();
|
||||
Register scratch2 = R1.scratchReg();
|
||||
@@ -2738,25 +2711,15 @@ bool BaselineCompilerCodeGen::emit_BigInt() {
|
||||
masm.tagValue(JSVAL_TYPE_BIGINT, scratch1, R0);
|
||||
frame.push(R0);
|
||||
} else {
|
||||
BigInt* bi = handler.scriptInternal()->getBigInt(handler.pc());
|
||||
BigInt* bi = handler.maybeScript()->getBigInt(handler.maybePC());
|
||||
frame.push(BigIntValue(bi));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool BaselineInterpreterCodeGen::emit_BigInt() {
|
||||
Register scratch1 = R0.scratchReg();
|
||||
Register scratch2 = R1.scratchReg();
|
||||
loadScriptGCThing(ScriptGCThingType::BigInt, scratch1, scratch2);
|
||||
masm.tagValue(JSVAL_TYPE_BIGINT, scratch1, R0);
|
||||
frame.push(R0);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool BaselineCompilerCodeGen::emit_String() {
|
||||
if (handler.isSelfHosted()) {
|
||||
template <typename Handler>
|
||||
bool BaselineCodeGen<Handler>::emit_String() {
|
||||
if (handler.realmIndependentJitcode()) {
|
||||
frame.syncStack(0);
|
||||
Register scratch1 = R0.scratchReg();
|
||||
Register scratch2 = R1.scratchReg();
|
||||
@@ -2764,21 +2727,12 @@ bool BaselineCompilerCodeGen::emit_String() {
|
||||
masm.tagValue(JSVAL_TYPE_STRING, scratch1, R0);
|
||||
frame.push(R0);
|
||||
} else {
|
||||
frame.push(StringValue(handler.scriptInternal()->getString(handler.pc())));
|
||||
frame.push(
|
||||
StringValue(handler.maybeScript()->getString(handler.maybePC())));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool BaselineInterpreterCodeGen::emit_String() {
|
||||
Register scratch1 = R0.scratchReg();
|
||||
Register scratch2 = R1.scratchReg();
|
||||
loadScriptGCThing(ScriptGCThingType::String, scratch1, scratch2);
|
||||
masm.tagValue(JSVAL_TYPE_STRING, scratch1, R0);
|
||||
frame.push(R0);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool BaselineCompilerCodeGen::emit_Symbol() {
|
||||
unsigned which = GET_UINT8(handler.pc());
|
||||
@@ -2801,30 +2755,21 @@ bool BaselineInterpreterCodeGen::emit_Symbol() {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool BaselineCompilerCodeGen::emit_Object() {
|
||||
if (handler.isSelfHosted()) {
|
||||
template <typename Handler>
|
||||
bool BaselineCodeGen<Handler>::emit_Object() {
|
||||
if (handler.realmIndependentJitcode()) {
|
||||
Register scratch1 = R0.scratchReg();
|
||||
Register scratch2 = R1.scratchReg();
|
||||
loadScriptGCThing(ScriptGCThingType::Object, scratch1, scratch2);
|
||||
masm.tagValue(JSVAL_TYPE_OBJECT, scratch1, R0);
|
||||
frame.push(R0);
|
||||
} else {
|
||||
frame.push(ObjectValue(*handler.scriptInternal()->getObject(handler.pc())));
|
||||
frame.push(
|
||||
ObjectValue(*handler.maybeScript()->getObject(handler.maybePC())));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool BaselineInterpreterCodeGen::emit_Object() {
|
||||
Register scratch1 = R0.scratchReg();
|
||||
Register scratch2 = R1.scratchReg();
|
||||
loadScriptGCThing(ScriptGCThingType::Object, scratch1, scratch2);
|
||||
masm.tagValue(JSVAL_TYPE_OBJECT, scratch1, R0);
|
||||
frame.push(R0);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
bool BaselineCodeGen<Handler>::emit_CallSiteObj() {
|
||||
return emit_Object();
|
||||
@@ -3702,10 +3647,10 @@ bool BaselineCodeGen<Handler>::emit_GetGName() {
|
||||
|
||||
template <>
|
||||
bool BaselineCompilerCodeGen::tryOptimizeBindUnqualifiedGlobalName() {
|
||||
if (handler.isSelfHosted()) {
|
||||
if (handler.realmIndependentJitcode()) {
|
||||
return false;
|
||||
}
|
||||
JSScript* script = handler.scriptInternal();
|
||||
JSScript* script = handler.script();
|
||||
MOZ_ASSERT(!script->hasNonSyntacticScope());
|
||||
|
||||
if (handler.compilingOffThread()) {
|
||||
@@ -6361,8 +6306,8 @@ bool BaselineCodeGen<Handler>::emitEnterGeneratorCode(Register script,
|
||||
masm.storePtr(scratch, icScriptAddr);
|
||||
|
||||
Label noBaselineScript;
|
||||
// Self-hosted frames need the interpreterScript pointer
|
||||
if (handler.isSelfHosted()) {
|
||||
// Frames with shared bytecode need the interpreterScript pointer
|
||||
if (handler.realmIndependentJitcode()) {
|
||||
masm.storePtr(script, frame.addressOfInterpreterScript());
|
||||
}
|
||||
masm.loadJitScript(script, scratch);
|
||||
@@ -6628,7 +6573,7 @@ bool BaselineCodeGen<Handler>::emit_Resume() {
|
||||
|
||||
// After the generator returns, we restore the stack pointer, switch back to
|
||||
// the current realm, push the return value, and we're done.
|
||||
if (handler.maybeScript() && !handler.isSelfHosted()) {
|
||||
if (!handler.realmIndependentJitcode()) {
|
||||
masm.switchToRealm(handler.maybeScript()->realm(), R2.scratchReg());
|
||||
} else {
|
||||
masm.switchToBaselineFrameRealm(R2.scratchReg());
|
||||
@@ -6943,7 +6888,7 @@ bool BaselineCodeGen<Handler>::emitPrologue() {
|
||||
|
||||
frame.assertSyncedStack();
|
||||
|
||||
if (handler.maybeScript() && !handler.isSelfHosted()) {
|
||||
if (!handler.realmIndependentJitcode()) {
|
||||
masm.debugAssertContextRealm(handler.maybeScript()->realm(),
|
||||
R1.scratchReg());
|
||||
}
|
||||
|
||||
@@ -345,11 +345,6 @@ class BaselineCompilerHandler {
|
||||
}
|
||||
|
||||
JSScript* script() const { return script_; }
|
||||
// Use for any time the script or script data will be baked into the bytecode
|
||||
JSScript* scriptInternal() const {
|
||||
MOZ_ASSERT(!isSelfHosted());
|
||||
return script_;
|
||||
}
|
||||
JSScript* maybeScript() const { return script_; }
|
||||
|
||||
JSFunction* function() const { return script_->function(); }
|
||||
@@ -384,7 +379,7 @@ class BaselineCompilerHandler {
|
||||
|
||||
bool canHaveFixedSlots() const { return script()->nfixed() != 0; }
|
||||
|
||||
JSObject* globalLexicalEnvironment() const {
|
||||
JSObject* maybeGlobalLexicalEnvironment() const {
|
||||
return globalLexicalEnvironment_;
|
||||
}
|
||||
JSObject* globalThis() const { return globalThis_; }
|
||||
@@ -406,7 +401,7 @@ class BaselineCompilerHandler {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isSelfHosted() const {
|
||||
bool realmIndependentJitcode() const {
|
||||
return JS::Prefs::experimental_self_hosted_cache() &&
|
||||
script()->selfHosted();
|
||||
}
|
||||
@@ -538,10 +533,11 @@ class BaselineInterpreterHandler {
|
||||
bool mustIncludeSlotsInStackCheck() const { return true; }
|
||||
|
||||
bool canHaveFixedSlots() const { return true; }
|
||||
JSObject* maybeGlobalLexicalEnvironment() const { return nullptr; }
|
||||
|
||||
bool addEnvAllocSite() { return false; } // Not supported.
|
||||
|
||||
bool isSelfHosted() const { return false; }
|
||||
bool realmIndependentJitcode() const { return true; }
|
||||
};
|
||||
|
||||
using BaselineInterpreterCodeGen = BaselineCodeGen<BaselineInterpreterHandler>;
|
||||
|
||||
@@ -52,7 +52,7 @@ void BaselineFrame::trace(JSTracer* trc, const JSJitFrameIter& frameIterator) {
|
||||
TraceRoot(trc, &argsObj_, "baseline-args-obj");
|
||||
}
|
||||
|
||||
if (runningInInterpreter() || isSelfHosted()) {
|
||||
if (runningInInterpreter() || isRealmIndependent()) {
|
||||
TraceRoot(trc, &interpreterScript_, "baseline-interpreterScript");
|
||||
}
|
||||
|
||||
|
||||
@@ -54,12 +54,15 @@ class BaselineFrame {
|
||||
// See comment above 'isDebuggee' in vm/Realm.h for explanation
|
||||
// of invariants of debuggee compartments, scripts, and frames.
|
||||
DEBUGGEE = 1 << 6,
|
||||
SELF_HOSTED = 1 << 7,
|
||||
|
||||
// Frame is executing Realm-independent Jitcode, which requires
|
||||
// a valid interpreterScript_ field.
|
||||
REALM_INDEPENDENT = 1 << 7,
|
||||
};
|
||||
|
||||
protected: // Silence Clang warning about unused private fields.
|
||||
// The fields below are only valid if RUNNING_IN_INTERPRETER or
|
||||
// isSelfHosted().
|
||||
// isRealmIndependent().
|
||||
JSScript* interpreterScript_;
|
||||
// The fields below are only valid if RUNNING_IN_INTERPRETER.
|
||||
jsbytecode* interpreterPC_;
|
||||
@@ -243,7 +246,7 @@ class BaselineFrame {
|
||||
}
|
||||
|
||||
bool runningInInterpreter() const { return flags_ & RUNNING_IN_INTERPRETER; }
|
||||
bool isSelfHosted() const { return flags_ & SELF_HOSTED; }
|
||||
bool isRealmIndependent() const { return flags_ & REALM_INDEPENDENT; }
|
||||
|
||||
JSScript* interpreterScript() const {
|
||||
MOZ_ASSERT(runningInInterpreter());
|
||||
|
||||
Reference in New Issue
Block a user