зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1334212 - Handle multiple contexts per runtime in compiled JIT code, r=h4writer.
--HG-- extra : rebase_source : 49c6a9d3b6b65dc221c2d23da332937fe9a5c175
This commit is contained in:
Родитель
72b92832e8
Коммит
ea0cbd818d
|
@ -268,7 +268,7 @@ Zone::discardJitCode(FreeOp* fop, bool discardBaselineCode)
|
|||
* Defer freeing any allocated blocks until after the next minor GC.
|
||||
*/
|
||||
if (discardBaselineCode) {
|
||||
jitZone()->optimizedStubSpace()->freeAllAfterMinorGC(fop->runtime());
|
||||
jitZone()->optimizedStubSpace()->freeAllAfterMinorGC(this);
|
||||
jitZone()->purgeIonCacheIRStubInfo();
|
||||
}
|
||||
|
||||
|
|
|
@ -157,8 +157,10 @@ NativeRegExpMacroAssembler::GenerateCode(JSContext* cx, bool match_only)
|
|||
// avoid failing repeatedly when the regex code is called from Ion JIT code,
|
||||
// see bug 1208819.
|
||||
Label stack_ok;
|
||||
void* stack_limit = &cx->runtime()->contextFromMainThread()->jitStackLimitNoInterrupt;
|
||||
masm.branchStackPtrRhs(Assembler::Below, AbsoluteAddress(stack_limit), &stack_ok);
|
||||
void* context_addr = &cx->zone()->group()->context;
|
||||
masm.loadPtr(AbsoluteAddress(context_addr), temp0);
|
||||
Address limit_addr(temp0, offsetof(JSContext, jitStackLimitNoInterrupt));
|
||||
masm.branchStackPtrRhs(Assembler::Below, limit_addr, &stack_ok);
|
||||
|
||||
// Exit with an exception. There is not enough space on the stack
|
||||
// for our working registers.
|
||||
|
@ -272,8 +274,9 @@ NativeRegExpMacroAssembler::GenerateCode(JSContext* cx, bool match_only)
|
|||
}
|
||||
|
||||
// Initialize backtrack stack pointer.
|
||||
masm.loadPtr(AbsoluteAddress(cx->runtime()->contextFromMainThread()->regexpStack.ref().addressOfBase()),
|
||||
backtrack_stack_pointer);
|
||||
size_t baseOffset = offsetof(JSContext, regexpStack) + RegExpStack::offsetOfBase();
|
||||
masm.loadPtr(AbsoluteAddress(context_addr), backtrack_stack_pointer);
|
||||
masm.loadPtr(Address(backtrack_stack_pointer, baseOffset), backtrack_stack_pointer);
|
||||
masm.storePtr(backtrack_stack_pointer,
|
||||
Address(masm.getStackPointer(), offsetof(FrameData, backtrackStackBase)));
|
||||
|
||||
|
@ -463,7 +466,10 @@ NativeRegExpMacroAssembler::GenerateCode(JSContext* cx, bool match_only)
|
|||
Address backtrackStackBaseAddress(temp2, offsetof(FrameData, backtrackStackBase));
|
||||
masm.subPtr(backtrackStackBaseAddress, backtrack_stack_pointer);
|
||||
|
||||
masm.loadPtr(AbsoluteAddress(cx->runtime()->contextFromMainThread()->regexpStack.ref().addressOfBase()), temp1);
|
||||
void* context_addr = &cx->zone()->group()->context;
|
||||
size_t baseOffset = offsetof(JSContext, regexpStack) + RegExpStack::offsetOfBase();
|
||||
masm.loadPtr(AbsoluteAddress(context_addr), temp1);
|
||||
masm.loadPtr(Address(temp1, baseOffset), temp1);
|
||||
masm.storePtr(temp1, backtrackStackBaseAddress);
|
||||
masm.addPtr(temp1, backtrack_stack_pointer);
|
||||
|
||||
|
@ -542,8 +548,9 @@ NativeRegExpMacroAssembler::Backtrack()
|
|||
|
||||
// Check for an interrupt.
|
||||
Label noInterrupt;
|
||||
masm.branch32(Assembler::Equal,
|
||||
AbsoluteAddress(&cx->runtime()->contextFromMainThread()->interrupt_), Imm32(0),
|
||||
void* contextAddr = &cx->zone()->group()->context;
|
||||
masm.loadPtr(AbsoluteAddress(contextAddr), temp0);
|
||||
masm.branch32(Assembler::Equal, Address(temp0, offsetof(JSContext, interrupt_)), Imm32(0),
|
||||
&noInterrupt);
|
||||
masm.movePtr(ImmWord(RegExpRunStatus_Error), temp0);
|
||||
masm.jump(&exit_label_);
|
||||
|
@ -1101,10 +1108,11 @@ NativeRegExpMacroAssembler::CheckBacktrackStackLimit()
|
|||
{
|
||||
JitSpew(SPEW_PREFIX "CheckBacktrackStackLimit");
|
||||
|
||||
const void* limitAddr = cx->runtime()->contextFromMainThread()->regexpStack.ref().addressOfLimit();
|
||||
|
||||
Label no_stack_overflow;
|
||||
masm.branchPtr(Assembler::AboveOrEqual, AbsoluteAddress(limitAddr),
|
||||
void* context_addr = &cx->zone()->group()->context;
|
||||
size_t limitOffset = offsetof(JSContext, regexpStack) + RegExpStack::offsetOfLimit();
|
||||
masm.loadPtr(AbsoluteAddress(context_addr), temp1);
|
||||
masm.branchPtr(Assembler::AboveOrEqual, Address(temp1, limitOffset),
|
||||
backtrack_stack_pointer, &no_stack_overflow);
|
||||
|
||||
// Copy the stack pointer before the call() instruction modifies it.
|
||||
|
|
|
@ -79,8 +79,8 @@ class RegExpStack
|
|||
bool grow();
|
||||
|
||||
// Address of allocated memory.
|
||||
const void* addressOfBase() { return &base_; }
|
||||
const void* addressOfLimit() { return &limit_; }
|
||||
static size_t offsetOfBase() { return offsetof(RegExpStack, base_); }
|
||||
static size_t offsetOfLimit() { return offsetof(RegExpStack, limit_); }
|
||||
|
||||
void* base() { return base_; }
|
||||
void* limit() { return limit_; }
|
||||
|
|
|
@ -525,7 +525,6 @@ bool
|
|||
BaselineCompiler::emitStackCheck(bool earlyCheck)
|
||||
{
|
||||
Label skipCall;
|
||||
void* limitAddr = &cx->runtime()->contextFromMainThread()->jitStackLimit;
|
||||
uint32_t slotsSize = script->nslots() * sizeof(Value);
|
||||
uint32_t tolerance = earlyCheck ? slotsSize : 0;
|
||||
|
||||
|
@ -551,7 +550,10 @@ BaselineCompiler::emitStackCheck(bool earlyCheck)
|
|||
&forceCall);
|
||||
}
|
||||
|
||||
masm.branchPtr(Assembler::BelowOrEqual, AbsoluteAddress(limitAddr), R1.scratchReg(),
|
||||
void* contextAddr = &cx->zone()->group()->context;
|
||||
masm.loadPtr(AbsoluteAddress(contextAddr), R0.scratchReg());
|
||||
masm.branchPtr(Assembler::BelowOrEqual,
|
||||
Address(R0.scratchReg(), offsetof(JSContext, jitStackLimit)), R1.scratchReg(),
|
||||
&skipCall);
|
||||
|
||||
if (!earlyCheck && needsEarlyStackCheck())
|
||||
|
@ -697,8 +699,11 @@ BaselineCompiler::emitInterruptCheck()
|
|||
frame.syncStack(0);
|
||||
|
||||
Label done;
|
||||
void* interrupt = &cx->runtime()->contextFromMainThread()->interrupt_;
|
||||
masm.branch32(Assembler::Equal, AbsoluteAddress(interrupt), Imm32(0), &done);
|
||||
void* context = &cx->zone()->group()->context;
|
||||
masm.loadPtr(AbsoluteAddress(context), R0.scratchReg());
|
||||
masm.branch32(Assembler::Equal,
|
||||
Address(R0.scratchReg(), offsetof(JSContext, interrupt_)), Imm32(0),
|
||||
&done);
|
||||
|
||||
prepareVMCall();
|
||||
if (!callVM(InterruptCheckInfo))
|
||||
|
|
|
@ -4126,7 +4126,7 @@ ICCall_Native::Compiler::generateStubCode(MacroAssembler& masm)
|
|||
EmitBaselineCreateStubFrameDescriptor(masm, scratch, ExitFrameLayout::Size());
|
||||
masm.push(scratch);
|
||||
masm.push(ICTailCallReg);
|
||||
masm.enterFakeExitFrameForNative(isConstructing_);
|
||||
masm.enterFakeExitFrameForNative(scratch, isConstructing_);
|
||||
|
||||
// Execute call.
|
||||
masm.setupUnalignedABICall(scratch);
|
||||
|
@ -4218,7 +4218,7 @@ ICCall_ClassHook::Compiler::generateStubCode(MacroAssembler& masm)
|
|||
EmitBaselineCreateStubFrameDescriptor(masm, scratch, ExitFrameLayout::Size());
|
||||
masm.push(scratch);
|
||||
masm.push(ICTailCallReg);
|
||||
masm.enterFakeExitFrameForNative(isConstructing_);
|
||||
masm.enterFakeExitFrameForNative(scratch, isConstructing_);
|
||||
|
||||
// Execute call.
|
||||
masm.setupUnalignedABICall(scratch);
|
||||
|
|
|
@ -49,9 +49,12 @@ PCMappingSlotInfo::ToSlotLocation(const StackValue* stackVal)
|
|||
}
|
||||
|
||||
void
|
||||
ICStubSpace::freeAllAfterMinorGC(JSRuntime* rt)
|
||||
ICStubSpace::freeAllAfterMinorGC(Zone* zone)
|
||||
{
|
||||
rt->zoneGroupFromMainThread()->freeAllLifoBlocksAfterMinorGC(&allocator_);
|
||||
if (zone->isAtomsZone())
|
||||
MOZ_ASSERT(allocator_.isEmpty());
|
||||
else
|
||||
zone->group()->freeAllLifoBlocksAfterMinorGC(&allocator_);
|
||||
}
|
||||
|
||||
BaselineScript::BaselineScript(uint32_t prologueOffset, uint32_t epilogueOffset,
|
||||
|
@ -517,7 +520,7 @@ BaselineScript::Destroy(FreeOp* fop, BaselineScript* script)
|
|||
*
|
||||
* Defer freeing any allocated blocks until after the next minor GC.
|
||||
*/
|
||||
script->fallbackStubSpace_.freeAllAfterMinorGC(fop->runtime());
|
||||
script->fallbackStubSpace_.freeAllAfterMinorGC(script->method()->zone());
|
||||
|
||||
fop->delete_(script);
|
||||
}
|
||||
|
|
|
@ -3856,7 +3856,7 @@ CodeGenerator::visitCallNative(LCallNative* call)
|
|||
|
||||
// Construct native exit frame.
|
||||
uint32_t safepointOffset = masm.buildFakeExitFrame(tempReg);
|
||||
masm.enterFakeExitFrameForNative(call->mir()->isConstructing());
|
||||
masm.enterFakeExitFrameForNative(tempReg, call->mir()->isConstructing());
|
||||
|
||||
markSafepointAt(safepointOffset, call);
|
||||
|
||||
|
@ -3978,7 +3978,7 @@ CodeGenerator::visitCallDOMNative(LCallDOMNative* call)
|
|||
|
||||
// Construct native exit frame.
|
||||
uint32_t safepointOffset = masm.buildFakeExitFrame(argJSContext);
|
||||
masm.enterFakeExitFrame(IonDOMMethodExitFrameLayoutToken);
|
||||
masm.enterFakeExitFrame(argJSContext, IonDOMMethodExitFrameLayoutToken);
|
||||
|
||||
markSafepointAt(safepointOffset, call);
|
||||
|
||||
|
@ -4772,16 +4772,20 @@ CodeGenerator::visitCheckOverRecursed(LCheckOverRecursed* lir)
|
|||
// It must always be possible to trespass past the stack limit.
|
||||
// Ion may legally place frames very close to the limit. Calling additional
|
||||
// C functions may then violate the limit without any checking.
|
||||
|
||||
//
|
||||
// Since Ion frames exist on the C stack, the stack limit may be
|
||||
// dynamically set by JS_SetThreadStackLimit() and JS_SetNativeStackQuota().
|
||||
const void* limitAddr = GetJitContext()->runtime->addressOfJitStackLimit();
|
||||
|
||||
CheckOverRecursedFailure* ool = new(alloc()) CheckOverRecursedFailure(lir);
|
||||
addOutOfLineCode(ool, lir->mir());
|
||||
|
||||
Register temp = ToRegister(lir->temp());
|
||||
|
||||
// Conditional forward (unlikely) branch to failure.
|
||||
masm.branchStackPtrRhs(Assembler::AboveOrEqual, AbsoluteAddress(limitAddr), ool->entry());
|
||||
const void* contextAddr = GetJitContext()->compartment->zone()->addressOfJSContext();
|
||||
masm.loadPtr(AbsoluteAddress(contextAddr), temp);
|
||||
masm.branchStackPtrRhs(Assembler::AboveOrEqual,
|
||||
Address(temp, offsetof(JSContext, jitStackLimit)), ool->entry());
|
||||
masm.bind(ool->rejoin());
|
||||
}
|
||||
|
||||
|
@ -5160,7 +5164,7 @@ CodeGenerator::emitDebugForceBailing(LInstruction* lir)
|
|||
return;
|
||||
|
||||
masm.comment("emitDebugForceBailing");
|
||||
const void* bailAfterAddr = GetJitContext()->runtime->addressOfIonBailAfter();
|
||||
const void* bailAfterAddr = GetJitContext()->compartment->zone()->addressOfIonBailAfter();
|
||||
|
||||
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
|
||||
|
@ -7810,11 +7814,10 @@ JitRuntime::generateLazyLinkStub(JSContext* cx)
|
|||
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::Volatile());
|
||||
Register temp0 = regs.takeAny();
|
||||
|
||||
masm.enterFakeExitFrame(LazyLinkExitFrameLayoutToken);
|
||||
masm.enterFakeExitFrame(temp0, LazyLinkExitFrameLayoutToken);
|
||||
masm.PushStubCode();
|
||||
|
||||
masm.setupUnalignedABICall(temp0);
|
||||
masm.loadJSContext(temp0);
|
||||
masm.passABIArg(temp0);
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, LazyLinkTopActivation));
|
||||
|
||||
|
@ -11349,7 +11352,7 @@ CodeGenerator::visitGetDOMProperty(LGetDOMProperty* ins)
|
|||
masm.moveStackPtrTo(ObjectReg);
|
||||
|
||||
uint32_t safepointOffset = masm.buildFakeExitFrame(JSContextReg);
|
||||
masm.enterFakeExitFrame(IonDOMExitFrameLayoutGetterToken);
|
||||
masm.enterFakeExitFrame(JSContextReg, IonDOMExitFrameLayoutGetterToken);
|
||||
|
||||
markSafepointAt(safepointOffset, ins);
|
||||
|
||||
|
@ -11438,7 +11441,7 @@ CodeGenerator::visitSetDOMProperty(LSetDOMProperty* ins)
|
|||
masm.moveStackPtrTo(ObjectReg);
|
||||
|
||||
uint32_t safepointOffset = masm.buildFakeExitFrame(JSContextReg);
|
||||
masm.enterFakeExitFrame(IonDOMExitFrameLayoutSetterToken);
|
||||
masm.enterFakeExitFrame(JSContextReg, IonDOMExitFrameLayoutSetterToken);
|
||||
|
||||
markSafepointAt(safepointOffset, ins);
|
||||
|
||||
|
@ -11891,8 +11894,12 @@ CodeGenerator::visitInterruptCheck(LInterruptCheck* lir)
|
|||
|
||||
OutOfLineCode* ool = oolCallVM(InterruptCheckInfo, lir, ArgList(), StoreNothing());
|
||||
|
||||
AbsoluteAddress interruptAddr(GetJitContext()->runtime->addressOfInterruptUint32());
|
||||
masm.branch32(Assembler::NotEqual, interruptAddr, Imm32(0), ool->entry());
|
||||
Register temp = ToRegister(lir->temp());
|
||||
|
||||
const void* contextAddr = GetJitContext()->compartment->zone()->addressOfJSContext();
|
||||
masm.loadPtr(AbsoluteAddress(contextAddr), temp);
|
||||
masm.branch32(Assembler::NotEqual, Address(temp, offsetof(JSContext, interrupt_)),
|
||||
Imm32(0), ool->entry());
|
||||
masm.bind(ool->rejoin());
|
||||
}
|
||||
|
||||
|
|
|
@ -23,50 +23,6 @@ CompileRuntime::get(JSRuntime* rt)
|
|||
return reinterpret_cast<CompileRuntime*>(rt);
|
||||
}
|
||||
|
||||
bool
|
||||
CompileRuntime::onMainThread()
|
||||
{
|
||||
return js::CurrentThreadCanAccessRuntime(runtime());
|
||||
}
|
||||
|
||||
const void*
|
||||
CompileRuntime::addressOfJitTop()
|
||||
{
|
||||
return &runtime()->unsafeContextFromAnyThread()->jitTop;
|
||||
}
|
||||
|
||||
const void*
|
||||
CompileRuntime::addressOfJitActivation()
|
||||
{
|
||||
return &runtime()->unsafeContextFromAnyThread()->jitActivation;
|
||||
}
|
||||
|
||||
const void*
|
||||
CompileRuntime::addressOfProfilingActivation()
|
||||
{
|
||||
return (const void*) &runtime()->unsafeContextFromAnyThread()->profilingActivation_;
|
||||
}
|
||||
|
||||
const void*
|
||||
CompileRuntime::addressOfJitStackLimit()
|
||||
{
|
||||
return &runtime()->unsafeContextFromAnyThread()->jitStackLimit;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
const void*
|
||||
CompileRuntime::addressOfIonBailAfter()
|
||||
{
|
||||
return runtime()->zoneGroupFromAnyThread()->addressOfIonBailAfter();
|
||||
}
|
||||
#endif
|
||||
|
||||
const void*
|
||||
CompileRuntime::addressOfActivation()
|
||||
{
|
||||
return &runtime()->unsafeContextFromAnyThread()->activation_;
|
||||
}
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
const void*
|
||||
CompileRuntime::addressOfGCZealModeBits()
|
||||
|
@ -75,18 +31,6 @@ CompileRuntime::addressOfGCZealModeBits()
|
|||
}
|
||||
#endif
|
||||
|
||||
const void*
|
||||
CompileRuntime::addressOfInterruptUint32()
|
||||
{
|
||||
return &runtime()->unsafeContextFromAnyThread()->interrupt_;
|
||||
}
|
||||
|
||||
const void*
|
||||
CompileRuntime::getJSContext()
|
||||
{
|
||||
return runtime()->unsafeContextFromAnyThread();
|
||||
}
|
||||
|
||||
const JitRuntime*
|
||||
CompileRuntime::jitRuntime()
|
||||
{
|
||||
|
@ -111,12 +55,6 @@ CompileRuntime::hadOutOfMemory()
|
|||
return runtime()->hadOutOfMemory;
|
||||
}
|
||||
|
||||
bool
|
||||
CompileRuntime::profilingScripts()
|
||||
{
|
||||
return runtime()->zoneGroupFromAnyThread()->profilingScripts;
|
||||
}
|
||||
|
||||
const JSAtomState&
|
||||
CompileRuntime::names()
|
||||
{
|
||||
|
@ -150,10 +88,15 @@ CompileRuntime::positiveInfinityValue()
|
|||
const WellKnownSymbols&
|
||||
CompileRuntime::wellKnownSymbols()
|
||||
{
|
||||
MOZ_ASSERT(onMainThread());
|
||||
return *runtime()->wellKnownSymbols;
|
||||
}
|
||||
|
||||
const void*
|
||||
CompileRuntime::addressOfActiveJSContext()
|
||||
{
|
||||
return &runtime()->activeContext;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
bool
|
||||
CompileRuntime::isInsideNursery(gc::Cell* cell)
|
||||
|
@ -168,19 +111,6 @@ CompileRuntime::DOMcallbacks()
|
|||
return runtime()->DOMcallbacks;
|
||||
}
|
||||
|
||||
const Nursery&
|
||||
CompileRuntime::gcNursery()
|
||||
{
|
||||
return runtime()->zoneGroupFromAnyThread()->nursery();
|
||||
}
|
||||
|
||||
void
|
||||
CompileRuntime::setMinorGCShouldCancelIonCompilations()
|
||||
{
|
||||
MOZ_ASSERT(onMainThread());
|
||||
runtime()->zoneGroupFromAnyThread()->storeBuffer().setShouldCancelIonCompilations();
|
||||
}
|
||||
|
||||
bool
|
||||
CompileRuntime::runtimeMatches(JSRuntime* rt)
|
||||
{
|
||||
|
@ -199,6 +129,32 @@ CompileZone::get(Zone* zone)
|
|||
return reinterpret_cast<CompileZone*>(zone);
|
||||
}
|
||||
|
||||
CompileRuntime*
|
||||
CompileZone::runtime()
|
||||
{
|
||||
return CompileRuntime::get(zone()->runtimeFromAnyThread());
|
||||
}
|
||||
|
||||
bool
|
||||
CompileZone::isAtomsZone()
|
||||
{
|
||||
return zone()->isAtomsZone();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
const void*
|
||||
CompileZone::addressOfIonBailAfter()
|
||||
{
|
||||
return zone()->group()->addressOfIonBailAfter();
|
||||
}
|
||||
#endif
|
||||
|
||||
const void*
|
||||
CompileZone::addressOfJSContext()
|
||||
{
|
||||
return &zone()->group()->context;
|
||||
}
|
||||
|
||||
const void*
|
||||
CompileZone::addressOfNeedsIncrementalBarrier()
|
||||
{
|
||||
|
@ -211,6 +167,38 @@ CompileZone::addressOfFreeList(gc::AllocKind allocKind)
|
|||
return zone()->arenas.addressOfFreeList(allocKind);
|
||||
}
|
||||
|
||||
const void*
|
||||
CompileZone::addressOfNurseryPosition()
|
||||
{
|
||||
return zone()->group()->addressOfNurseryPosition();
|
||||
}
|
||||
|
||||
const void*
|
||||
CompileZone::addressOfNurseryCurrentEnd()
|
||||
{
|
||||
return zone()->group()->addressOfNurseryCurrentEnd();
|
||||
}
|
||||
|
||||
bool
|
||||
CompileZone::nurseryExists()
|
||||
{
|
||||
MOZ_ASSERT(CurrentThreadCanAccessZone(zone()));
|
||||
return zone()->group()->nursery().exists();
|
||||
}
|
||||
|
||||
void
|
||||
CompileZone::setMinorGCShouldCancelIonCompilations()
|
||||
{
|
||||
MOZ_ASSERT(CurrentThreadCanAccessZone(zone()));
|
||||
zone()->group()->storeBuffer().setShouldCancelIonCompilations();
|
||||
}
|
||||
|
||||
bool
|
||||
CompileZone::profilingScripts()
|
||||
{
|
||||
return zone()->group()->profilingScripts;
|
||||
}
|
||||
|
||||
JSCompartment*
|
||||
CompileCompartment::compartment()
|
||||
{
|
||||
|
|
|
@ -27,38 +27,10 @@ class CompileRuntime
|
|||
public:
|
||||
static CompileRuntime* get(JSRuntime* rt);
|
||||
|
||||
bool onMainThread();
|
||||
|
||||
// &runtime()->jitTop
|
||||
const void* addressOfJitTop();
|
||||
|
||||
// &runtime()->jitActivation
|
||||
const void* addressOfJitActivation();
|
||||
|
||||
// &runtime()->profilingActivation
|
||||
const void* addressOfProfilingActivation();
|
||||
|
||||
// rt->runtime()->jitStackLimit;
|
||||
const void* addressOfJitStackLimit();
|
||||
|
||||
#ifdef DEBUG
|
||||
// rt->runtime()->addressOfIonBailAfter;
|
||||
const void* addressOfIonBailAfter();
|
||||
#endif
|
||||
|
||||
// &runtime()->activation_
|
||||
const void* addressOfActivation();
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
const void* addressOfGCZealModeBits();
|
||||
#endif
|
||||
|
||||
const void* addressOfInterruptUint32();
|
||||
|
||||
// We have to bake JSContext* into JIT code, but this pointer shouldn't be
|
||||
// used/dereferenced on the background thread so we return it as void*.
|
||||
const void* getJSContext();
|
||||
|
||||
const JitRuntime* jitRuntime();
|
||||
|
||||
// Compilation does not occur off thread when the Gecko Profiler is enabled.
|
||||
|
@ -66,7 +38,6 @@ class CompileRuntime
|
|||
|
||||
bool jitSupportsFloatingPoint();
|
||||
bool hadOutOfMemory();
|
||||
bool profilingScripts();
|
||||
|
||||
const JSAtomState& names();
|
||||
const PropertyName* emptyString();
|
||||
|
@ -74,6 +45,7 @@ class CompileRuntime
|
|||
const Value& NaNValue();
|
||||
const Value& positiveInfinityValue();
|
||||
const WellKnownSymbols& wellKnownSymbols();
|
||||
const void* addressOfActiveJSContext();
|
||||
|
||||
#ifdef DEBUG
|
||||
bool isInsideNursery(gc::Cell* cell);
|
||||
|
@ -82,9 +54,6 @@ class CompileRuntime
|
|||
// DOM callbacks must be threadsafe (and will hopefully be removed soon).
|
||||
const DOMCallbacks* DOMcallbacks();
|
||||
|
||||
const Nursery& gcNursery();
|
||||
void setMinorGCShouldCancelIonCompilations();
|
||||
|
||||
bool runtimeMatches(JSRuntime* rt);
|
||||
};
|
||||
|
||||
|
@ -95,9 +64,23 @@ class CompileZone
|
|||
public:
|
||||
static CompileZone* get(Zone* zone);
|
||||
|
||||
const void* addressOfNeedsIncrementalBarrier();
|
||||
CompileRuntime* runtime();
|
||||
bool isAtomsZone();
|
||||
|
||||
#ifdef DEBUG
|
||||
const void* addressOfIonBailAfter();
|
||||
#endif
|
||||
|
||||
const void* addressOfJSContext();
|
||||
const void* addressOfNeedsIncrementalBarrier();
|
||||
const void* addressOfFreeList(gc::AllocKind allocKind);
|
||||
const void* addressOfNurseryPosition();
|
||||
const void* addressOfNurseryCurrentEnd();
|
||||
|
||||
bool nurseryExists();
|
||||
void setMinorGCShouldCancelIonCompilations();
|
||||
|
||||
bool profilingScripts();
|
||||
};
|
||||
|
||||
class JitCompartment;
|
||||
|
|
|
@ -35,7 +35,7 @@ class ICStubSpace
|
|||
|
||||
JS_DECLARE_NEW_METHODS(allocate, alloc, inline)
|
||||
|
||||
void freeAllAfterMinorGC(JSRuntime* rt);
|
||||
void freeAllAfterMinorGC(JS::Zone* zone);
|
||||
|
||||
#ifdef DEBUG
|
||||
bool isEmpty() const {
|
||||
|
|
|
@ -575,9 +575,10 @@ jit::LinkIonScript(JSContext* cx, HandleScript calleeScript)
|
|||
}
|
||||
|
||||
uint8_t*
|
||||
jit::LazyLinkTopActivation(JSContext* cx)
|
||||
jit::LazyLinkTopActivation()
|
||||
{
|
||||
// First frame should be an exit frame.
|
||||
JSContext* cx = TlsContext.get();
|
||||
JitFrameIterator it(cx);
|
||||
LazyLinkExitFrameLayout* ll = it.exitFrame()->as<LazyLinkExitFrameLayout>();
|
||||
RootedScript calleeScript(cx, ScriptFromCalleeToken(ll->jsFrame()->calleeToken()));
|
||||
|
@ -636,13 +637,6 @@ JitRuntime::SweepJitcodeGlobalTable(JSRuntime* rt)
|
|||
rt->jitRuntime()->getJitcodeGlobalTable()->sweep(rt);
|
||||
}
|
||||
|
||||
void
|
||||
JitCompartment::trace(JSTracer* trc, JSCompartment* compartment)
|
||||
{
|
||||
// Free temporary OSR buffer.
|
||||
trc->runtime()->contextFromMainThread()->freeOsrTempData();
|
||||
}
|
||||
|
||||
void
|
||||
JitCompartment::sweep(FreeOp* fop, JSCompartment* compartment)
|
||||
{
|
||||
|
@ -1260,7 +1254,7 @@ IonScript::Destroy(FreeOp* fop, IonScript* script)
|
|||
*
|
||||
* Defer freeing any allocated blocks until after the next minor GC.
|
||||
*/
|
||||
script->fallbackStubSpace_.freeAllAfterMinorGC(fop->runtime());
|
||||
script->fallbackStubSpace_.freeAllAfterMinorGC(script->method()->zone());
|
||||
|
||||
fop->delete_(script);
|
||||
}
|
||||
|
|
|
@ -87,11 +87,8 @@ class JitContext
|
|||
CompileRuntime* runtime;
|
||||
CompileCompartment* compartment;
|
||||
|
||||
bool onMainThread() const {
|
||||
return runtime && runtime->onMainThread();
|
||||
}
|
||||
bool hasProfilingScripts() const {
|
||||
return runtime && !!runtime->profilingScripts();
|
||||
return compartment && compartment->zone()->profilingScripts();
|
||||
}
|
||||
|
||||
int getNextAssemblerId() {
|
||||
|
@ -178,7 +175,7 @@ void FinishOffThreadBuilder(JSRuntime* runtime, IonBuilder* builder,
|
|||
const AutoLockHelperThreadState& lock);
|
||||
|
||||
void LinkIonScript(JSContext* cx, HandleScript calleescript);
|
||||
uint8_t* LazyLinkTopActivation(JSContext* cx);
|
||||
uint8_t* LazyLinkTopActivation();
|
||||
|
||||
static inline bool
|
||||
IsIonEnabled(JSContext* cx)
|
||||
|
|
|
@ -7129,7 +7129,7 @@ IonBuilder::loadStaticSlot(JSObject* staticObject, BarrierKind barrier, Temporar
|
|||
bool
|
||||
jit::NeedsPostBarrier(MDefinition* value)
|
||||
{
|
||||
if (!GetJitContext()->runtime->gcNursery().exists())
|
||||
if (!GetJitContext()->compartment->zone()->nurseryExists())
|
||||
return false;
|
||||
return value->mightBeType(MIRType::Object);
|
||||
}
|
||||
|
@ -13080,7 +13080,7 @@ IonBuilder::checkNurseryObject(JSObject* obj)
|
|||
// GC. All constants used during compilation should either go through this
|
||||
// function or should come from a type set (which has a similar barrier).
|
||||
if (obj && IsInsideNursery(obj)) {
|
||||
compartment->runtime()->setMinorGCShouldCancelIonCompilations();
|
||||
compartment->zone()->setMinorGCShouldCancelIonCompilations();
|
||||
IonBuilder* builder = this;
|
||||
while (builder) {
|
||||
builder->setNotSafeForMinorGC();
|
||||
|
|
|
@ -683,7 +683,7 @@ IonCacheIRCompiler::emitCallNativeGetterResult()
|
|||
|
||||
if (!masm.icBuildOOLFakeExitFrame(GetReturnAddressToIonCode(cx_), save))
|
||||
return false;
|
||||
masm.enterFakeExitFrame(IonOOLNativeExitFrameLayoutToken);
|
||||
masm.enterFakeExitFrame(scratch, IonOOLNativeExitFrameLayoutToken);
|
||||
|
||||
// Construct and execute call.
|
||||
masm.setupUnalignedABICall(scratch);
|
||||
|
@ -740,7 +740,7 @@ IonCacheIRCompiler::emitCallProxyGetResult()
|
|||
|
||||
if (!masm.icBuildOOLFakeExitFrame(GetReturnAddressToIonCode(cx_), save))
|
||||
return false;
|
||||
masm.enterFakeExitFrame(IonOOLProxyExitFrameLayoutToken);
|
||||
masm.enterFakeExitFrame(scratch, IonOOLProxyExitFrameLayoutToken);
|
||||
|
||||
// Make the call.
|
||||
masm.setupUnalignedABICall(scratch);
|
||||
|
|
|
@ -903,7 +903,7 @@ EmitGetterCall(JSContext* cx, MacroAssembler& masm,
|
|||
|
||||
if (!masm.icBuildOOLFakeExitFrame(returnAddr, aic))
|
||||
return false;
|
||||
masm.enterFakeExitFrame(IonOOLNativeExitFrameLayoutToken);
|
||||
masm.enterFakeExitFrame(scratchReg, IonOOLNativeExitFrameLayoutToken);
|
||||
|
||||
// Construct and execute call.
|
||||
masm.setupUnalignedABICall(scratchReg);
|
||||
|
@ -961,7 +961,7 @@ EmitGetterCall(JSContext* cx, MacroAssembler& masm,
|
|||
|
||||
if (!masm.icBuildOOLFakeExitFrame(returnAddr, aic))
|
||||
return false;
|
||||
masm.enterFakeExitFrame(IonOOLPropertyOpExitFrameLayoutToken);
|
||||
masm.enterFakeExitFrame(scratchReg, IonOOLPropertyOpExitFrameLayoutToken);
|
||||
|
||||
// Make the call.
|
||||
masm.setupUnalignedABICall(scratchReg);
|
||||
|
@ -1497,7 +1497,7 @@ EmitCallProxySet(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& at
|
|||
|
||||
if (!masm.icBuildOOLFakeExitFrame(returnAddr, aic))
|
||||
return false;
|
||||
masm.enterFakeExitFrame(IonOOLProxyExitFrameLayoutToken);
|
||||
masm.enterFakeExitFrame(scratch, IonOOLProxyExitFrameLayoutToken);
|
||||
|
||||
// Make the call.
|
||||
masm.setupUnalignedABICall(scratch);
|
||||
|
@ -1671,7 +1671,7 @@ GenerateCallSetter(JSContext* cx, IonScript* ion, MacroAssembler& masm,
|
|||
|
||||
if (!masm.icBuildOOLFakeExitFrame(returnAddr, aic))
|
||||
return false;
|
||||
masm.enterFakeExitFrame(IonOOLNativeExitFrameLayoutToken);
|
||||
masm.enterFakeExitFrame(tempReg, IonOOLNativeExitFrameLayoutToken);
|
||||
|
||||
// Make the call
|
||||
masm.setupUnalignedABICall(tempReg);
|
||||
|
@ -1735,7 +1735,7 @@ GenerateCallSetter(JSContext* cx, IonScript* ion, MacroAssembler& masm,
|
|||
|
||||
if (!masm.icBuildOOLFakeExitFrame(returnAddr, aic))
|
||||
return false;
|
||||
masm.enterFakeExitFrame(IonOOLSetterOpExitFrameLayoutToken);
|
||||
masm.enterFakeExitFrame(tempReg, IonOOLSetterOpExitFrameLayoutToken);
|
||||
|
||||
// Make the call.
|
||||
masm.setupUnalignedABICall(tempReg);
|
||||
|
|
|
@ -574,7 +574,6 @@ class JitCompartment
|
|||
// Initialize code stubs only used by Ion, not Baseline.
|
||||
MOZ_MUST_USE bool ensureIonStubsExist(JSContext* cx);
|
||||
|
||||
void trace(JSTracer* trc, JSCompartment* compartment);
|
||||
void sweep(FreeOp* fop, JSCompartment* compartment);
|
||||
|
||||
JitCode* stringConcatStubNoBarrier() const {
|
||||
|
|
|
@ -183,7 +183,7 @@ LIRGenerator::visitTableSwitch(MTableSwitch* tableswitch)
|
|||
void
|
||||
LIRGenerator::visitCheckOverRecursed(MCheckOverRecursed* ins)
|
||||
{
|
||||
LCheckOverRecursed* lir = new(alloc()) LCheckOverRecursed();
|
||||
LCheckOverRecursed* lir = new(alloc()) LCheckOverRecursed(temp());
|
||||
add(lir, ins);
|
||||
assignSafepoint(lir, ins);
|
||||
}
|
||||
|
@ -2564,7 +2564,7 @@ LIRGenerator::visitFunctionEnvironment(MFunctionEnvironment* ins)
|
|||
void
|
||||
LIRGenerator::visitInterruptCheck(MInterruptCheck* ins)
|
||||
{
|
||||
LInstruction* lir = new(alloc()) LInterruptCheck();
|
||||
LInstruction* lir = new(alloc()) LInterruptCheck(temp());
|
||||
add(lir, ins);
|
||||
assignSafepoint(lir, ins);
|
||||
}
|
||||
|
|
|
@ -281,9 +281,9 @@ MacroAssembler::PushStubCode()
|
|||
}
|
||||
|
||||
void
|
||||
MacroAssembler::enterExitFrame(const VMFunction* f)
|
||||
MacroAssembler::enterExitFrame(Register temp, const VMFunction* f)
|
||||
{
|
||||
linkExitFrame();
|
||||
linkExitFrame(temp);
|
||||
// Push the JitCode pointer. (Keep the code alive, when on the stack)
|
||||
PushStubCode();
|
||||
// Push VMFunction pointer, to mark arguments.
|
||||
|
@ -291,18 +291,18 @@ MacroAssembler::enterExitFrame(const VMFunction* f)
|
|||
}
|
||||
|
||||
void
|
||||
MacroAssembler::enterFakeExitFrame(enum ExitFrameTokenValues token)
|
||||
MacroAssembler::enterFakeExitFrame(Register temp, enum ExitFrameTokenValues token)
|
||||
{
|
||||
linkExitFrame();
|
||||
linkExitFrame(temp);
|
||||
Push(Imm32(token));
|
||||
Push(ImmPtr(nullptr));
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::enterFakeExitFrameForNative(bool isConstructing)
|
||||
MacroAssembler::enterFakeExitFrameForNative(Register temp, bool isConstructing)
|
||||
{
|
||||
enterFakeExitFrame(isConstructing ? ConstructNativeExitFrameLayoutToken
|
||||
: CallNativeExitFrameLayoutToken);
|
||||
enterFakeExitFrame(temp, isConstructing ? ConstructNativeExitFrameLayoutToken
|
||||
: CallNativeExitFrameLayoutToken);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -785,14 +785,14 @@ MacroAssembler::nurseryAllocate(Register result, Register temp, gc::AllocKind al
|
|||
|
||||
// No explicit check for nursery.isEnabled() is needed, as the comparison
|
||||
// with the nursery's end will always fail in such cases.
|
||||
const Nursery& nursery = GetJitContext()->runtime->gcNursery();
|
||||
CompileZone* zone = GetJitContext()->compartment->zone();
|
||||
int thingSize = int(gc::Arena::thingSize(allocKind));
|
||||
int totalSize = thingSize + nDynamicSlots * sizeof(HeapSlot);
|
||||
MOZ_ASSERT(totalSize % gc::CellSize == 0);
|
||||
loadPtr(AbsoluteAddress(nursery.addressOfPosition()), result);
|
||||
loadPtr(AbsoluteAddress(zone->addressOfNurseryPosition()), result);
|
||||
computeEffectiveAddress(Address(result, totalSize), temp);
|
||||
branchPtr(Assembler::Below, AbsoluteAddress(nursery.addressOfCurrentEnd()), temp, fail);
|
||||
storePtr(temp, AbsoluteAddress(nursery.addressOfPosition()));
|
||||
branchPtr(Assembler::Below, AbsoluteAddress(zone->addressOfNurseryCurrentEnd()), temp, fail);
|
||||
storePtr(temp, AbsoluteAddress(zone->addressOfNurseryPosition()));
|
||||
|
||||
if (nDynamicSlots) {
|
||||
computeEffectiveAddress(Address(result, thingSize), temp);
|
||||
|
@ -1403,6 +1403,24 @@ MacroAssembler::loadStringChar(Register str, Register index, Register output)
|
|||
bind(&done);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::loadJSContext(Register dest)
|
||||
{
|
||||
CompileCompartment* compartment = GetJitContext()->compartment;
|
||||
if (compartment->zone()->isAtomsZone()) {
|
||||
// If we are in the atoms zone then we are generating a runtime wide
|
||||
// trampoline which can run in any zone. Load the context which is
|
||||
// currently running using cooperative scheduling in the runtime.
|
||||
// (This will need to be fixed when we have preemptive scheduling,
|
||||
// bug 1323066).
|
||||
loadPtr(AbsoluteAddress(GetJitContext()->runtime->addressOfActiveJSContext()), dest);
|
||||
} else {
|
||||
// If we are in a specific zone then the current context will be stored
|
||||
// in the containing zone group.
|
||||
loadPtr(AbsoluteAddress(GetJitContext()->compartment->zone()->addressOfJSContext()), dest);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
BailoutReportOverRecursed(JSContext* cx)
|
||||
{
|
||||
|
@ -1412,7 +1430,7 @@ BailoutReportOverRecursed(JSContext* cx)
|
|||
void
|
||||
MacroAssembler::generateBailoutTail(Register scratch, Register bailoutInfo)
|
||||
{
|
||||
enterExitFrame();
|
||||
enterExitFrame(scratch);
|
||||
|
||||
Label baseline;
|
||||
|
||||
|
@ -1473,7 +1491,7 @@ MacroAssembler::generateBailoutTail(Register scratch, Register bailoutInfo)
|
|||
push(temp);
|
||||
push(Address(bailoutInfo, offsetof(BaselineBailoutInfo, resumeAddr)));
|
||||
// No GC things to mark on the stack, push a bare token.
|
||||
enterFakeExitFrame(ExitFrameLayoutBareToken);
|
||||
enterFakeExitFrame(scratch, ExitFrameLayoutBareToken);
|
||||
|
||||
// If monitorStub is non-null, handle resumeAddr appropriately.
|
||||
Label noMonitor;
|
||||
|
@ -2238,11 +2256,9 @@ MacroAssembler::AutoProfilerCallInstrumentation::AutoProfilerCallInstrumentation
|
|||
masm.push(reg);
|
||||
masm.push(reg2);
|
||||
|
||||
JitContext* icx = GetJitContext();
|
||||
AbsoluteAddress profilingActivation(icx->runtime->addressOfProfilingActivation());
|
||||
|
||||
CodeOffset label = masm.movWithPatch(ImmWord(uintptr_t(-1)), reg);
|
||||
masm.loadPtr(profilingActivation, reg2);
|
||||
masm.loadJSContext(reg2);
|
||||
masm.loadPtr(Address(reg2, offsetof(JSContext, profilingActivation_)), reg2);
|
||||
masm.storePtr(reg, Address(reg2, JitActivation::offsetOfLastProfilingCallSite()));
|
||||
|
||||
masm.appendProfilerCallSite(label);
|
||||
|
@ -2683,10 +2699,10 @@ MacroAssembler::callWithABINoProfiler(wasm::SymbolicAddress imm, MoveOp::Type re
|
|||
// Exit frame footer.
|
||||
|
||||
void
|
||||
MacroAssembler::linkExitFrame()
|
||||
MacroAssembler::linkExitFrame(Register temp)
|
||||
{
|
||||
AbsoluteAddress jitTop(GetJitContext()->runtime->addressOfJitTop());
|
||||
storeStackPtr(jitTop);
|
||||
loadJSContext(temp);
|
||||
storeStackPtr(Address(temp, offsetof(JSContext, jitTop)));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -686,14 +686,14 @@ class MacroAssembler : public MacroAssemblerSpecific
|
|||
inline bool hasSelfReference() const;
|
||||
|
||||
// Push stub code and the VMFunction pointer.
|
||||
inline void enterExitFrame(const VMFunction* f = nullptr);
|
||||
inline void enterExitFrame(Register temp, const VMFunction* f = nullptr);
|
||||
|
||||
// Push an exit frame token to identify which fake exit frame this footer
|
||||
// corresponds to.
|
||||
inline void enterFakeExitFrame(enum ExitFrameTokenValues token);
|
||||
inline void enterFakeExitFrame(Register temp, enum ExitFrameTokenValues token);
|
||||
|
||||
// Push an exit frame token for a native call.
|
||||
inline void enterFakeExitFrameForNative(bool isConstructing);
|
||||
inline void enterFakeExitFrameForNative(Register temp, bool isConstructing);
|
||||
|
||||
// Pop ExitFrame footer in addition to the extra frame.
|
||||
inline void leaveExitFrame(size_t extraFrame = 0);
|
||||
|
@ -701,7 +701,7 @@ class MacroAssembler : public MacroAssemblerSpecific
|
|||
private:
|
||||
// Save the top of the stack into JSontext::jitTop of the current thread,
|
||||
// which should be the location of the latest exit frame.
|
||||
void linkExitFrame();
|
||||
void linkExitFrame(Register temp);
|
||||
|
||||
// Patch the value of PushStubCode with the pointer to the finalized code.
|
||||
void linkSelfReference(JitCode* code);
|
||||
|
@ -1494,11 +1494,10 @@ class MacroAssembler : public MacroAssemblerSpecific
|
|||
void loadStringChars(Register str, Register dest);
|
||||
void loadStringChar(Register str, Register index, Register output);
|
||||
|
||||
void loadJSContext(Register dest) {
|
||||
movePtr(ImmPtr(GetJitContext()->runtime->getJSContext()), dest);
|
||||
}
|
||||
void loadJSContext(Register dest);
|
||||
void loadJitActivation(Register dest) {
|
||||
loadPtr(AbsoluteAddress(GetJitContext()->runtime->addressOfActivation()), dest);
|
||||
loadJSContext(dest);
|
||||
loadPtr(Address(dest, offsetof(JSContext, activation_)), dest);
|
||||
}
|
||||
void loadWasmActivationFromTls(Register dest) {
|
||||
loadPtr(Address(WasmTlsReg, offsetof(wasm::TlsData, cx)), dest);
|
||||
|
|
|
@ -4747,8 +4747,8 @@ MacroAssemblerARMCompat::atomicExchangeToTypedIntArray(Scalar::Type arrayType, c
|
|||
void
|
||||
MacroAssemblerARMCompat::profilerEnterFrame(Register framePtr, Register scratch)
|
||||
{
|
||||
AbsoluteAddress activation(GetJitContext()->runtime->addressOfProfilingActivation());
|
||||
loadPtr(activation, scratch);
|
||||
asMasm().loadJSContext(scratch);
|
||||
loadPtr(Address(scratch, offsetof(JSContext, profilingActivation_)), scratch);
|
||||
storePtr(framePtr, Address(scratch, JitActivation::offsetOfLastProfilingFrame()));
|
||||
storePtr(ImmPtr(nullptr), Address(scratch, JitActivation::offsetOfLastProfilingCallSite()));
|
||||
}
|
||||
|
|
|
@ -287,7 +287,7 @@ JitRuntime::generateEnterJIT(JSContext* cx, EnterJitType type)
|
|||
masm.push(scratch);
|
||||
masm.push(Imm32(0)); // Fake return address.
|
||||
// No GC things to mark on the stack, push a bare token.
|
||||
masm.enterFakeExitFrame(ExitFrameLayoutBareToken);
|
||||
masm.enterFakeExitFrame(scratch, ExitFrameLayoutBareToken);
|
||||
|
||||
masm.push(framePtr); // BaselineFrame
|
||||
masm.push(r0); // jitcode
|
||||
|
@ -793,7 +793,7 @@ JitRuntime::generateVMWrapper(JSContext* cx, const VMFunction& f)
|
|||
if (f.expectTailCall == NonTailCall)
|
||||
masm.pushReturnAddress();
|
||||
|
||||
masm.enterExitFrame(&f);
|
||||
masm.enterExitFrame(cxreg, &f);
|
||||
masm.loadJSContext(cxreg);
|
||||
|
||||
// Save the base of the argument set stored on the stack.
|
||||
|
@ -1155,8 +1155,8 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
|
|||
// ^--- Entry Frame (From C++)
|
||||
//
|
||||
Register actReg = scratch4;
|
||||
AbsoluteAddress activationAddr(GetJitContext()->runtime->addressOfProfilingActivation());
|
||||
masm.loadPtr(activationAddr, actReg);
|
||||
masm.loadJSContext(actReg);
|
||||
masm.loadPtr(Address(actReg, offsetof(JSContext, profilingActivation_)), actReg);
|
||||
|
||||
Address lastProfilingFrame(actReg, JitActivation::offsetOfLastProfilingFrame());
|
||||
Address lastProfilingCallSite(actReg, JitActivation::offsetOfLastProfilingCallSite());
|
||||
|
|
|
@ -217,6 +217,15 @@ MacroAssemblerCompat::handleFailureWithHandlerTail(void* handler)
|
|||
Br(x1);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerCompat::profilerEnterFrame(Register framePtr, Register scratch)
|
||||
{
|
||||
asMasm().loadJSContext(scratch);
|
||||
loadPtr(Address(scratch, offsetof(JSContext, profilingActivation_)), scratch);
|
||||
storePtr(framePtr, Address(scratch, JitActivation::offsetOfLastProfilingFrame()));
|
||||
storePtr(ImmPtr(nullptr), Address(scratch, JitActivation::offsetOfLastProfilingCallSite()));
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerCompat::breakpoint()
|
||||
{
|
||||
|
|
|
@ -1866,12 +1866,7 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
|
|||
|
||||
void handleFailureWithHandlerTail(void* handler);
|
||||
|
||||
void profilerEnterFrame(Register framePtr, Register scratch) {
|
||||
AbsoluteAddress activation(GetJitContext()->runtime->addressOfProfilingActivation());
|
||||
loadPtr(activation, scratch);
|
||||
storePtr(framePtr, Address(scratch, JitActivation::offsetOfLastProfilingFrame()));
|
||||
storePtr(ImmPtr(nullptr), Address(scratch, JitActivation::offsetOfLastProfilingCallSite()));
|
||||
}
|
||||
void profilerEnterFrame(Register framePtr, Register scratch);
|
||||
void profilerExitFrame() {
|
||||
branch(GetJitContext()->runtime->jitRuntime()->getProfilerExitFrameTail());
|
||||
}
|
||||
|
|
|
@ -189,7 +189,7 @@ JitRuntime::generateEnterJIT(JSContext* cx, EnterJitType type)
|
|||
masm.makeFrameDescriptor(r19, JitFrame_BaselineJS, ExitFrameLayout::Size());
|
||||
masm.asVIXL().Push(x19, xzr); // Push xzr for a fake return address.
|
||||
// No GC things to mark: push a bare token.
|
||||
masm.enterFakeExitFrame(ExitFrameLayoutBareToken);
|
||||
masm.enterFakeExitFrame(r19, ExitFrameLayoutBareToken);
|
||||
|
||||
masm.push(BaselineFrameReg, reg_code);
|
||||
|
||||
|
@ -586,7 +586,7 @@ JitRuntime::generateVMWrapper(JSContext* cx, const VMFunction& f)
|
|||
// +0 returnAddress (pushed by this function, caller sets as lr)
|
||||
//
|
||||
// We're aligned to an exit frame, so link it up.
|
||||
masm.enterExitFrame(&f);
|
||||
masm.enterExitFrame(reg_cx, &f);
|
||||
masm.loadJSContext(reg_cx);
|
||||
|
||||
// Save the current stack pointer as the base for copying arguments.
|
||||
|
@ -943,8 +943,8 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
|
|||
// ^--- Entry Frame (From C++)
|
||||
//
|
||||
Register actReg = scratch4;
|
||||
AbsoluteAddress activationAddr(GetJitContext()->runtime->addressOfProfilingActivation());
|
||||
masm.loadPtr(activationAddr, actReg);
|
||||
masm.loadJSContext(actReg);
|
||||
masm.loadPtr(Address(actReg, offsetof(JSContext, profilingActivation_)), actReg);
|
||||
|
||||
Address lastProfilingFrame(actReg, JitActivation::offsetOfLastProfilingFrame());
|
||||
Address lastProfilingCallSite(actReg, JitActivation::offsetOfLastProfilingCallSite());
|
||||
|
|
|
@ -2052,8 +2052,8 @@ MacroAssemblerMIPSCompat::toggledCall(JitCode* target, bool enabled)
|
|||
void
|
||||
MacroAssemblerMIPSCompat::profilerEnterFrame(Register framePtr, Register scratch)
|
||||
{
|
||||
AbsoluteAddress activation(GetJitContext()->runtime->addressOfProfilingActivation());
|
||||
loadPtr(activation, scratch);
|
||||
asMasm().loadJSContext(scratch);
|
||||
loadPtr(Address(scratch, offsetof(JSContext, profilingActivation_)), scratch);
|
||||
storePtr(framePtr, Address(scratch, JitActivation::offsetOfLastProfilingFrame()));
|
||||
storePtr(ImmPtr(nullptr), Address(scratch, JitActivation::offsetOfLastProfilingCallSite()));
|
||||
}
|
||||
|
|
|
@ -254,7 +254,7 @@ JitRuntime::generateEnterJIT(JSContext* cx, EnterJitType type)
|
|||
masm.storePtr(zero, Address(StackPointer, 0)); // fake return address
|
||||
|
||||
// No GC things to mark, push a bare token.
|
||||
masm.enterFakeExitFrame(ExitFrameLayoutBareToken);
|
||||
masm.enterFakeExitFrame(scratch, ExitFrameLayoutBareToken);
|
||||
|
||||
masm.reserveStack(2 * sizeof(uintptr_t));
|
||||
masm.storePtr(framePtr, Address(StackPointer, sizeof(uintptr_t))); // BaselineFrame
|
||||
|
@ -736,7 +736,7 @@ JitRuntime::generateVMWrapper(JSContext* cx, const VMFunction& f)
|
|||
masm.pushReturnAddress();
|
||||
|
||||
// We're aligned to an exit frame, so link it up.
|
||||
masm.enterExitFrame(&f);
|
||||
masm.enterExitFrame(cxreg, &f);
|
||||
masm.loadJSContext(cxreg);
|
||||
|
||||
// Save the base of the argument set stored on the stack.
|
||||
|
@ -1134,8 +1134,8 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
|
|||
// ^--- Entry Frame (From C++)
|
||||
//
|
||||
Register actReg = scratch4;
|
||||
AbsoluteAddress activationAddr(GetJitContext()->runtime->addressOfProfilingActivation());
|
||||
masm.loadPtr(activationAddr, actReg);
|
||||
masm.loadJSContext(actReg);
|
||||
masm.loadPtr(Address(actReg, offsetof(JSContext, profilingActivation_)), actReg);
|
||||
|
||||
Address lastProfilingFrame(actReg, JitActivation::offsetOfLastProfilingFrame());
|
||||
Address lastProfilingCallSite(actReg, JitActivation::offsetOfLastProfilingCallSite());
|
||||
|
|
|
@ -2227,8 +2227,8 @@ MacroAssemblerMIPS64Compat::toggledCall(JitCode* target, bool enabled)
|
|||
void
|
||||
MacroAssemblerMIPS64Compat::profilerEnterFrame(Register framePtr, Register scratch)
|
||||
{
|
||||
AbsoluteAddress activation(GetJitContext()->runtime->addressOfProfilingActivation());
|
||||
loadPtr(activation, scratch);
|
||||
asMasm().loadJSContext(scratch);
|
||||
loadPtr(Address(scratch, offsetof(JSContext, profilingActivation_)), scratch);
|
||||
storePtr(framePtr, Address(scratch, JitActivation::offsetOfLastProfilingFrame()));
|
||||
storePtr(ImmPtr(nullptr), Address(scratch, JitActivation::offsetOfLastProfilingCallSite()));
|
||||
}
|
||||
|
|
|
@ -271,7 +271,7 @@ JitRuntime::generateEnterJIT(JSContext* cx, EnterJitType type)
|
|||
masm.storePtr(zero, Address(StackPointer, 0)); // fake return address
|
||||
|
||||
// No GC things to mark, push a bare token.
|
||||
masm.enterFakeExitFrame(ExitFrameLayoutBareToken);
|
||||
masm.enterFakeExitFrame(scratch, ExitFrameLayoutBareToken);
|
||||
|
||||
masm.reserveStack(2 * sizeof(uintptr_t));
|
||||
masm.storePtr(framePtr, Address(StackPointer, sizeof(uintptr_t))); // BaselineFrame
|
||||
|
@ -706,7 +706,7 @@ JitRuntime::generateVMWrapper(JSContext* cx, const VMFunction& f)
|
|||
masm.pushReturnAddress();
|
||||
|
||||
// We're aligned to an exit frame, so link it up.
|
||||
masm.enterExitFrame(&f);
|
||||
masm.enterExitFrame(cxreg, &f);
|
||||
masm.loadJSContext(cxreg);
|
||||
|
||||
// Save the base of the argument set stored on the stack.
|
||||
|
@ -1079,8 +1079,8 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
|
|||
// ^--- Entry Frame (From C++)
|
||||
//
|
||||
Register actReg = scratch4;
|
||||
AbsoluteAddress activationAddr(GetJitContext()->runtime->addressOfProfilingActivation());
|
||||
masm.loadPtr(activationAddr, actReg);
|
||||
masm.loadJSContext(actReg);
|
||||
masm.loadPtr(Address(actReg, offsetof(JSContext, profilingActivation_)), actReg);
|
||||
|
||||
Address lastProfilingFrame(actReg, JitActivation::offsetOfLastProfilingFrame());
|
||||
Address lastProfilingCallSite(actReg, JitActivation::offsetOfLastProfilingCallSite());
|
||||
|
|
|
@ -1378,13 +1378,18 @@ class LInitPropGetterSetter : public LCallInstructionHelper<0, 2, 0>
|
|||
}
|
||||
};
|
||||
|
||||
class LCheckOverRecursed : public LInstructionHelper<0, 0, 0>
|
||||
class LCheckOverRecursed : public LInstructionHelper<0, 0, 1>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(CheckOverRecursed)
|
||||
|
||||
LCheckOverRecursed()
|
||||
{ }
|
||||
explicit LCheckOverRecursed(const LDefinition& temp) {
|
||||
setTemp(0, temp);
|
||||
}
|
||||
|
||||
const LDefinition* temp() {
|
||||
return getTemp(0);
|
||||
}
|
||||
|
||||
MCheckOverRecursed* mir() const {
|
||||
return mir_->toCheckOverRecursed();
|
||||
|
@ -1484,22 +1489,24 @@ class LRotateI64 : public details::RotateBase<INT64_PIECES, INT64_PIECES + 1, 1>
|
|||
LAllocation* count() { return getOperand(Count); }
|
||||
};
|
||||
|
||||
class LInterruptCheck : public LInstructionHelper<0, 0, 0>
|
||||
class LInterruptCheck : public LInstructionHelper<0, 0, 1>
|
||||
{
|
||||
Label* oolEntry_;
|
||||
|
||||
// Whether this is an implicit interrupt check. Implicit interrupt checks
|
||||
// use a patchable backedge and signal handlers instead of an explicit
|
||||
// rt->interrupt check.
|
||||
// cx->interrupt check.
|
||||
bool implicit_;
|
||||
|
||||
public:
|
||||
LIR_HEADER(InterruptCheck)
|
||||
|
||||
LInterruptCheck()
|
||||
explicit LInterruptCheck(const LDefinition& temp)
|
||||
: oolEntry_(nullptr),
|
||||
implicit_(false)
|
||||
{}
|
||||
{
|
||||
setTemp(0, temp);
|
||||
}
|
||||
|
||||
Label* oolEntry() {
|
||||
MOZ_ASSERT(implicit_);
|
||||
|
@ -1516,10 +1523,15 @@ class LInterruptCheck : public LInstructionHelper<0, 0, 0>
|
|||
|
||||
void setImplicit() {
|
||||
implicit_ = true;
|
||||
setTemp(0, LDefinition::BogusTemp());
|
||||
}
|
||||
bool implicit() const {
|
||||
return implicit_;
|
||||
}
|
||||
|
||||
const LDefinition* temp() {
|
||||
return getTemp(0);
|
||||
}
|
||||
};
|
||||
|
||||
class LDefVar : public LCallInstructionHelper<0, 1, 0>
|
||||
|
|
|
@ -381,8 +381,8 @@ MacroAssemblerX64::handleFailureWithHandlerTail(void* handler)
|
|||
void
|
||||
MacroAssemblerX64::profilerEnterFrame(Register framePtr, Register scratch)
|
||||
{
|
||||
AbsoluteAddress activation(GetJitContext()->runtime->addressOfProfilingActivation());
|
||||
loadPtr(activation, scratch);
|
||||
asMasm().loadJSContext(scratch);
|
||||
loadPtr(Address(scratch, offsetof(JSContext, profilingActivation_)), scratch);
|
||||
storePtr(framePtr, Address(scratch, JitActivation::offsetOfLastProfilingFrame()));
|
||||
storePtr(ImmPtr(nullptr), Address(scratch, JitActivation::offsetOfLastProfilingCallSite()));
|
||||
}
|
||||
|
|
|
@ -229,7 +229,7 @@ JitRuntime::generateEnterJIT(JSContext* cx, EnterJitType type)
|
|||
masm.push(valuesSize);
|
||||
masm.push(Imm32(0)); // Fake return address.
|
||||
// No GC things to mark, push a bare token.
|
||||
masm.enterFakeExitFrame(ExitFrameLayoutBareToken);
|
||||
masm.enterFakeExitFrame(scratch, ExitFrameLayoutBareToken);
|
||||
|
||||
regs.add(valuesSize);
|
||||
|
||||
|
@ -667,7 +667,7 @@ JitRuntime::generateVMWrapper(JSContext* cx, const VMFunction& f)
|
|||
// +0 returnAddress
|
||||
//
|
||||
// We're aligned to an exit frame, so link it up.
|
||||
masm.enterExitFrame(&f);
|
||||
masm.enterExitFrame(cxreg, &f);
|
||||
masm.loadJSContext(cxreg);
|
||||
|
||||
// Save the current stack pointer as the base for copying arguments.
|
||||
|
@ -1026,8 +1026,8 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
|
|||
// ^--- Entry Frame (From C++)
|
||||
//
|
||||
Register actReg = scratch4;
|
||||
AbsoluteAddress activationAddr(GetJitContext()->runtime->addressOfProfilingActivation());
|
||||
masm.loadPtr(activationAddr, actReg);
|
||||
masm.loadJSContext(actReg);
|
||||
masm.loadPtr(Address(actReg, offsetof(JSContext, profilingActivation_)), actReg);
|
||||
|
||||
Address lastProfilingFrame(actReg, JitActivation::offsetOfLastProfilingFrame());
|
||||
Address lastProfilingCallSite(actReg, JitActivation::offsetOfLastProfilingCallSite());
|
||||
|
|
|
@ -288,8 +288,8 @@ MacroAssemblerX86::handleFailureWithHandlerTail(void* handler)
|
|||
void
|
||||
MacroAssemblerX86::profilerEnterFrame(Register framePtr, Register scratch)
|
||||
{
|
||||
AbsoluteAddress activation(GetJitContext()->runtime->addressOfProfilingActivation());
|
||||
loadPtr(activation, scratch);
|
||||
asMasm().loadJSContext(scratch);
|
||||
loadPtr(Address(scratch, offsetof(JSContext, profilingActivation_)), scratch);
|
||||
storePtr(framePtr, Address(scratch, JitActivation::offsetOfLastProfilingFrame()));
|
||||
storePtr(ImmPtr(nullptr), Address(scratch, JitActivation::offsetOfLastProfilingCallSite()));
|
||||
}
|
||||
|
|
|
@ -224,7 +224,7 @@ JitRuntime::generateEnterJIT(JSContext* cx, EnterJitType type)
|
|||
masm.push(scratch); // Fake return address.
|
||||
masm.push(Imm32(0));
|
||||
// No GC things to mark on the stack, push a bare token.
|
||||
masm.enterFakeExitFrame(ExitFrameLayoutBareToken);
|
||||
masm.enterFakeExitFrame(scratch, ExitFrameLayoutBareToken);
|
||||
|
||||
masm.push(framePtr);
|
||||
masm.push(jitcode);
|
||||
|
@ -696,7 +696,7 @@ JitRuntime::generateVMWrapper(JSContext* cx, const VMFunction& f)
|
|||
// +0 returnAddress
|
||||
//
|
||||
// We're aligned to an exit frame, so link it up.
|
||||
masm.enterExitFrame(&f);
|
||||
masm.enterExitFrame(cxreg, &f);
|
||||
masm.loadJSContext(cxreg);
|
||||
|
||||
// Save the current stack pointer as the base for copying arguments.
|
||||
|
@ -1056,8 +1056,8 @@ JitRuntime::generateProfilerExitFrameTailStub(JSContext* cx)
|
|||
// ^--- Entry Frame (From C++)
|
||||
//
|
||||
Register actReg = scratch4;
|
||||
AbsoluteAddress activationAddr(GetJitContext()->runtime->addressOfProfilingActivation());
|
||||
masm.loadPtr(activationAddr, actReg);
|
||||
masm.loadJSContext(actReg);
|
||||
masm.loadPtr(Address(actReg, offsetof(JSContext, profilingActivation_)), actReg);
|
||||
|
||||
Address lastProfilingFrame(actReg, JitActivation::offsetOfLastProfilingFrame());
|
||||
Address lastProfilingCallSite(actReg, JitActivation::offsetOfLastProfilingCallSite());
|
||||
|
|
|
@ -649,12 +649,9 @@ JSCompartment::traceRoots(JSTracer* trc, js::gc::GCRuntime::TraceOrMarkRuntime t
|
|||
}
|
||||
|
||||
if (!JS::CurrentThreadIsHeapMinorCollecting()) {
|
||||
// JIT code and the global are never nursery allocated, so we only need
|
||||
// to trace them when not doing a minor collection.
|
||||
|
||||
if (jitCompartment_)
|
||||
jitCompartment_->trace(trc, this);
|
||||
|
||||
// The global is never nursery allocated, so we don't need to
|
||||
// trace it when doing a minor collection.
|
||||
//
|
||||
// If a compartment is on-stack, we mark its global so that
|
||||
// JSContext::global() remains valid.
|
||||
if (enterCompartmentDepth && global_.unbarrieredGet())
|
||||
|
|
Загрузка…
Ссылка в новой задаче