mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 16:22:00 +00:00
Bug 1561925 - Implement remaining interpreter-specific BaselineCodeGen methods. r=tcampbell
After the recent script data changes we can now read objects/scopes/bigints and resume offsets from JIT code. Differential Revision: https://phabricator.services.mozilla.com/D36201 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
e4638db56f
commit
676b258268
@ -41,6 +41,8 @@
|
||||
using namespace js;
|
||||
using namespace js::jit;
|
||||
|
||||
using JS::TraceKind;
|
||||
|
||||
using mozilla::AssertedCast;
|
||||
using mozilla::Maybe;
|
||||
|
||||
@ -926,33 +928,89 @@ void BaselineInterpreterCodeGen::pushScriptNameArg(Register scratch1,
|
||||
pushArg(scratch2);
|
||||
}
|
||||
|
||||
template <>
|
||||
void BaselineCompilerCodeGen::pushScriptObjectArg(ScriptObjectType type) {
|
||||
JSScript* script = handler.script();
|
||||
static gc::Cell* GetScriptGCThing(JSScript* script, jsbytecode* pc,
|
||||
ScriptGCThingType type) {
|
||||
switch (type) {
|
||||
case ScriptObjectType::RegExp:
|
||||
pushArg(ImmGCPtr(script->getRegExp(handler.pc())));
|
||||
return;
|
||||
case ScriptObjectType::Function:
|
||||
pushArg(ImmGCPtr(script->getFunction(handler.pc())));
|
||||
return;
|
||||
case ScriptGCThingType::RegExp:
|
||||
return script->getRegExp(pc);
|
||||
case ScriptGCThingType::Function:
|
||||
return script->getFunction(pc);
|
||||
case ScriptGCThingType::Scope:
|
||||
return script->getScope(pc);
|
||||
case ScriptGCThingType::BigInt:
|
||||
return script->getBigInt(pc);
|
||||
}
|
||||
MOZ_CRASH("Unexpected object type");
|
||||
MOZ_CRASH("Unexpected GCThing type");
|
||||
}
|
||||
|
||||
template <>
|
||||
void BaselineInterpreterCodeGen::pushScriptObjectArg(ScriptObjectType type) {
|
||||
MOZ_CRASH("NYI: interpreter pushScriptObjectArg");
|
||||
void BaselineCompilerCodeGen::loadScriptGCThing(ScriptGCThingType type,
|
||||
Register dest,
|
||||
Register scratch) {
|
||||
gc::Cell* thing = GetScriptGCThing(handler.script(), handler.pc(), type);
|
||||
masm.movePtr(ImmGCPtr(thing), dest);
|
||||
}
|
||||
|
||||
template <>
|
||||
void BaselineCompilerCodeGen::pushScriptScopeArg() {
|
||||
pushArg(ImmGCPtr(handler.script()->getScope(handler.pc())));
|
||||
void BaselineInterpreterCodeGen::loadScriptGCThing(ScriptGCThingType type,
|
||||
Register dest,
|
||||
Register scratch) {
|
||||
MOZ_ASSERT(dest != scratch);
|
||||
|
||||
// Load the index in |scratch|.
|
||||
masm.loadPtr(frame.addressOfInterpreterPC(), scratch);
|
||||
LoadInt32Operand(masm, scratch, scratch);
|
||||
|
||||
// Load the GCCellPtr.
|
||||
loadScript(dest);
|
||||
masm.loadPtr(Address(dest, JSScript::offsetOfPrivateScriptData()), dest);
|
||||
masm.loadPtr(BaseIndex(dest, scratch, ScalePointer,
|
||||
PrivateScriptData::offsetOfGCThings()),
|
||||
dest);
|
||||
|
||||
// Clear the tag bits.
|
||||
switch (type) {
|
||||
case ScriptGCThingType::RegExp:
|
||||
case ScriptGCThingType::Function:
|
||||
// No-op because GCCellPtr tag bits are zero for objects.
|
||||
static_assert(uintptr_t(TraceKind::Object) == 0,
|
||||
"Unexpected tag bits for object GCCellPtr");
|
||||
break;
|
||||
case ScriptGCThingType::Scope:
|
||||
case ScriptGCThingType::BigInt:
|
||||
// Use xorPtr with a 32-bit immediate because it's more efficient than
|
||||
// andPtr on 64-bit.
|
||||
static_assert(uintptr_t(TraceKind::Scope) >= JS::OutOfLineTraceKindMask,
|
||||
"Expected Scopes to have OutOfLineTraceKindMask tag");
|
||||
static_assert(uintptr_t(TraceKind::BigInt) >= JS::OutOfLineTraceKindMask,
|
||||
"Expected BigInts to have OutOfLineTraceKindMask tag");
|
||||
masm.xorPtr(Imm32(JS::OutOfLineTraceKindMask), dest);
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// Assert low bits are not set.
|
||||
Label ok;
|
||||
masm.branchTestPtr(Assembler::Zero, dest, Imm32(0b111), &ok);
|
||||
masm.assumeUnreachable("GC pointer with tag bits set");
|
||||
masm.bind(&ok);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <>
|
||||
void BaselineInterpreterCodeGen::pushScriptScopeArg() {
|
||||
MOZ_CRASH("NYI: interpreter pushScriptScopeArg");
|
||||
void BaselineCompilerCodeGen::pushScriptGCThingArg(ScriptGCThingType type,
|
||||
Register scratch1,
|
||||
Register scratch2) {
|
||||
gc::Cell* thing = GetScriptGCThing(handler.script(), handler.pc(), type);
|
||||
pushArg(ImmGCPtr(thing));
|
||||
}
|
||||
|
||||
template <>
|
||||
void BaselineInterpreterCodeGen::pushScriptGCThingArg(ScriptGCThingType type,
|
||||
Register scratch1,
|
||||
Register scratch2) {
|
||||
loadScriptGCThing(type, scratch1, scratch2);
|
||||
pushArg(scratch1);
|
||||
}
|
||||
|
||||
template <>
|
||||
@ -1530,7 +1588,10 @@ bool BaselineCompilerCodeGen::emitTraceLoggerEnter() {
|
||||
|
||||
template <>
|
||||
bool BaselineInterpreterCodeGen::emitTraceLoggerEnter() {
|
||||
MOZ_CRASH("NYI: interpreter emitTraceLoggerEnter");
|
||||
if (JS::TraceLoggerSupported()) {
|
||||
MOZ_CRASH("NYI: interpreter emitTraceLoggerEnter");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
@ -2466,7 +2527,12 @@ bool BaselineCompilerCodeGen::emit_JSOP_BIGINT() {
|
||||
|
||||
template <>
|
||||
bool BaselineInterpreterCodeGen::emit_JSOP_BIGINT() {
|
||||
MOZ_CRASH("NYI: interpreter JSOP_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 <>
|
||||
@ -2579,7 +2645,8 @@ bool BaselineInterpreterCodeGen::emit_JSOP_CALLSITEOBJ() {
|
||||
template <typename Handler>
|
||||
bool BaselineCodeGen<Handler>::emit_JSOP_REGEXP() {
|
||||
prepareVMCall();
|
||||
pushScriptObjectArg(ScriptObjectType::RegExp);
|
||||
pushScriptGCThingArg(ScriptGCThingType::RegExp, R0.scratchReg(),
|
||||
R1.scratchReg());
|
||||
|
||||
using Fn = JSObject* (*)(JSContext*, Handle<RegExpObject*>);
|
||||
if (!callVM<Fn, CloneRegExpObject>()) {
|
||||
@ -2598,7 +2665,8 @@ bool BaselineCodeGen<Handler>::emit_JSOP_LAMBDA() {
|
||||
masm.loadPtr(frame.addressOfEnvironmentChain(), R0.scratchReg());
|
||||
|
||||
pushArg(R0.scratchReg());
|
||||
pushScriptObjectArg(ScriptObjectType::Function);
|
||||
pushScriptGCThingArg(ScriptGCThingType::Function, R0.scratchReg(),
|
||||
R1.scratchReg());
|
||||
|
||||
using Fn = JSObject* (*)(JSContext*, HandleFunction, HandleObject);
|
||||
if (!callVM<Fn, js::Lambda>()) {
|
||||
@ -2621,7 +2689,8 @@ bool BaselineCodeGen<Handler>::emit_JSOP_LAMBDA_ARROW() {
|
||||
|
||||
pushArg(R0);
|
||||
pushArg(R2.scratchReg());
|
||||
pushScriptObjectArg(ScriptObjectType::Function);
|
||||
pushScriptGCThingArg(ScriptGCThingType::Function, R0.scratchReg(),
|
||||
R1.scratchReg());
|
||||
|
||||
using Fn =
|
||||
JSObject* (*)(JSContext*, HandleFunction, HandleObject, HandleValue);
|
||||
@ -4738,6 +4807,32 @@ static void LoadBaselineScriptResumeEntries(MacroAssembler& masm,
|
||||
masm.addPtr(scratch, dest);
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
void BaselineCodeGen<Handler>::emitInterpJumpToResumeEntry(Register script,
|
||||
Register resumeIndex,
|
||||
Register scratch) {
|
||||
// Load JSScript::scriptData() into |script|.
|
||||
masm.loadPtr(Address(script, JSScript::offsetOfScriptData()), script);
|
||||
|
||||
// Load the resume pcOffset in |resumeIndex|.
|
||||
masm.load32(Address(script, SharedScriptData::offsetOfResumeOffsetsOffset()),
|
||||
scratch);
|
||||
masm.computeEffectiveAddress(BaseIndex(scratch, resumeIndex, TimesFour),
|
||||
scratch);
|
||||
masm.load32(BaseIndex(script, scratch, TimesOne), resumeIndex);
|
||||
|
||||
// Load pc* in |script|.
|
||||
masm.load32(Address(script, SharedScriptData::offsetOfCodeOffset()), scratch);
|
||||
masm.addPtr(scratch, script);
|
||||
|
||||
// Add resume offset to PC, jump to it.
|
||||
masm.addPtr(resumeIndex, script);
|
||||
Address pcAddr(BaselineFrameReg,
|
||||
BaselineFrame::reverseOffsetOfInterpreterPC());
|
||||
masm.storePtr(script, pcAddr);
|
||||
emitJumpToInterpretOpLabel();
|
||||
}
|
||||
|
||||
template <>
|
||||
void BaselineCompilerCodeGen::jumpToResumeEntry(Register resumeIndex,
|
||||
Register scratch1,
|
||||
@ -4753,7 +4848,8 @@ template <>
|
||||
void BaselineInterpreterCodeGen::jumpToResumeEntry(Register resumeIndex,
|
||||
Register scratch1,
|
||||
Register scratch2) {
|
||||
MOZ_CRASH("NYI: interpreter jumpToResumeEntry");
|
||||
loadScript(scratch1);
|
||||
emitInterpJumpToResumeEntry(scratch1, resumeIndex, scratch2);
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
@ -4837,7 +4933,8 @@ bool BaselineCodeGen<Handler>::emit_JSOP_PUSHLEXICALENV() {
|
||||
prepareVMCall();
|
||||
masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
|
||||
|
||||
pushScriptScopeArg();
|
||||
pushScriptGCThingArg(ScriptGCThingType::Scope, R1.scratchReg(),
|
||||
R2.scratchReg());
|
||||
pushArg(R0.scratchReg());
|
||||
|
||||
using Fn = bool (*)(JSContext*, BaselineFrame*, Handle<LexicalScope*>);
|
||||
@ -4934,7 +5031,8 @@ template <typename Handler>
|
||||
bool BaselineCodeGen<Handler>::emit_JSOP_PUSHVARENV() {
|
||||
prepareVMCall();
|
||||
masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
|
||||
pushScriptScopeArg();
|
||||
pushScriptGCThingArg(ScriptGCThingType::Scope, R1.scratchReg(),
|
||||
R2.scratchReg());
|
||||
pushArg(R0.scratchReg());
|
||||
|
||||
using Fn = bool (*)(JSContext*, BaselineFrame*, HandleScope);
|
||||
@ -4958,10 +5056,11 @@ bool BaselineCodeGen<Handler>::emit_JSOP_ENTERWITH() {
|
||||
|
||||
// Call a stub to push the object onto the environment chain.
|
||||
prepareVMCall();
|
||||
masm.loadBaselineFramePtr(BaselineFrameReg, R1.scratchReg());
|
||||
|
||||
pushScriptScopeArg();
|
||||
pushScriptGCThingArg(ScriptGCThingType::Scope, R1.scratchReg(),
|
||||
R2.scratchReg());
|
||||
pushArg(R0);
|
||||
masm.loadBaselineFramePtr(BaselineFrameReg, R1.scratchReg());
|
||||
pushArg(R1.scratchReg());
|
||||
|
||||
using Fn =
|
||||
@ -5274,15 +5373,22 @@ bool BaselineCodeGen<Handler>::emit_JSOP_TOSTRING() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static constexpr uint32_t TableSwitchOpLowOffset = 1 * JUMP_OFFSET_LEN;
|
||||
static constexpr uint32_t TableSwitchOpHighOffset = 2 * JUMP_OFFSET_LEN;
|
||||
static constexpr uint32_t TableSwitchOpFirstResumeIndexOffset =
|
||||
3 * JUMP_OFFSET_LEN;
|
||||
|
||||
template <>
|
||||
void BaselineCompilerCodeGen::emitGetTableSwitchIndex(ValueOperand val,
|
||||
Register dest) {
|
||||
Register dest,
|
||||
Register scratch1,
|
||||
Register scratch2) {
|
||||
jsbytecode* pc = handler.pc();
|
||||
jsbytecode* defaultpc = pc + GET_JUMP_OFFSET(pc);
|
||||
Label* defaultLabel = handler.labelOf(defaultpc);
|
||||
|
||||
int32_t low = GET_JUMP_OFFSET(pc + 1 * JUMP_OFFSET_LEN);
|
||||
int32_t high = GET_JUMP_OFFSET(pc + 2 * JUMP_OFFSET_LEN);
|
||||
int32_t low = GET_JUMP_OFFSET(pc + TableSwitchOpLowOffset);
|
||||
int32_t high = GET_JUMP_OFFSET(pc + TableSwitchOpHighOffset);
|
||||
int32_t length = high - low + 1;
|
||||
|
||||
// Jump to the 'default' pc if not int32 (tableswitch is only used when
|
||||
@ -5299,8 +5405,35 @@ void BaselineCompilerCodeGen::emitGetTableSwitchIndex(ValueOperand val,
|
||||
|
||||
template <>
|
||||
void BaselineInterpreterCodeGen::emitGetTableSwitchIndex(ValueOperand val,
|
||||
Register dest) {
|
||||
MOZ_CRASH("NYI: interpreter emitTableSwitchJumpTableIndex");
|
||||
Register dest,
|
||||
Register scratch1,
|
||||
Register scratch2) {
|
||||
// Jump to the 'default' pc if not int32 (tableswitch is only used when
|
||||
// all cases are int32).
|
||||
Label done, jumpToDefault;
|
||||
masm.branchTestInt32(Assembler::NotEqual, val, &jumpToDefault);
|
||||
masm.unboxInt32(val, dest);
|
||||
|
||||
masm.loadPtr(frame.addressOfInterpreterPC(), scratch1);
|
||||
|
||||
Address lowAddr(scratch1, sizeof(jsbytecode) + TableSwitchOpLowOffset);
|
||||
Address highAddr(scratch1, sizeof(jsbytecode) + TableSwitchOpHighOffset);
|
||||
|
||||
// Jump to default if val > high.
|
||||
masm.branch32(Assembler::LessThan, highAddr, dest, &jumpToDefault);
|
||||
|
||||
// Jump to default if val < low.
|
||||
masm.load32(lowAddr, scratch2);
|
||||
masm.branch32(Assembler::GreaterThan, scratch2, dest, &jumpToDefault);
|
||||
|
||||
// index := val - low.
|
||||
masm.sub32(scratch2, dest);
|
||||
masm.jump(&done);
|
||||
|
||||
masm.bind(&jumpToDefault);
|
||||
emitJump();
|
||||
|
||||
masm.bind(&done);
|
||||
}
|
||||
|
||||
template <>
|
||||
@ -5312,7 +5445,7 @@ void BaselineCompilerCodeGen::emitTableSwitchJump(Register key,
|
||||
// Note: BytecodeEmitter::allocateResumeIndex static_asserts
|
||||
// |firstResumeIndex * sizeof(uintptr_t)| fits in int32_t.
|
||||
uint32_t firstResumeIndex =
|
||||
GET_RESUMEINDEX(handler.pc() + 3 * JUMP_OFFSET_LEN);
|
||||
GET_RESUMEINDEX(handler.pc() + TableSwitchOpFirstResumeIndexOffset);
|
||||
LoadBaselineScriptResumeEntries(masm, handler.script(), scratch1, scratch2);
|
||||
masm.loadPtr(BaseIndex(scratch1, key, ScaleFromElemWidth(sizeof(uintptr_t)),
|
||||
firstResumeIndex * sizeof(uintptr_t)),
|
||||
@ -5324,7 +5457,13 @@ template <>
|
||||
void BaselineInterpreterCodeGen::emitTableSwitchJump(Register key,
|
||||
Register scratch1,
|
||||
Register scratch2) {
|
||||
MOZ_CRASH("NYI: interpreter emitTableSwitchJump");
|
||||
// Load the op's firstResumeIndex in scratch1.
|
||||
masm.loadPtr(frame.addressOfInterpreterPC(), scratch1);
|
||||
LoadUint24Operand(masm, scratch1, TableSwitchOpFirstResumeIndexOffset,
|
||||
scratch1);
|
||||
|
||||
masm.add32(key, scratch1);
|
||||
jumpToResumeEntry(scratch1, key, scratch2);
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
@ -5341,7 +5480,7 @@ bool BaselineCodeGen<Handler>::emit_JSOP_TABLESWITCH() {
|
||||
|
||||
// Load the index in the jump table in |key|, or branch to default pc if not
|
||||
// int32 or out-of-range.
|
||||
emitGetTableSwitchIndex(R0, key);
|
||||
emitGetTableSwitchIndex(R0, key, scratch1, scratch2);
|
||||
|
||||
// Jump to the target pc.
|
||||
emitTableSwitchJump(key, scratch1, scratch2);
|
||||
@ -5872,7 +6011,17 @@ bool BaselineCodeGen<Handler>::emitEnterGeneratorCode(Register script,
|
||||
emitEnterBaseline();
|
||||
|
||||
masm.bind(&noBaselineScript);
|
||||
MOZ_CRASH("NYI: enter interpreted generator");
|
||||
|
||||
// Initialize interpreter frame fields.
|
||||
Address flagsAddr(BaselineFrameReg, BaselineFrame::reverseOffsetOfFlags());
|
||||
Address scriptAddr(BaselineFrameReg,
|
||||
BaselineFrame::reverseOffsetOfInterpreterScript());
|
||||
masm.or32(Imm32(BaselineFrame::RUNNING_IN_INTERPRETER), flagsAddr);
|
||||
masm.storePtr(script, scriptAddr);
|
||||
|
||||
// Initialize pc and jump to it.
|
||||
emitInterpJumpToResumeEntry(script, resumeIndex, scratch);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
@ -6369,7 +6518,8 @@ bool BaselineCodeGen<Handler>::emit_JSOP_FUNWITHPROTO() {
|
||||
prepareVMCall();
|
||||
pushArg(R0.scratchReg());
|
||||
pushArg(R1.scratchReg());
|
||||
pushScriptObjectArg(ScriptObjectType::Function);
|
||||
pushScriptGCThingArg(ScriptGCThingType::Function, R0.scratchReg(),
|
||||
R1.scratchReg());
|
||||
|
||||
using Fn =
|
||||
JSObject* (*)(JSContext*, HandleFunction, HandleObject, HandleObject);
|
||||
|
@ -256,6 +256,8 @@ namespace jit {
|
||||
_(JSOP_INC) \
|
||||
_(JSOP_DEC)
|
||||
|
||||
enum class ScriptGCThingType { RegExp, Function, Scope, BigInt };
|
||||
|
||||
// Base class for BaselineCompiler and BaselineInterpreterGenerator. The Handler
|
||||
// template is a class storing fields/methods that are interpreter or compiler
|
||||
// specific. This can be combined with template specialization of methods in
|
||||
@ -318,10 +320,11 @@ class BaselineCodeGen {
|
||||
|
||||
// Pushes a name/object/scope associated with the current bytecode op (and
|
||||
// stored in the script) as argument for a VM function.
|
||||
enum class ScriptObjectType { RegExp, Function };
|
||||
void pushScriptObjectArg(ScriptObjectType type);
|
||||
void loadScriptGCThing(ScriptGCThingType type, Register dest,
|
||||
Register scratch);
|
||||
void pushScriptGCThingArg(ScriptGCThingType type, Register scratch1,
|
||||
Register scratch2);
|
||||
void pushScriptNameArg(Register scratch1, Register scratch2);
|
||||
void pushScriptScopeArg();
|
||||
|
||||
// Pushes a bytecode operand as argument for a VM function.
|
||||
void pushUint8BytecodeOperandArg(Register scratch);
|
||||
@ -407,6 +410,8 @@ class BaselineCodeGen {
|
||||
MOZ_MUST_USE bool emitEnterGeneratorCode(Register script,
|
||||
Register resumeIndex,
|
||||
Register scratch);
|
||||
void emitInterpJumpToResumeEntry(Register script, Register resumeIndex,
|
||||
Register scratch);
|
||||
void emitJumpToInterpretOpLabel();
|
||||
|
||||
MOZ_MUST_USE bool emitIncExecutionProgressCounter(Register scratch);
|
||||
@ -444,7 +449,8 @@ class BaselineCodeGen {
|
||||
|
||||
// Converts |val| to an index in the jump table and stores this in |dest|
|
||||
// or branches to the default pc if not int32 or out-of-range.
|
||||
void emitGetTableSwitchIndex(ValueOperand val, Register dest);
|
||||
void emitGetTableSwitchIndex(ValueOperand val, Register dest,
|
||||
Register scratch1, Register scratch2);
|
||||
|
||||
// Jumps to the target of a table switch based on |key| and the
|
||||
// firstResumeIndex stored in JSOP_TABLESWITCH.
|
||||
|
@ -1474,9 +1474,13 @@ class alignas(uintptr_t) PrivateScriptData final {
|
||||
explicit PrivateScriptData(uint32_t ngcthings);
|
||||
|
||||
public:
|
||||
static constexpr size_t offsetOfGCThings() {
|
||||
return sizeof(PrivateScriptData);
|
||||
}
|
||||
|
||||
// Accessors for typed array spans.
|
||||
mozilla::Span<JS::GCCellPtr> gcthings() {
|
||||
size_t offset = sizeof(PrivateScriptData);
|
||||
size_t offset = offsetOfGCThings();
|
||||
return mozilla::MakeSpan(offsetToPointer<JS::GCCellPtr>(offset), ngcthings);
|
||||
}
|
||||
|
||||
@ -1778,6 +1782,11 @@ class alignas(uintptr_t) SharedScriptData final {
|
||||
static constexpr size_t offsetOfCodeOffset() {
|
||||
return offsetof(SharedScriptData, codeOffset_);
|
||||
}
|
||||
static constexpr size_t offsetOfResumeOffsetsOffset() {
|
||||
// Resume-offsets are the first optional array if they exist. Locate the
|
||||
// array with the 'optArrayOffset_' field.
|
||||
return offsetof(SharedScriptData, optArrayOffset_);
|
||||
}
|
||||
static constexpr size_t offsetOfNfixed() {
|
||||
return offsetof(SharedScriptData, nfixed);
|
||||
}
|
||||
@ -2552,6 +2561,9 @@ class JSScript : public js::gc::TenuredCell {
|
||||
static constexpr size_t offsetOfScriptData() {
|
||||
return offsetof(JSScript, scriptData_);
|
||||
}
|
||||
static constexpr size_t offsetOfPrivateScriptData() {
|
||||
return offsetof(JSScript, data_);
|
||||
}
|
||||
static constexpr size_t offsetOfJitScript() {
|
||||
return offsetof(JSScript, jitScript_);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user