mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1143011 - Use AllocatableSet or LiveSet for all register set uses. r=jandem
This commit is contained in:
parent
36197ee613
commit
16f92ff981
@ -8229,19 +8229,19 @@ StackDecrementForCall(MacroAssembler &masm, uint32_t alignment, const VectorT &a
|
||||
#if defined(JS_CODEGEN_ARM)
|
||||
// The ARM system ABI also includes d15 & s31 in the non volatile float registers.
|
||||
// Also exclude lr (a.k.a. r14) as we preserve it manually)
|
||||
static const RegisterSet NonVolatileRegs =
|
||||
RegisterSet(GeneralRegisterSet(Registers::NonVolatileMask &
|
||||
~(uint32_t(1) << Registers::lr)),
|
||||
FloatRegisterSet(FloatRegisters::NonVolatileMask
|
||||
| (1ULL << FloatRegisters::d15)
|
||||
| (1ULL << FloatRegisters::s31)));
|
||||
static const LiveRegisterSet NonVolatileRegs =
|
||||
LiveRegisterSet(GeneralRegisterSet(Registers::NonVolatileMask &
|
||||
~(uint32_t(1) << Registers::lr)),
|
||||
FloatRegisterSet(FloatRegisters::NonVolatileMask
|
||||
| (1ULL << FloatRegisters::d15)
|
||||
| (1ULL << FloatRegisters::s31)));
|
||||
#else
|
||||
static const RegisterSet NonVolatileRegs =
|
||||
RegisterSet(GeneralRegisterSet(Registers::NonVolatileMask),
|
||||
FloatRegisterSet(FloatRegisters::NonVolatileMask));
|
||||
static const LiveRegisterSet NonVolatileRegs =
|
||||
LiveRegisterSet(GeneralRegisterSet(Registers::NonVolatileMask),
|
||||
FloatRegisterSet(FloatRegisters::NonVolatileMask));
|
||||
#endif
|
||||
static const FloatRegisterSet NonVolatileSimdRegs = SupportsSimd ? NonVolatileRegs.fpus()
|
||||
: FloatRegisterSet();
|
||||
static const LiveFloatRegisterSet NonVolatileSimdRegs(
|
||||
SupportsSimd ? NonVolatileRegs.fpus() : FloatRegisterSet());
|
||||
|
||||
#if defined(JS_CODEGEN_MIPS)
|
||||
// Mips is using one more double slot due to stack alignment for double values.
|
||||
@ -9031,10 +9031,10 @@ GenerateOnOutOfBoundsLabelExit(ModuleCompiler &m, Label *throwLabel)
|
||||
return m.finishGeneratingInlineStub(&m.onOutOfBoundsLabel()) && !masm.oom();
|
||||
}
|
||||
|
||||
static const RegisterSet AllRegsExceptSP =
|
||||
RegisterSet(GeneralRegisterSet(Registers::AllMask &
|
||||
~(uint32_t(1) << Registers::StackPointer)),
|
||||
FloatRegisterSet(FloatRegisters::AllDoubleMask));
|
||||
static const LiveRegisterSet AllRegsExceptSP(
|
||||
GeneralRegisterSet(Registers::AllMask &
|
||||
~(uint32_t(1) << Registers::StackPointer)),
|
||||
FloatRegisterSet(FloatRegisters::AllDoubleMask));
|
||||
|
||||
// The async interrupt-callback exit is called from arbitrarily-interrupted asm.js
|
||||
// code. That means we must first save *all* registers and restore *all*
|
||||
@ -9058,7 +9058,8 @@ GenerateAsyncInterruptExit(ModuleCompiler &m, Label *throwLabel)
|
||||
masm.push(Imm32(0)); // space for resumePC
|
||||
masm.pushFlags(); // after this we are safe to use sub
|
||||
masm.setFramePushed(0); // set to zero so we can use masm.framePushed() below
|
||||
masm.PushRegsInMask(AllRegsExceptSP, AllRegsExceptSP.fpus()); // save all GP/FP registers (except SP)
|
||||
LiveFloatRegisterSet simdSet(AllRegsExceptSP.fpus());
|
||||
masm.PushRegsInMask(AllRegsExceptSP, simdSet); // save all GP/FP registers (except SP)
|
||||
|
||||
Register scratch = ABIArgGenerator::NonArgReturnReg0;
|
||||
|
||||
@ -9083,7 +9084,7 @@ GenerateAsyncInterruptExit(ModuleCompiler &m, Label *throwLabel)
|
||||
masm.mov(ABIArgGenerator::NonVolatileReg, StackPointer);
|
||||
|
||||
// Restore the machine state to before the interrupt.
|
||||
masm.PopRegsInMask(AllRegsExceptSP, AllRegsExceptSP.fpus()); // restore all GP/FP registers (except SP)
|
||||
masm.PopRegsInMask(AllRegsExceptSP, simdSet); // restore all GP/FP registers (except SP)
|
||||
masm.popFlags(); // after this, nothing that sets conditions
|
||||
masm.ret(); // pop resumePC into PC
|
||||
#elif defined(JS_CODEGEN_MIPS)
|
||||
@ -9128,7 +9129,11 @@ GenerateAsyncInterruptExit(ModuleCompiler &m, Label *throwLabel)
|
||||
masm.loadAsmJSHeapRegisterFromGlobalData();
|
||||
#elif defined(JS_CODEGEN_ARM)
|
||||
masm.setFramePushed(0); // set to zero so we can use masm.framePushed() below
|
||||
masm.PushRegsInMask(RegisterSet(GeneralRegisterSet(Registers::AllMask & ~(1<<Registers::sp)), FloatRegisterSet(uint32_t(0)))); // save all GP registers,excep sp
|
||||
|
||||
// Save all GPR, except the stack pointer.
|
||||
masm.PushRegsInMask(LiveRegisterSet(
|
||||
GeneralRegisterSet(Registers::AllMask & ~(1<<Registers::sp)),
|
||||
FloatRegisterSet(uint32_t(0))));
|
||||
|
||||
// Save both the APSR and FPSCR in non-volatile registers.
|
||||
masm.as_mrs(r4);
|
||||
@ -9145,8 +9150,11 @@ GenerateAsyncInterruptExit(ModuleCompiler &m, Label *throwLabel)
|
||||
|
||||
// When this platform supports SIMD extensions, we'll need to push and pop
|
||||
// high lanes of SIMD registers as well.
|
||||
|
||||
// Save all FP registers
|
||||
JS_STATIC_ASSERT(!SupportsSimd);
|
||||
masm.PushRegsInMask(RegisterSet(GeneralRegisterSet(0), FloatRegisterSet(FloatRegisters::AllDoubleMask))); // save all FP registers
|
||||
masm.PushRegsInMask(LiveRegisterSet(GeneralRegisterSet(0),
|
||||
FloatRegisterSet(FloatRegisters::AllDoubleMask)));
|
||||
|
||||
masm.assertStackAlignment(ABIStackAlignment);
|
||||
masm.call(AsmJSImm_HandleExecutionInterrupt);
|
||||
@ -9154,7 +9162,10 @@ GenerateAsyncInterruptExit(ModuleCompiler &m, Label *throwLabel)
|
||||
masm.branchIfFalseBool(ReturnReg, throwLabel);
|
||||
|
||||
// Restore the machine state to before the interrupt. this will set the pc!
|
||||
masm.PopRegsInMask(RegisterSet(GeneralRegisterSet(0), FloatRegisterSet(FloatRegisters::AllDoubleMask))); // restore all FP registers
|
||||
|
||||
// Restore all FP registers
|
||||
masm.PopRegsInMask(LiveRegisterSet(GeneralRegisterSet(0),
|
||||
FloatRegisterSet(FloatRegisters::AllDoubleMask)));
|
||||
masm.mov(r6,sp);
|
||||
masm.as_vmsr(r5);
|
||||
masm.as_msr(r4);
|
||||
|
@ -68,7 +68,7 @@ NativeRegExpMacroAssembler::NativeRegExpMacroAssembler(LifoAlloc *alloc, RegExpS
|
||||
runtime(rt), mode_(mode)
|
||||
{
|
||||
// Find physical registers for each compiler register.
|
||||
GeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
|
||||
input_end_pointer = regs.takeAny();
|
||||
current_character = regs.takeAny();
|
||||
@ -382,7 +382,7 @@ NativeRegExpMacroAssembler::GenerateCode(JSContext *cx, bool match_only)
|
||||
masm.movePtr(ImmPtr(runtime), temp1);
|
||||
|
||||
// Save registers before calling C function
|
||||
GeneralRegisterSet volatileRegs = GeneralRegisterSet::Volatile();
|
||||
LiveGeneralRegisterSet volatileRegs(GeneralRegisterSet::Volatile());
|
||||
#if defined(JS_CODEGEN_ARM)
|
||||
volatileRegs.add(Register::FromCode(Registers::lr));
|
||||
#elif defined(JS_CODEGEN_MIPS)
|
||||
@ -784,7 +784,7 @@ NativeRegExpMacroAssembler::CheckNotBackReferenceIgnoreCase(int start_reg, Label
|
||||
MOZ_ASSERT(mode_ == CHAR16);
|
||||
|
||||
// Note: temp1 needs to be saved/restored if it is volatile, as it is used after the call.
|
||||
GeneralRegisterSet volatileRegs = GeneralRegisterSet::Volatile();
|
||||
LiveGeneralRegisterSet volatileRegs(GeneralRegisterSet::Volatile());
|
||||
volatileRegs.takeUnchecked(temp0);
|
||||
volatileRegs.takeUnchecked(temp2);
|
||||
masm.PushRegsInMask(volatileRegs);
|
||||
|
@ -181,7 +181,9 @@ class MOZ_STACK_CLASS NativeRegExpMacroAssembler : public RegExpMacroAssembler
|
||||
jit::Label stack_overflow_label_;
|
||||
jit::Label exit_with_exception_label_;
|
||||
|
||||
jit::GeneralRegisterSet savedNonVolatileRegisters;
|
||||
// Set of registers which are used by the code generator, and as such which
|
||||
// are saved.
|
||||
jit::LiveGeneralRegisterSet savedNonVolatileRegisters;
|
||||
|
||||
struct LabelPatch {
|
||||
// Once it is bound via BindBacktrack, |label| becomes null and
|
||||
|
@ -15,13 +15,13 @@ using mozilla::DebugOnly;
|
||||
bool
|
||||
BacktrackingAllocator::init()
|
||||
{
|
||||
RegisterSet remainingRegisters(allRegisters_);
|
||||
while (!remainingRegisters.empty(/* float = */ false)) {
|
||||
AnyRegister reg = AnyRegister(remainingRegisters.takeUnaliasedGeneral());
|
||||
LiveRegisterSet remainingRegisters(allRegisters_.asLiveSet());
|
||||
while (!remainingRegisters.emptyGeneral()) {
|
||||
AnyRegister reg = AnyRegister(remainingRegisters.takeAnyGeneral());
|
||||
registers[reg.code()].allocatable = true;
|
||||
}
|
||||
while (!remainingRegisters.empty(/* float = */ true)) {
|
||||
AnyRegister reg = AnyRegister(remainingRegisters.takeUnaliasedFloat());
|
||||
while (!remainingRegisters.emptyFloat()) {
|
||||
AnyRegister reg = AnyRegister(remainingRegisters.takeAnyFloat());
|
||||
registers[reg.code()].allocatable = true;
|
||||
}
|
||||
|
||||
|
@ -467,7 +467,7 @@ BaselineCompiler::emitOutOfLinePostBarrierSlot()
|
||||
masm.bind(&postBarrierSlot_);
|
||||
|
||||
Register objReg = R2.scratchReg();
|
||||
GeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
regs.take(R0);
|
||||
regs.take(objReg);
|
||||
regs.take(BaselineFrameReg);
|
||||
@ -799,9 +799,9 @@ bool
|
||||
BaselineCompiler::emitTraceLoggerEnter()
|
||||
{
|
||||
TraceLoggerThread *logger = TraceLoggerForMainThread(cx->runtime());
|
||||
RegisterSet regs = RegisterSet::Volatile();
|
||||
Register loggerReg = regs.takeGeneral();
|
||||
Register scriptReg = regs.takeGeneral();
|
||||
AllocatableRegisterSet regs(RegisterSet::Volatile());
|
||||
Register loggerReg = regs.takeAnyGeneral();
|
||||
Register scriptReg = regs.takeAnyGeneral();
|
||||
|
||||
Label noTraceLogger;
|
||||
traceLoggerEnterToggleOffset_ = masm.toggledJump(&noTraceLogger);
|
||||
@ -833,7 +833,8 @@ bool
|
||||
BaselineCompiler::emitTraceLoggerExit()
|
||||
{
|
||||
TraceLoggerThread *logger = TraceLoggerForMainThread(cx->runtime());
|
||||
Register loggerReg = RegisterSet::Volatile().takeGeneral();
|
||||
AllocatableRegisterSet regs(RegisterSet::Volatile());
|
||||
Register loggerReg = regs.takeAnyGeneral();
|
||||
|
||||
Label noTraceLogger;
|
||||
traceLoggerExitToggleOffset_ = masm.toggledJump(&noTraceLogger);
|
||||
@ -3588,7 +3589,7 @@ BaselineCompiler::emit_JSOP_RESUME()
|
||||
frame.syncStack(0);
|
||||
masm.checkStackAlignment();
|
||||
|
||||
GeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
regs.take(BaselineFrameReg);
|
||||
|
||||
// Load generator object.
|
||||
|
@ -1072,7 +1072,7 @@ EmitBaselineDebugModeOSRHandlerTail(MacroAssembler &masm, Register temp, bool re
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, FinishBaselineDebugModeOSR));
|
||||
|
||||
// Restore saved values.
|
||||
GeneralRegisterSet jumpRegs(GeneralRegisterSet::All());
|
||||
AllocatableGeneralRegisterSet jumpRegs(GeneralRegisterSet::All());
|
||||
if (returnFromCallVM) {
|
||||
jumpRegs.take(ReturnReg);
|
||||
} else {
|
||||
@ -1099,7 +1099,7 @@ JitRuntime::generateBaselineDebugModeOSRHandler(JSContext *cx, uint32_t *noFrame
|
||||
{
|
||||
MacroAssembler masm(cx);
|
||||
|
||||
GeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
regs.take(BaselineFrameReg);
|
||||
regs.take(ReturnReg);
|
||||
Register temp = regs.takeAny();
|
||||
|
@ -736,7 +736,7 @@ ICStubCompiler::leaveStubFrame(MacroAssembler &masm, bool calledIntoIon)
|
||||
|
||||
inline bool
|
||||
ICStubCompiler::emitPostWriteBarrierSlot(MacroAssembler &masm, Register obj, ValueOperand val,
|
||||
Register scratch, GeneralRegisterSet saveRegs)
|
||||
Register scratch, LiveGeneralRegisterSet saveRegs)
|
||||
{
|
||||
Label skipBarrier;
|
||||
masm.branchPtrInNurseryRange(Assembler::Equal, obj, scratch, &skipBarrier);
|
||||
@ -746,7 +746,7 @@ ICStubCompiler::emitPostWriteBarrierSlot(MacroAssembler &masm, Register obj, Val
|
||||
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS)
|
||||
saveRegs.add(BaselineTailCallReg);
|
||||
#endif
|
||||
saveRegs = GeneralRegisterSet::Intersect(saveRegs, GeneralRegisterSet::Volatile());
|
||||
saveRegs.set() = GeneralRegisterSet::Intersect(saveRegs.set(), GeneralRegisterSet::Volatile());
|
||||
masm.PushRegsInMask(saveRegs);
|
||||
masm.setupUnalignedABICall(2, scratch);
|
||||
masm.movePtr(ImmPtr(cx->runtime()), scratch);
|
||||
@ -1000,7 +1000,7 @@ ICWarmUpCounter_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
}
|
||||
|
||||
// Get a scratch register.
|
||||
GeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
Register osrDataReg = R0.scratchReg();
|
||||
regs.take(osrDataReg);
|
||||
regs.takeUnchecked(OsrFrameReg);
|
||||
@ -1993,7 +1993,7 @@ ICCompare_String::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
Register left = masm.extractString(R0, ExtractTemp0);
|
||||
Register right = masm.extractString(R1, ExtractTemp1);
|
||||
|
||||
GeneralRegisterSet regs(availableGeneralRegs(2));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(2));
|
||||
Register scratchReg = regs.takeAny();
|
||||
|
||||
masm.compareStrings(op, left, right, scratchReg, &failure);
|
||||
@ -3191,7 +3191,7 @@ CheckDOMProxyExpandoDoesNotShadow(JSContext *cx, MacroAssembler &masm, Register
|
||||
Address *expandoAndGenerationAddr,
|
||||
Address *generationAddr,
|
||||
Register scratch,
|
||||
GeneralRegisterSet &domProxyRegSet,
|
||||
AllocatableGeneralRegisterSet &domProxyRegSet,
|
||||
Label *checkFailed)
|
||||
{
|
||||
// Guard that the object does not have expando properties, or has an expando
|
||||
@ -4124,7 +4124,7 @@ static const VMFunction DoAtomizeStringInfo = FunctionInfo<DoAtomizeStringFn>(Do
|
||||
bool
|
||||
ICGetElemNativeCompiler::emitCallNative(MacroAssembler &masm, Register objReg)
|
||||
{
|
||||
GeneralRegisterSet regs = availableGeneralRegs(0);
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
regs.takeUnchecked(objReg);
|
||||
regs.takeUnchecked(BaselineTailCallReg);
|
||||
|
||||
@ -4151,7 +4151,7 @@ ICGetElemNativeCompiler::emitCallNative(MacroAssembler &masm, Register objReg)
|
||||
bool
|
||||
ICGetElemNativeCompiler::emitCallScripted(MacroAssembler &masm, Register objReg)
|
||||
{
|
||||
GeneralRegisterSet regs = availableGeneralRegs(0);
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
regs.takeUnchecked(objReg);
|
||||
regs.takeUnchecked(BaselineTailCallReg);
|
||||
|
||||
@ -4225,7 +4225,7 @@ ICGetElemNativeCompiler::generateStubCode(MacroAssembler &masm)
|
||||
masm.branchTestObject(Assembler::NotEqual, R0, &failure);
|
||||
masm.branchTestString(Assembler::NotEqual, R1, &failure);
|
||||
|
||||
GeneralRegisterSet regs(availableGeneralRegs(2));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(2));
|
||||
Register scratchReg = regs.takeAny();
|
||||
|
||||
// Unbox object.
|
||||
@ -4342,7 +4342,7 @@ ICGetElemNativeCompiler::generateStubCode(MacroAssembler &masm)
|
||||
|
||||
masm.branchTestUndefined(Assembler::NotEqual, valAddr, &skipNoSuchMethod);
|
||||
|
||||
GeneralRegisterSet regs = availableGeneralRegs(0);
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
regs.take(R1);
|
||||
regs.take(R0);
|
||||
regs.takeUnchecked(objReg);
|
||||
@ -4445,7 +4445,7 @@ ICGetElem_String::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
masm.branchTestString(Assembler::NotEqual, R0, &failure);
|
||||
masm.branchTestInt32(Assembler::NotEqual, R1, &failure);
|
||||
|
||||
GeneralRegisterSet regs(availableGeneralRegs(2));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(2));
|
||||
Register scratchReg = regs.takeAny();
|
||||
|
||||
// Unbox string in R0.
|
||||
@ -4493,7 +4493,7 @@ ICGetElem_Dense::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
masm.branchTestObject(Assembler::NotEqual, R0, &failure);
|
||||
masm.branchTestInt32(Assembler::NotEqual, R1, &failure);
|
||||
|
||||
GeneralRegisterSet regs(availableGeneralRegs(2));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(2));
|
||||
Register scratchReg = regs.takeAny();
|
||||
|
||||
// Unbox R0 and shape guard.
|
||||
@ -4527,7 +4527,7 @@ ICGetElem_Dense::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
regs.takeUnchecked(obj);
|
||||
regs.takeUnchecked(key);
|
||||
regs.takeUnchecked(BaselineTailCallReg);
|
||||
ValueOperand val = regs.takeValueOperand();
|
||||
ValueOperand val = regs.takeAnyValue();
|
||||
|
||||
masm.loadValue(element, val);
|
||||
masm.branchTestUndefined(Assembler::NotEqual, val, &skipNoSuchMethod);
|
||||
@ -4641,7 +4641,7 @@ ICGetElem_TypedArray::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
|
||||
masm.branchTestObject(Assembler::NotEqual, R0, &failure);
|
||||
|
||||
GeneralRegisterSet regs(availableGeneralRegs(2));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(2));
|
||||
Register scratchReg = regs.takeAny();
|
||||
|
||||
// Unbox R0 and shape guard.
|
||||
@ -4721,7 +4721,7 @@ ICGetElem_Arguments::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
masm.branchTestInt32(Assembler::NotEqual, R1, &failure);
|
||||
Register idx = masm.extractInt32(R1, ExtractTemp1);
|
||||
|
||||
GeneralRegisterSet regs(availableGeneralRegs(2));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(2));
|
||||
Register scratch = regs.takeAny();
|
||||
|
||||
// Load num actual arguments
|
||||
@ -4751,7 +4751,7 @@ ICGetElem_Arguments::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
bool isStrict = which_ == ICGetElem_Arguments::Strict;
|
||||
const Class *clasp = isStrict ? &StrictArgumentsObject::class_ : &NormalArgumentsObject::class_;
|
||||
|
||||
GeneralRegisterSet regs(availableGeneralRegs(2));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(2));
|
||||
Register scratchReg = regs.takeAny();
|
||||
|
||||
// Guard on input being an arguments object.
|
||||
@ -4825,7 +4825,7 @@ ICGetElem_Arguments::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
regs.takeUnchecked(objReg);
|
||||
regs.takeUnchecked(idxReg);
|
||||
regs.takeUnchecked(BaselineTailCallReg);
|
||||
ValueOperand val = regs.takeValueOperand();
|
||||
ValueOperand val = regs.takeAnyValue();
|
||||
|
||||
// Box and push obj and key onto baseline frame stack for decompiler.
|
||||
EmitRestoreTailCallReg(masm);
|
||||
@ -5259,7 +5259,7 @@ ICSetElem_Dense::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
masm.branchTestObject(Assembler::NotEqual, R0, &failure);
|
||||
masm.branchTestInt32(Assembler::NotEqual, R1, &failure);
|
||||
|
||||
GeneralRegisterSet regs(availableGeneralRegs(2));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(2));
|
||||
Register scratchReg = regs.takeAny();
|
||||
|
||||
// Unbox R0 and guard on its shape.
|
||||
@ -5354,7 +5354,7 @@ ICSetElem_Dense::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
regs.add(key);
|
||||
if (cx->runtime()->gc.nursery.exists()) {
|
||||
Register r = regs.takeAny();
|
||||
GeneralRegisterSet saveRegs;
|
||||
LiveGeneralRegisterSet saveRegs;
|
||||
emitPostWriteBarrierSlot(masm, obj, tmpVal, r, saveRegs);
|
||||
regs.add(r);
|
||||
}
|
||||
@ -5425,7 +5425,7 @@ ICSetElemDenseAddCompiler::generateStubCode(MacroAssembler &masm)
|
||||
masm.branchTestObject(Assembler::NotEqual, R0, &failure);
|
||||
masm.branchTestInt32(Assembler::NotEqual, R1, &failure);
|
||||
|
||||
GeneralRegisterSet regs(availableGeneralRegs(2));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(2));
|
||||
Register scratchReg = regs.takeAny();
|
||||
|
||||
// Unbox R0 and guard on its shape.
|
||||
@ -5539,7 +5539,7 @@ ICSetElemDenseAddCompiler::generateStubCode(MacroAssembler &masm)
|
||||
regs.add(key);
|
||||
if (cx->runtime()->gc.nursery.exists()) {
|
||||
Register r = regs.takeAny();
|
||||
GeneralRegisterSet saveRegs;
|
||||
LiveGeneralRegisterSet saveRegs;
|
||||
emitPostWriteBarrierSlot(masm, obj, tmpVal, r, saveRegs);
|
||||
regs.add(r);
|
||||
}
|
||||
@ -5635,7 +5635,7 @@ ICSetElem_TypedArray::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
|
||||
masm.branchTestObject(Assembler::NotEqual, R0, &failure);
|
||||
|
||||
GeneralRegisterSet regs(availableGeneralRegs(2));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(2));
|
||||
Register scratchReg = regs.takeAny();
|
||||
|
||||
// Unbox R0 and shape guard.
|
||||
@ -6154,7 +6154,7 @@ bool
|
||||
ICGetName_Scope<NumHops>::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
Label failure;
|
||||
GeneralRegisterSet regs(availableGeneralRegs(1));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
|
||||
Register obj = R0.scratchReg();
|
||||
Register walker = regs.takeAny();
|
||||
Register scratch = regs.takeAny();
|
||||
@ -7163,7 +7163,7 @@ ICGetProp_Primitive::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
MOZ_CRASH("unexpected type");
|
||||
}
|
||||
|
||||
GeneralRegisterSet regs(availableGeneralRegs(1));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
|
||||
Register holderReg = regs.takeAny();
|
||||
Register scratchReg = regs.takeAny();
|
||||
|
||||
@ -7254,7 +7254,7 @@ bool
|
||||
ICGetPropNativeCompiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
Label failure;
|
||||
GeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
Register objReg = InvalidReg;
|
||||
|
||||
if (inputDefinitelyObject_) {
|
||||
@ -7322,7 +7322,7 @@ ICGetPropNativeCompiler::generateStubCode(MacroAssembler &masm)
|
||||
regs = availableGeneralRegs(0);
|
||||
regs.takeUnchecked(objReg);
|
||||
regs.takeUnchecked(BaselineTailCallReg);
|
||||
ValueOperand val = regs.takeValueOperand();
|
||||
ValueOperand val = regs.takeAnyValue();
|
||||
|
||||
// Box and push obj onto baseline frame stack for decompiler.
|
||||
EmitRestoreTailCallReg(masm);
|
||||
@ -7399,7 +7399,7 @@ ICGetPropNativeDoesNotExistCompiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
Label failure;
|
||||
|
||||
GeneralRegisterSet regs(availableGeneralRegs(1));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
|
||||
Register scratch = regs.takeAny();
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -7449,7 +7449,7 @@ ICGetProp_CallScripted::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
Label failure;
|
||||
Label failureLeaveStubFrame;
|
||||
GeneralRegisterSet regs(availableGeneralRegs(1));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
|
||||
Register scratch = regs.takeAnyExcluding(BaselineTailCallReg);
|
||||
|
||||
// Guard input is an object.
|
||||
@ -7538,7 +7538,7 @@ ICGetProp_CallNative::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
Label failure;
|
||||
|
||||
GeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
Register objReg = InvalidReg;
|
||||
|
||||
MOZ_ASSERT(!(inputDefinitelyObject_ && outerClass_));
|
||||
@ -7611,7 +7611,7 @@ ICGetPropCallDOMProxyNativeCompiler::generateStubCode(MacroAssembler &masm,
|
||||
Address* generationAddr)
|
||||
{
|
||||
Label failure;
|
||||
GeneralRegisterSet regs(availableGeneralRegs(1));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
|
||||
Register scratch = regs.takeAnyExcluding(BaselineTailCallReg);
|
||||
|
||||
// Guard input is an object.
|
||||
@ -7629,7 +7629,7 @@ ICGetPropCallDOMProxyNativeCompiler::generateStubCode(MacroAssembler &masm,
|
||||
|
||||
// Guard that our expando object hasn't started shadowing this property.
|
||||
{
|
||||
GeneralRegisterSet domProxyRegSet(GeneralRegisterSet::All());
|
||||
AllocatableGeneralRegisterSet domProxyRegSet(GeneralRegisterSet::All());
|
||||
domProxyRegSet.take(BaselineStubReg);
|
||||
domProxyRegSet.take(objReg);
|
||||
domProxyRegSet.take(scratch);
|
||||
@ -7752,7 +7752,7 @@ ICGetProp_DOMProxyShadowed::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
Label failure;
|
||||
|
||||
GeneralRegisterSet regs(availableGeneralRegs(1));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
|
||||
// Need to reserve a scratch register, but the scratch register should not be
|
||||
// BaselineTailCallReg, because it's used for |enterStubFrame| which needs a
|
||||
// non-BaselineTailCallReg scratch reg.
|
||||
@ -7904,7 +7904,7 @@ static const VMFunction DoGetPropGenericInfo = FunctionInfo<DoGetPropGenericFn>(
|
||||
bool
|
||||
ICGetProp_Generic::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
GeneralRegisterSet regs(availableGeneralRegs(1));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
|
||||
|
||||
Register scratch = regs.takeAnyExcluding(BaselineTailCallReg);
|
||||
|
||||
@ -7933,7 +7933,7 @@ ICGetProp_Unboxed::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
Label failure;
|
||||
|
||||
GeneralRegisterSet regs(availableGeneralRegs(1));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
|
||||
|
||||
Register scratch = regs.takeAnyExcluding(BaselineTailCallReg);
|
||||
|
||||
@ -7968,7 +7968,7 @@ ICGetProp_TypedObject::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
|
||||
CheckForNeuteredTypedObject(cx, masm, &failure);
|
||||
|
||||
GeneralRegisterSet regs(availableGeneralRegs(1));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
|
||||
|
||||
Register scratch1 = regs.takeAnyExcluding(BaselineTailCallReg);
|
||||
Register scratch2 = regs.takeAnyExcluding(BaselineTailCallReg);
|
||||
@ -8478,7 +8478,7 @@ ICSetProp_Native::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
// Guard input is an object.
|
||||
masm.branchTestObject(Assembler::NotEqual, R0, &failure);
|
||||
|
||||
GeneralRegisterSet regs(availableGeneralRegs(2));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(2));
|
||||
Register scratch = regs.takeAny();
|
||||
|
||||
// Unbox and shape guard.
|
||||
@ -8523,7 +8523,7 @@ ICSetProp_Native::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
regs.add(holderReg);
|
||||
if (cx->runtime()->gc.nursery.exists()) {
|
||||
Register scr = regs.takeAny();
|
||||
GeneralRegisterSet saveRegs;
|
||||
LiveGeneralRegisterSet saveRegs;
|
||||
saveRegs.add(R1);
|
||||
emitPostWriteBarrierSlot(masm, objReg, R1, scr, saveRegs);
|
||||
regs.add(scr);
|
||||
@ -8574,7 +8574,7 @@ ICSetPropNativeAddCompiler::generateStubCode(MacroAssembler &masm)
|
||||
// Guard input is an object.
|
||||
masm.branchTestObject(Assembler::NotEqual, R0, &failure);
|
||||
|
||||
GeneralRegisterSet regs(availableGeneralRegs(2));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(2));
|
||||
Register scratch = regs.takeAny();
|
||||
|
||||
// Unbox and guard against old shape.
|
||||
@ -8667,7 +8667,7 @@ ICSetPropNativeAddCompiler::generateStubCode(MacroAssembler &masm)
|
||||
|
||||
if (cx->runtime()->gc.nursery.exists()) {
|
||||
Register scr = regs.takeAny();
|
||||
GeneralRegisterSet saveRegs;
|
||||
LiveGeneralRegisterSet saveRegs;
|
||||
saveRegs.add(R1);
|
||||
emitPostWriteBarrierSlot(masm, objReg, R1, scr, saveRegs);
|
||||
}
|
||||
@ -8693,7 +8693,7 @@ ICSetProp_Unboxed::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
// Guard input is an object.
|
||||
masm.branchTestObject(Assembler::NotEqual, R0, &failure);
|
||||
|
||||
GeneralRegisterSet regs(availableGeneralRegs(2));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(2));
|
||||
Register scratch = regs.takeAny();
|
||||
|
||||
// Unbox and group guard.
|
||||
@ -8722,7 +8722,7 @@ ICSetProp_Unboxed::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
|
||||
// Trigger post barriers here on the values being written. Fields which
|
||||
// objects can be written to also need update stubs.
|
||||
GeneralRegisterSet saveRegs;
|
||||
LiveGeneralRegisterSet saveRegs;
|
||||
saveRegs.add(R0);
|
||||
saveRegs.add(R1);
|
||||
saveRegs.addUnchecked(object);
|
||||
@ -8764,7 +8764,7 @@ ICSetProp_TypedObject::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
// Guard input is an object.
|
||||
masm.branchTestObject(Assembler::NotEqual, R0, &failure);
|
||||
|
||||
GeneralRegisterSet regs(availableGeneralRegs(2));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(2));
|
||||
Register scratch = regs.takeAny();
|
||||
|
||||
// Unbox and shape guard.
|
||||
@ -8797,7 +8797,7 @@ ICSetProp_TypedObject::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
|
||||
// Trigger post barriers here on the values being written. Descriptors
|
||||
// which can write objects also need update stubs.
|
||||
GeneralRegisterSet saveRegs;
|
||||
LiveGeneralRegisterSet saveRegs;
|
||||
saveRegs.add(R0);
|
||||
saveRegs.add(R1);
|
||||
saveRegs.addUnchecked(object);
|
||||
@ -8889,7 +8889,7 @@ ICSetProp_CallScripted::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
// Stow R0 and R1 to free up registers.
|
||||
EmitStowICValues(masm, 2);
|
||||
|
||||
GeneralRegisterSet regs(availableGeneralRegs(1));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
|
||||
Register scratch = regs.takeAnyExcluding(BaselineTailCallReg);
|
||||
|
||||
// Unbox and shape guard.
|
||||
@ -9008,7 +9008,7 @@ ICSetProp_CallNative::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
// Stow R0 and R1 to free up registers.
|
||||
EmitStowICValues(masm, 2);
|
||||
|
||||
GeneralRegisterSet regs(availableGeneralRegs(1));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
|
||||
Register scratch = regs.takeAnyExcluding(BaselineTailCallReg);
|
||||
|
||||
// Unbox and shape guard.
|
||||
@ -9716,7 +9716,7 @@ DoSpreadCallFallback(JSContext *cx, BaselineFrame *frame, ICCall_Fallback *stub_
|
||||
}
|
||||
|
||||
void
|
||||
ICCallStubCompiler::pushCallArguments(MacroAssembler &masm, GeneralRegisterSet regs,
|
||||
ICCallStubCompiler::pushCallArguments(MacroAssembler &masm, AllocatableGeneralRegisterSet regs,
|
||||
Register argcReg, bool isJitCall)
|
||||
{
|
||||
MOZ_ASSERT(!regs.has(argcReg));
|
||||
@ -9769,7 +9769,8 @@ ICCallStubCompiler::guardSpreadCall(MacroAssembler &masm, Register argcReg, Labe
|
||||
}
|
||||
|
||||
void
|
||||
ICCallStubCompiler::pushSpreadCallArguments(MacroAssembler &masm, GeneralRegisterSet regs,
|
||||
ICCallStubCompiler::pushSpreadCallArguments(MacroAssembler &masm,
|
||||
AllocatableGeneralRegisterSet regs,
|
||||
Register argcReg, bool isJitCall)
|
||||
{
|
||||
// Push arguments
|
||||
@ -9806,8 +9807,9 @@ ICCallStubCompiler::pushSpreadCallArguments(MacroAssembler &masm, GeneralRegiste
|
||||
}
|
||||
|
||||
Register
|
||||
ICCallStubCompiler::guardFunApply(MacroAssembler &masm, GeneralRegisterSet regs, Register argcReg,
|
||||
bool checkNative, FunApplyThing applyThing, Label *failure)
|
||||
ICCallStubCompiler::guardFunApply(MacroAssembler &masm, AllocatableGeneralRegisterSet regs,
|
||||
Register argcReg, bool checkNative, FunApplyThing applyThing,
|
||||
Label *failure)
|
||||
{
|
||||
// Ensure argc == 2
|
||||
masm.branch32(Assembler::NotEqual, argcReg, Imm32(2), failure);
|
||||
@ -9828,7 +9830,7 @@ ICCallStubCompiler::guardFunApply(MacroAssembler &masm, GeneralRegisterSet regs,
|
||||
} else {
|
||||
MOZ_ASSERT(applyThing == FunApply_Array);
|
||||
|
||||
GeneralRegisterSet regsx = regs;
|
||||
AllocatableGeneralRegisterSet regsx = regs;
|
||||
|
||||
// Ensure that the second arg is an array.
|
||||
ValueOperand secondArgVal = regsx.takeAnyValue();
|
||||
@ -9920,7 +9922,7 @@ ICCallStubCompiler::guardFunApply(MacroAssembler &masm, GeneralRegisterSet regs,
|
||||
}
|
||||
|
||||
void
|
||||
ICCallStubCompiler::pushCallerArguments(MacroAssembler &masm, GeneralRegisterSet regs)
|
||||
ICCallStubCompiler::pushCallerArguments(MacroAssembler &masm, AllocatableGeneralRegisterSet regs)
|
||||
{
|
||||
// Initialize copyReg to point to start caller arguments vector.
|
||||
// Initialize argcReg to poitn to the end of it.
|
||||
@ -9946,7 +9948,7 @@ ICCallStubCompiler::pushCallerArguments(MacroAssembler &masm, GeneralRegisterSet
|
||||
|
||||
void
|
||||
ICCallStubCompiler::pushArrayArguments(MacroAssembler &masm, Address arrayVal,
|
||||
GeneralRegisterSet regs)
|
||||
AllocatableGeneralRegisterSet regs)
|
||||
{
|
||||
// Load start and end address of values to copy.
|
||||
// guardFunApply has already gauranteed that the array is packed and contains
|
||||
@ -9992,7 +9994,7 @@ ICCall_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
// right-to-left so duplicate them on the stack in reverse order.
|
||||
// |this| and callee are pushed last.
|
||||
|
||||
GeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
|
||||
if (MOZ_UNLIKELY(isSpread_)) {
|
||||
// Use BaselineFrameReg instead of BaselineStackReg, because
|
||||
@ -10098,7 +10100,7 @@ bool
|
||||
ICCallScriptedCompiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
Label failure;
|
||||
GeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
bool canUseTailCallReg = regs.has(BaselineTailCallReg);
|
||||
|
||||
Register argcReg = R0.scratchReg();
|
||||
@ -10363,7 +10365,7 @@ bool
|
||||
ICCall_StringSplit::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
// Stack Layout: [ ..., CalleeVal, ThisVal, Arg0Val, +ICStackValueOffset+ ]
|
||||
GeneralRegisterSet regs = availableGeneralRegs(0);
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
Label failureRestoreArgc;
|
||||
#ifdef DEBUG
|
||||
Label oneArg;
|
||||
@ -10457,7 +10459,7 @@ ICCall_IsSuspendedStarGenerator::Compiler::generateStubCode(MacroAssembler &masm
|
||||
// code, so it's safe to assume we have a single argument and the callee
|
||||
// is our intrinsic.
|
||||
|
||||
GeneralRegisterSet regs = availableGeneralRegs(0);
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
|
||||
// Load the argument.
|
||||
Address argAddr(BaselineStackReg, ICStackValueOffset);
|
||||
@ -10496,7 +10498,7 @@ bool
|
||||
ICCall_Native::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
Label failure;
|
||||
GeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
|
||||
Register argcReg = R0.scratchReg();
|
||||
regs.take(argcReg);
|
||||
@ -10600,7 +10602,7 @@ bool
|
||||
ICCall_ClassHook::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
Label failure;
|
||||
GeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
|
||||
Register argcReg = R0.scratchReg();
|
||||
regs.take(argcReg);
|
||||
@ -10687,7 +10689,7 @@ bool
|
||||
ICCall_ScriptedApplyArray::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
Label failure;
|
||||
GeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
|
||||
Register argcReg = R0.scratchReg();
|
||||
regs.take(argcReg);
|
||||
@ -10789,7 +10791,7 @@ bool
|
||||
ICCall_ScriptedApplyArguments::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
Label failure;
|
||||
GeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
|
||||
Register argcReg = R0.scratchReg();
|
||||
regs.take(argcReg);
|
||||
@ -10885,7 +10887,7 @@ bool
|
||||
ICCall_ScriptedFunCall::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
Label failure;
|
||||
GeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
bool canUseTailCallReg = regs.has(BaselineTailCallReg);
|
||||
|
||||
Register argcReg = R0.scratchReg();
|
||||
@ -11219,7 +11221,7 @@ ICIteratorMore_Native::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
|
||||
Register obj = masm.extractObject(R0, ExtractTemp0);
|
||||
|
||||
GeneralRegisterSet regs(availableGeneralRegs(1));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
|
||||
Register nativeIterator = regs.takeAny();
|
||||
Register scratch = regs.takeAny();
|
||||
|
||||
@ -11393,7 +11395,7 @@ ICInstanceOf_Function::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
// Allow using R1's type register as scratch. We have to restore it when
|
||||
// we want to jump to the next stub.
|
||||
Label failureRestoreR1;
|
||||
GeneralRegisterSet regs(availableGeneralRegs(1));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
|
||||
regs.takeUnchecked(rhsObj);
|
||||
|
||||
Register scratch1 = regs.takeAny();
|
||||
@ -11587,7 +11589,7 @@ ICRetSub_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
masm.branchTestBooleanTruthy(true, R0, &rethrow);
|
||||
{
|
||||
// Call a stub to get the native code address for the pc offset in R1.
|
||||
GeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
regs.take(R1);
|
||||
regs.takeUnchecked(BaselineTailCallReg);
|
||||
|
||||
|
@ -1127,8 +1127,8 @@ class ICStubCompiler
|
||||
// given label.
|
||||
void guardProfilingEnabled(MacroAssembler &masm, Register scratch, Label *skip);
|
||||
|
||||
inline GeneralRegisterSet availableGeneralRegs(size_t numInputs) const {
|
||||
GeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
inline AllocatableGeneralRegisterSet availableGeneralRegs(size_t numInputs) const {
|
||||
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
MOZ_ASSERT(!regs.has(BaselineStackReg));
|
||||
#if defined(JS_CODEGEN_ARM)
|
||||
MOZ_ASSERT(!regs.has(BaselineTailCallReg));
|
||||
@ -1162,7 +1162,7 @@ class ICStubCompiler
|
||||
}
|
||||
|
||||
inline bool emitPostWriteBarrierSlot(MacroAssembler &masm, Register obj, ValueOperand val,
|
||||
Register scratch, GeneralRegisterSet saveRegs);
|
||||
Register scratch, LiveGeneralRegisterSet saveRegs);
|
||||
|
||||
public:
|
||||
virtual ICStub *getStub(ICStubSpace *space) = 0;
|
||||
@ -5253,15 +5253,17 @@ class ICCallStubCompiler : public ICStubCompiler
|
||||
FunApply_Array
|
||||
};
|
||||
|
||||
void pushCallArguments(MacroAssembler &masm, GeneralRegisterSet regs, Register argcReg,
|
||||
bool isJitCall);
|
||||
void pushSpreadCallArguments(MacroAssembler &masm, GeneralRegisterSet regs, Register argcReg,
|
||||
bool isJitCall);
|
||||
void pushCallArguments(MacroAssembler &masm, AllocatableGeneralRegisterSet regs,
|
||||
Register argcReg, bool isJitCall);
|
||||
void pushSpreadCallArguments(MacroAssembler &masm, AllocatableGeneralRegisterSet regs,
|
||||
Register argcReg, bool isJitCall);
|
||||
void guardSpreadCall(MacroAssembler &masm, Register argcReg, Label *failure);
|
||||
Register guardFunApply(MacroAssembler &masm, GeneralRegisterSet regs, Register argcReg,
|
||||
bool checkNative, FunApplyThing applyThing, Label *failure);
|
||||
void pushCallerArguments(MacroAssembler &masm, GeneralRegisterSet regs);
|
||||
void pushArrayArguments(MacroAssembler &masm, Address arrayVal, GeneralRegisterSet regs);
|
||||
Register guardFunApply(MacroAssembler &masm, AllocatableGeneralRegisterSet regs,
|
||||
Register argcReg, bool checkNative, FunApplyThing applyThing,
|
||||
Label *failure);
|
||||
void pushCallerArguments(MacroAssembler &masm, AllocatableGeneralRegisterSet regs);
|
||||
void pushArrayArguments(MacroAssembler &masm, Address arrayVal,
|
||||
AllocatableGeneralRegisterSet regs);
|
||||
};
|
||||
|
||||
class ICCall_Fallback : public ICMonitoredFallbackStub
|
||||
|
@ -1138,7 +1138,7 @@ PrepareAndExecuteRegExp(JSContext *cx, MacroAssembler &masm, Register regexp, Re
|
||||
masm.store32(Imm32(0), matchResultAddress);
|
||||
|
||||
// Save any volatile inputs.
|
||||
GeneralRegisterSet volatileRegs;
|
||||
LiveGeneralRegisterSet volatileRegs;
|
||||
if (input.volatile_())
|
||||
volatileRegs.add(input);
|
||||
if (regexp.volatile_())
|
||||
@ -1313,7 +1313,7 @@ JitCompartment::generateRegExpExecStub(JSContext *cx)
|
||||
ValueOperand result = JSReturnOperand;
|
||||
|
||||
// We are free to clobber all registers, as LRegExpExec is a call instruction.
|
||||
GeneralRegisterSet regs = GeneralRegisterSet::All();
|
||||
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
regs.take(input);
|
||||
regs.take(regexp);
|
||||
|
||||
@ -1322,7 +1322,7 @@ JitCompartment::generateRegExpExecStub(JSContext *cx)
|
||||
// platforms.
|
||||
Register temp5;
|
||||
{
|
||||
GeneralRegisterSet oregs = regs;
|
||||
AllocatableGeneralRegisterSet oregs = regs;
|
||||
do {
|
||||
temp5 = oregs.takeAny();
|
||||
} while (!MacroAssembler::canUseInSingleByteInstruction(temp5));
|
||||
@ -1481,7 +1481,7 @@ CodeGenerator::visitOutOfLineRegExpExec(OutOfLineRegExpExec *ool)
|
||||
Register input = ToRegister(lir->string());
|
||||
Register regexp = ToRegister(lir->regexp());
|
||||
|
||||
GeneralRegisterSet regs = GeneralRegisterSet::All();
|
||||
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
regs.take(input);
|
||||
regs.take(regexp);
|
||||
Register temp = regs.takeAny();
|
||||
@ -1530,7 +1530,7 @@ JitCompartment::generateRegExpTestStub(JSContext *cx)
|
||||
MOZ_ASSERT(regexp != result && input != result);
|
||||
|
||||
// We are free to clobber all registers, as LRegExpTest is a call instruction.
|
||||
GeneralRegisterSet regs = GeneralRegisterSet::All();
|
||||
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
regs.take(input);
|
||||
regs.take(regexp);
|
||||
Register temp1 = regs.takeAny();
|
||||
@ -2656,7 +2656,7 @@ CodeGenerator::visitOutOfLineCallPostWriteBarrier(OutOfLineCallPostWriteBarrier
|
||||
|
||||
const LAllocation *obj = ool->object();
|
||||
|
||||
GeneralRegisterSet regs = GeneralRegisterSet::Volatile();
|
||||
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::Volatile());
|
||||
|
||||
Register objreg;
|
||||
bool isGlobal = false;
|
||||
@ -3768,7 +3768,7 @@ CodeGenerator::emitAssertObjectOrStringResult(Register input, MIRType type, Temp
|
||||
MOZ_ASSERT(type == MIRType_Object || type == MIRType_ObjectOrNull ||
|
||||
type == MIRType_String || type == MIRType_Symbol);
|
||||
|
||||
GeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
regs.take(input);
|
||||
|
||||
Register temp = regs.takeAny();
|
||||
@ -3835,7 +3835,7 @@ CodeGenerator::emitAssertObjectOrStringResult(Register input, MIRType type, Temp
|
||||
void
|
||||
CodeGenerator::emitAssertResultV(const ValueOperand input, TemporaryTypeSet *typeset)
|
||||
{
|
||||
GeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
regs.take(input);
|
||||
|
||||
Register temp1 = regs.takeAny();
|
||||
@ -6094,16 +6094,16 @@ JitRuntime::generateMallocStub(JSContext *cx)
|
||||
|
||||
MacroAssembler masm(cx);
|
||||
|
||||
RegisterSet regs = RegisterSet::Volatile();
|
||||
AllocatableRegisterSet regs(RegisterSet::Volatile());
|
||||
#ifdef JS_USE_LINK_REGISTER
|
||||
masm.pushReturnAddress();
|
||||
#endif
|
||||
regs.takeUnchecked(regNBytes);
|
||||
masm.PushRegsInMask(regs);
|
||||
LiveRegisterSet save(regs.asLiveSet());
|
||||
masm.PushRegsInMask(save);
|
||||
|
||||
const Register regTemp = regs.takeGeneral();
|
||||
const Register regTemp = regs.takeAnyGeneral();
|
||||
const Register regRuntime = regTemp;
|
||||
regs.add(regTemp);
|
||||
MOZ_ASSERT(regTemp != regNBytes);
|
||||
|
||||
masm.setupUnalignedABICall(2, regTemp);
|
||||
@ -6113,7 +6113,7 @@ JitRuntime::generateMallocStub(JSContext *cx)
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, MallocWrapper));
|
||||
masm.storeCallResult(regReturn);
|
||||
|
||||
masm.PopRegsInMask(regs);
|
||||
masm.PopRegsInMask(save);
|
||||
masm.ret();
|
||||
|
||||
Linker linker(masm);
|
||||
@ -6136,19 +6136,19 @@ JitRuntime::generateFreeStub(JSContext *cx)
|
||||
#ifdef JS_USE_LINK_REGISTER
|
||||
masm.pushReturnAddress();
|
||||
#endif
|
||||
RegisterSet regs = RegisterSet::Volatile();
|
||||
AllocatableRegisterSet regs(RegisterSet::Volatile());
|
||||
regs.takeUnchecked(regSlots);
|
||||
masm.PushRegsInMask(regs);
|
||||
LiveRegisterSet save(regs.asLiveSet());
|
||||
masm.PushRegsInMask(save);
|
||||
|
||||
const Register regTemp = regs.takeGeneral();
|
||||
regs.add(regTemp);
|
||||
const Register regTemp = regs.takeAnyGeneral();
|
||||
MOZ_ASSERT(regTemp != regSlots);
|
||||
|
||||
masm.setupUnalignedABICall(1, regTemp);
|
||||
masm.passABIArg(regSlots);
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, js_free));
|
||||
|
||||
masm.PopRegsInMask(regs);
|
||||
masm.PopRegsInMask(save);
|
||||
|
||||
masm.ret();
|
||||
|
||||
@ -6172,7 +6172,7 @@ JitRuntime::generateLazyLinkStub(JSContext *cx)
|
||||
masm.pushReturnAddress();
|
||||
#endif
|
||||
|
||||
GeneralRegisterSet regs = GeneralRegisterSet::Volatile();
|
||||
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::Volatile());
|
||||
Register temp0 = regs.takeAny();
|
||||
|
||||
// The caller did not push an exit frame on the stack, it pushed a
|
||||
@ -6820,7 +6820,7 @@ CodeGenerator::emitArrayPopShift(LInstruction *lir, const MArrayPopShift *mir, R
|
||||
|
||||
if (mir->mode() == MArrayPopShift::Shift) {
|
||||
// Don't save the temp registers.
|
||||
RegisterSet temps;
|
||||
LiveRegisterSet temps;
|
||||
temps.add(elementsTemp);
|
||||
temps.add(lengthTemp);
|
||||
|
||||
@ -7899,7 +7899,7 @@ CodeGenerator::visitStoreFixedSlotT(LStoreFixedSlotT *ins)
|
||||
void
|
||||
CodeGenerator::visitGetNameCache(LGetNameCache *ins)
|
||||
{
|
||||
RegisterSet liveRegs = ins->safepoint()->liveRegs();
|
||||
LiveRegisterSet liveRegs = ins->safepoint()->liveRegs();
|
||||
Register scopeChain = ToRegister(ins->scopeObj());
|
||||
TypedOrValueRegister output(GetValueOutput(ins));
|
||||
bool isTypeOf = ins->mir()->accessKind() != MGetNameCache::NAME;
|
||||
@ -7929,7 +7929,7 @@ CodeGenerator::visitNameIC(OutOfLineUpdateCache *ool, DataPtr<NameIC> &ic)
|
||||
}
|
||||
|
||||
void
|
||||
CodeGenerator::addGetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Register objReg,
|
||||
CodeGenerator::addGetPropertyCache(LInstruction *ins, LiveRegisterSet liveRegs, Register objReg,
|
||||
PropertyName *name, TypedOrValueRegister output,
|
||||
bool monitoredResult, jsbytecode *profilerLeavePc)
|
||||
{
|
||||
@ -7939,7 +7939,7 @@ CodeGenerator::addGetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Regi
|
||||
}
|
||||
|
||||
void
|
||||
CodeGenerator::addSetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Register objReg,
|
||||
CodeGenerator::addSetPropertyCache(LInstruction *ins, LiveRegisterSet liveRegs, Register objReg,
|
||||
PropertyName *name, ConstantOrRegister value, bool strict,
|
||||
bool needsTypeBarrier, jsbytecode *profilerLeavePc)
|
||||
{
|
||||
@ -7964,7 +7964,7 @@ CodeGenerator::addSetElementCache(LInstruction *ins, Register obj, Register unbo
|
||||
void
|
||||
CodeGenerator::visitGetPropertyCacheV(LGetPropertyCacheV *ins)
|
||||
{
|
||||
RegisterSet liveRegs = ins->safepoint()->liveRegs();
|
||||
LiveRegisterSet liveRegs = ins->safepoint()->liveRegs();
|
||||
Register objReg = ToRegister(ins->getOperand(0));
|
||||
PropertyName *name = ins->mir()->name();
|
||||
bool monitoredResult = ins->mir()->monitoredResult();
|
||||
@ -7977,7 +7977,7 @@ CodeGenerator::visitGetPropertyCacheV(LGetPropertyCacheV *ins)
|
||||
void
|
||||
CodeGenerator::visitGetPropertyCacheT(LGetPropertyCacheT *ins)
|
||||
{
|
||||
RegisterSet liveRegs = ins->safepoint()->liveRegs();
|
||||
LiveRegisterSet liveRegs = ins->safepoint()->liveRegs();
|
||||
Register objReg = ToRegister(ins->getOperand(0));
|
||||
PropertyName *name = ins->mir()->name();
|
||||
bool monitoredResult = ins->mir()->monitoredResult();
|
||||
@ -8020,7 +8020,7 @@ CodeGenerator::addGetElementCache(LInstruction *ins, Register obj, ConstantOrReg
|
||||
TypedOrValueRegister output, bool monitoredResult,
|
||||
bool allowDoubleResult, jsbytecode *profilerLeavePc)
|
||||
{
|
||||
RegisterSet liveRegs = ins->safepoint()->liveRegs();
|
||||
LiveRegisterSet liveRegs = ins->safepoint()->liveRegs();
|
||||
GetElementIC cache(liveRegs, obj, index, output, monitoredResult, allowDoubleResult);
|
||||
cache.setProfilerLeavePC(profilerLeavePc);
|
||||
addCache(ins, allocateCache(cache));
|
||||
@ -8219,7 +8219,7 @@ CodeGenerator::visitCallDeleteElement(LCallDeleteElement *lir)
|
||||
void
|
||||
CodeGenerator::visitSetPropertyCacheV(LSetPropertyCacheV *ins)
|
||||
{
|
||||
RegisterSet liveRegs = ins->safepoint()->liveRegs();
|
||||
LiveRegisterSet liveRegs = ins->safepoint()->liveRegs();
|
||||
Register objReg = ToRegister(ins->getOperand(0));
|
||||
ConstantOrRegister value = TypedOrValueRegister(ToValue(ins, LSetPropertyCacheV::Value));
|
||||
|
||||
@ -8231,7 +8231,7 @@ CodeGenerator::visitSetPropertyCacheV(LSetPropertyCacheV *ins)
|
||||
void
|
||||
CodeGenerator::visitSetPropertyCacheT(LSetPropertyCacheT *ins)
|
||||
{
|
||||
RegisterSet liveRegs = ins->safepoint()->liveRegs();
|
||||
LiveRegisterSet liveRegs = ins->safepoint()->liveRegs();
|
||||
Register objReg = ToRegister(ins->getOperand(0));
|
||||
ConstantOrRegister value;
|
||||
|
||||
|
@ -373,13 +373,13 @@ class CodeGenerator : public CodeGeneratorSpecific
|
||||
}
|
||||
|
||||
private:
|
||||
void addGetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Register objReg,
|
||||
void addGetPropertyCache(LInstruction *ins, LiveRegisterSet liveRegs, Register objReg,
|
||||
PropertyName *name, TypedOrValueRegister output,
|
||||
bool monitoredResult, jsbytecode *profilerLeavePc);
|
||||
void addGetElementCache(LInstruction *ins, Register obj, ConstantOrRegister index,
|
||||
TypedOrValueRegister output, bool monitoredResult,
|
||||
bool allowDoubleResult, jsbytecode *profilerLeavePc);
|
||||
void addSetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Register objReg,
|
||||
void addSetPropertyCache(LInstruction *ins, LiveRegisterSet liveRegs, Register objReg,
|
||||
PropertyName *name, ConstantOrRegister value, bool strict,
|
||||
bool needsTypeBarrier, jsbytecode *profilerLeavePc);
|
||||
void addSetElementCache(LInstruction *ins, Register obj, Register unboxIndex, Register temp,
|
||||
|
@ -764,9 +764,9 @@ CheckDOMProxyExpandoDoesNotShadow(JSContext *cx, MacroAssembler &masm, JSObject
|
||||
|
||||
// For the remaining code, we need to reserve some registers to load a value.
|
||||
// This is ugly, but unvaoidable.
|
||||
RegisterSet domProxyRegSet(RegisterSet::All());
|
||||
AllocatableRegisterSet domProxyRegSet(RegisterSet::All());
|
||||
domProxyRegSet.take(AnyRegister(object));
|
||||
ValueOperand tempVal = domProxyRegSet.takeValueOperand();
|
||||
ValueOperand tempVal = domProxyRegSet.takeAnyValue();
|
||||
masm.pushValue(tempVal);
|
||||
|
||||
Label failDOMProxyCheck;
|
||||
@ -963,7 +963,7 @@ static bool
|
||||
EmitGetterCall(JSContext *cx, MacroAssembler &masm,
|
||||
IonCache::StubAttacher &attacher, JSObject *obj,
|
||||
JSObject *holder, HandleShape shape,
|
||||
RegisterSet liveRegs, Register object,
|
||||
LiveRegisterSet liveRegs, Register object,
|
||||
TypedOrValueRegister output,
|
||||
void *returnAddr)
|
||||
{
|
||||
@ -972,20 +972,20 @@ EmitGetterCall(JSContext *cx, MacroAssembler &masm,
|
||||
|
||||
// Remaining registers should basically be free, but we need to use |object| still
|
||||
// so leave it alone.
|
||||
RegisterSet regSet(RegisterSet::All());
|
||||
AllocatableRegisterSet regSet(RegisterSet::All());
|
||||
regSet.take(AnyRegister(object));
|
||||
|
||||
// This is a slower stub path, and we're going to be doing a call anyway. Don't need
|
||||
// to try so hard to not use the stack. Scratch regs are just taken from the register
|
||||
// set not including the input, current value saved on the stack, and restored when
|
||||
// we're done with it.
|
||||
Register scratchReg = regSet.takeGeneral();
|
||||
Register scratchReg = regSet.takeAnyGeneral();
|
||||
|
||||
// Shape has a JSNative, PropertyOp or scripted getter function.
|
||||
if (IsCacheableGetPropCallNative(obj, holder, shape)) {
|
||||
Register argJSContextReg = regSet.takeGeneral();
|
||||
Register argUintNReg = regSet.takeGeneral();
|
||||
Register argVpReg = regSet.takeGeneral();
|
||||
Register argJSContextReg = regSet.takeAnyGeneral();
|
||||
Register argUintNReg = regSet.takeAnyGeneral();
|
||||
Register argVpReg = regSet.takeAnyGeneral();
|
||||
|
||||
JSFunction *target = &shape->getterValue().toObject().as<JSFunction>();
|
||||
MOZ_ASSERT(target);
|
||||
@ -1032,11 +1032,11 @@ EmitGetterCall(JSContext *cx, MacroAssembler &masm,
|
||||
// masm.leaveExitFrame & pop locals
|
||||
masm.adjustStack(IonOOLNativeExitFrameLayout::Size(0));
|
||||
} else if (IsCacheableGetPropCallPropertyOp(obj, holder, shape)) {
|
||||
Register argJSContextReg = regSet.takeGeneral();
|
||||
Register argUintNReg = regSet.takeGeneral();
|
||||
Register argVpReg = regSet.takeGeneral();
|
||||
Register argJSContextReg = regSet.takeAnyGeneral();
|
||||
Register argUintNReg = regSet.takeAnyGeneral();
|
||||
Register argVpReg = regSet.takeAnyGeneral();
|
||||
Register argObjReg = argUintNReg;
|
||||
Register argIdReg = regSet.takeGeneral();
|
||||
Register argIdReg = regSet.takeAnyGeneral();
|
||||
|
||||
GetterOp target = shape->getterOp();
|
||||
MOZ_ASSERT(target);
|
||||
@ -1134,7 +1134,7 @@ EmitGetterCall(JSContext *cx, MacroAssembler &masm,
|
||||
static bool
|
||||
GenerateCallGetter(JSContext *cx, IonScript *ion, MacroAssembler &masm,
|
||||
IonCache::StubAttacher &attacher, JSObject *obj, PropertyName *name,
|
||||
JSObject *holder, HandleShape shape, RegisterSet &liveRegs, Register object,
|
||||
JSObject *holder, HandleShape shape, LiveRegisterSet &liveRegs, Register object,
|
||||
TypedOrValueRegister output, void *returnAddr, Label *failures = nullptr)
|
||||
{
|
||||
MOZ_ASSERT(output.hasValue());
|
||||
@ -1526,7 +1526,7 @@ PushObjectOpResult(MacroAssembler &masm)
|
||||
|
||||
static bool
|
||||
EmitCallProxyGet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &attacher,
|
||||
PropertyName *name, RegisterSet liveRegs, Register object,
|
||||
PropertyName *name, LiveRegisterSet liveRegs, Register object,
|
||||
TypedOrValueRegister output, jsbytecode *pc, void *returnAddr)
|
||||
{
|
||||
MOZ_ASSERT(output.hasValue());
|
||||
@ -1534,17 +1534,17 @@ EmitCallProxyGet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &at
|
||||
|
||||
// Remaining registers should be free, but we need to use |object| still
|
||||
// so leave it alone.
|
||||
RegisterSet regSet(RegisterSet::All());
|
||||
AllocatableRegisterSet regSet(RegisterSet::All());
|
||||
regSet.take(AnyRegister(object));
|
||||
|
||||
// Proxy::get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
// MutableHandleValue vp)
|
||||
Register argJSContextReg = regSet.takeGeneral();
|
||||
Register argProxyReg = regSet.takeGeneral();
|
||||
Register argIdReg = regSet.takeGeneral();
|
||||
Register argVpReg = regSet.takeGeneral();
|
||||
Register argJSContextReg = regSet.takeAnyGeneral();
|
||||
Register argProxyReg = regSet.takeAnyGeneral();
|
||||
Register argIdReg = regSet.takeAnyGeneral();
|
||||
Register argVpReg = regSet.takeAnyGeneral();
|
||||
|
||||
Register scratch = regSet.takeGeneral();
|
||||
Register scratch = regSet.takeAnyGeneral();
|
||||
|
||||
void *getFunction = JSOp(*pc) == JSOP_CALLPROP ?
|
||||
JS_FUNC_TO_DATA_PTR(void *, Proxy::callProp) :
|
||||
@ -2228,7 +2228,7 @@ ProxySetProperty(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v,
|
||||
|
||||
static bool
|
||||
EmitCallProxySet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &attacher,
|
||||
HandleId propId, RegisterSet liveRegs, Register object,
|
||||
HandleId propId, LiveRegisterSet liveRegs, Register object,
|
||||
ConstantOrRegister value, void *returnAddr, bool strict)
|
||||
{
|
||||
MacroAssembler::AfterICSaveLive aic = masm.icSaveLive(liveRegs);
|
||||
@ -2240,18 +2240,18 @@ EmitCallProxySet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &at
|
||||
// regSet is going to re-allocate it. Hence the emitted code must not touch
|
||||
// any of the registers allocated from regSet until after the last use of
|
||||
// |value|. (We can't afford to take it, either, because x86.)
|
||||
RegisterSet regSet(RegisterSet::All());
|
||||
AllocatableRegisterSet regSet(RegisterSet::All());
|
||||
regSet.take(AnyRegister(object));
|
||||
|
||||
// ProxySetProperty(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v,
|
||||
// bool strict);
|
||||
Register argJSContextReg = regSet.takeGeneral();
|
||||
Register argProxyReg = regSet.takeGeneral();
|
||||
Register argIdReg = regSet.takeGeneral();
|
||||
Register argValueReg = regSet.takeGeneral();
|
||||
Register argStrictReg = regSet.takeGeneral();
|
||||
Register argJSContextReg = regSet.takeAnyGeneral();
|
||||
Register argProxyReg = regSet.takeAnyGeneral();
|
||||
Register argIdReg = regSet.takeAnyGeneral();
|
||||
Register argValueReg = regSet.takeAnyGeneral();
|
||||
Register argStrictReg = regSet.takeAnyGeneral();
|
||||
|
||||
Register scratch = regSet.takeGeneral();
|
||||
Register scratch = regSet.takeAnyGeneral();
|
||||
|
||||
// Push stubCode for marking.
|
||||
attacher.pushStubCodePointer(masm);
|
||||
@ -2311,12 +2311,12 @@ SetPropertyIC::attachGenericProxy(JSContext *cx, HandleScript outerScript, IonSc
|
||||
Label proxyFailures;
|
||||
Label proxySuccess;
|
||||
|
||||
RegisterSet regSet(RegisterSet::All());
|
||||
AllocatableRegisterSet regSet(RegisterSet::All());
|
||||
regSet.take(AnyRegister(object()));
|
||||
if (!value().constant())
|
||||
regSet.takeUnchecked(value().reg());
|
||||
|
||||
Register scratch = regSet.takeGeneral();
|
||||
Register scratch = regSet.takeAnyGeneral();
|
||||
masm.push(scratch);
|
||||
|
||||
masm.branchTestObjectIsProxy(false, object(), scratch, &proxyFailures);
|
||||
@ -2393,17 +2393,17 @@ static bool
|
||||
GenerateCallSetter(JSContext *cx, IonScript *ion, MacroAssembler &masm,
|
||||
IonCache::StubAttacher &attacher, HandleObject obj,
|
||||
HandleObject holder, HandleShape shape, bool strict, Register object,
|
||||
ConstantOrRegister value, Label *failure, RegisterSet liveRegs,
|
||||
ConstantOrRegister value, Label *failure, LiveRegisterSet liveRegs,
|
||||
void *returnAddr)
|
||||
{
|
||||
// Generate prototype guards if needed.
|
||||
// Take a scratch register for use, save on stack.
|
||||
{
|
||||
RegisterSet regSet(RegisterSet::All());
|
||||
AllocatableRegisterSet regSet(RegisterSet::All());
|
||||
regSet.take(AnyRegister(object));
|
||||
if (!value.constant())
|
||||
regSet.takeUnchecked(value.reg());
|
||||
Register scratchReg = regSet.takeGeneral();
|
||||
Register scratchReg = regSet.takeAnyGeneral();
|
||||
masm.push(scratchReg);
|
||||
|
||||
Label protoFailure;
|
||||
@ -2435,7 +2435,7 @@ GenerateCallSetter(JSContext *cx, IonScript *ion, MacroAssembler &masm,
|
||||
|
||||
// Remaining registers should basically be free, but we need to use |object| still
|
||||
// so leave it alone. And of course we need our value, if it's not a constant.
|
||||
RegisterSet regSet(RegisterSet::All());
|
||||
AllocatableRegisterSet regSet(RegisterSet::All());
|
||||
regSet.take(AnyRegister(object));
|
||||
if (!value.constant())
|
||||
regSet.takeUnchecked(value.reg());
|
||||
@ -2447,11 +2447,11 @@ GenerateCallSetter(JSContext *cx, IonScript *ion, MacroAssembler &masm,
|
||||
//
|
||||
// Be very careful not to use any of these before value is pushed, since they
|
||||
// might shadow.
|
||||
Register scratchReg = regSet.takeGeneral();
|
||||
Register scratchReg = regSet.takeAnyGeneral();
|
||||
|
||||
if (IsCacheableSetPropCallNative(obj, holder, shape)) {
|
||||
Register argJSContextReg = regSet.takeGeneral();
|
||||
Register argVpReg = regSet.takeGeneral();
|
||||
Register argJSContextReg = regSet.takeAnyGeneral();
|
||||
Register argVpReg = regSet.takeAnyGeneral();
|
||||
|
||||
MOZ_ASSERT(shape->hasSetterValue() && shape->setterObject() &&
|
||||
shape->setterObject()->is<JSFunction>());
|
||||
@ -2459,7 +2459,7 @@ GenerateCallSetter(JSContext *cx, IonScript *ion, MacroAssembler &masm,
|
||||
|
||||
MOZ_ASSERT(target->isNative());
|
||||
|
||||
Register argUintNReg = regSet.takeGeneral();
|
||||
Register argUintNReg = regSet.takeAnyGeneral();
|
||||
|
||||
// Set up the call:
|
||||
// bool (*)(JSContext *, unsigned, Value *vp)
|
||||
@ -2502,7 +2502,8 @@ GenerateCallSetter(JSContext *cx, IonScript *ion, MacroAssembler &masm,
|
||||
// for the value, one for scratch, 5 for the arguments, which makes 8,
|
||||
// but we only have 7 to work with. So only grab the ones we need
|
||||
// before we push value and release its reg back into the set.
|
||||
Register argResultReg = regSet.takeGeneral();
|
||||
Register argResultReg = regSet.takeAnyGeneral();
|
||||
|
||||
|
||||
SetterOp target = shape->setterOp();
|
||||
MOZ_ASSERT(target);
|
||||
@ -2528,11 +2529,11 @@ GenerateCallSetter(JSContext *cx, IonScript *ion, MacroAssembler &masm,
|
||||
|
||||
// OK, now we can grab our remaining registers and grab the pointer to
|
||||
// what we just pushed into one of them.
|
||||
Register argJSContextReg = regSet.takeGeneral();
|
||||
Register argValueReg = regSet.takeGeneral();
|
||||
Register argJSContextReg = regSet.takeAnyGeneral();
|
||||
Register argValueReg = regSet.takeAnyGeneral();
|
||||
// We can just reuse the "object" register for argObjReg
|
||||
Register argObjReg = object;
|
||||
Register argIdReg = regSet.takeGeneral();
|
||||
Register argIdReg = regSet.takeAnyGeneral();
|
||||
masm.movePtr(StackPointer, argValueReg);
|
||||
|
||||
// push canonical jsid from shape instead of propertyname.
|
||||
@ -3387,7 +3388,7 @@ GetElementIC::attachGetProp(JSContext *cx, HandleScript outerScript, IonScript *
|
||||
|
||||
// We have a non-atomized string with the same length. For now call a helper
|
||||
// function to do the comparison.
|
||||
RegisterSet volatileRegs = RegisterSet::Volatile();
|
||||
LiveRegisterSet volatileRegs(RegisterSet::Volatile());
|
||||
masm.PushRegsInMask(volatileRegs);
|
||||
|
||||
Register objReg = object();
|
||||
@ -3407,7 +3408,7 @@ GetElementIC::attachGetProp(JSContext *cx, HandleScript outerScript, IonScript *
|
||||
if (!volatileRegs.has(objReg))
|
||||
masm.pop(objReg);
|
||||
|
||||
RegisterSet ignore = RegisterSet();
|
||||
LiveRegisterSet ignore;
|
||||
ignore.add(scratch);
|
||||
masm.PopRegsInMaskIgnore(volatileRegs, ignore);
|
||||
|
||||
@ -3737,20 +3738,21 @@ GenerateGetTypedArrayElement(JSContext *cx, MacroAssembler &masm, IonCache::Stub
|
||||
}
|
||||
|
||||
// Part 2: Call to translate the str into index
|
||||
RegisterSet regs = RegisterSet::Volatile();
|
||||
masm.PushRegsInMask(regs);
|
||||
AllocatableRegisterSet regs(RegisterSet::Volatile());
|
||||
LiveRegisterSet save(regs.asLiveSet());
|
||||
masm.PushRegsInMask(save);
|
||||
regs.takeUnchecked(str);
|
||||
|
||||
Register temp = regs.takeGeneral();
|
||||
Register temp = regs.takeAnyGeneral();
|
||||
|
||||
masm.setupUnalignedABICall(1, temp);
|
||||
masm.passABIArg(str);
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, GetIndexFromString));
|
||||
masm.mov(ReturnReg, indexReg);
|
||||
|
||||
RegisterSet ignore = RegisterSet();
|
||||
LiveRegisterSet ignore;
|
||||
ignore.add(indexReg);
|
||||
masm.PopRegsInMaskIgnore(RegisterSet::Volatile(), ignore);
|
||||
masm.PopRegsInMaskIgnore(save, ignore);
|
||||
|
||||
masm.branch32(Assembler::Equal, indexReg, Imm32(UINT32_MAX), &failures);
|
||||
|
||||
|
@ -544,7 +544,7 @@ class GetPropertyIC : public RepatchIonCache
|
||||
protected:
|
||||
// Registers live after the cache, excluding output registers. The initial
|
||||
// value of these registers must be preserved by the cache.
|
||||
RegisterSet liveRegs_;
|
||||
LiveRegisterSet liveRegs_;
|
||||
|
||||
Register object_;
|
||||
PropertyName *name_;
|
||||
@ -562,7 +562,7 @@ class GetPropertyIC : public RepatchIonCache
|
||||
bool hasGenericProxyStub_ : 1;
|
||||
|
||||
public:
|
||||
GetPropertyIC(RegisterSet liveRegs,
|
||||
GetPropertyIC(LiveRegisterSet liveRegs,
|
||||
Register object, PropertyName *name,
|
||||
TypedOrValueRegister output,
|
||||
bool monitoredResult)
|
||||
@ -689,7 +689,7 @@ class SetPropertyIC : public RepatchIonCache
|
||||
protected:
|
||||
// Registers live after the cache, excluding output registers. The initial
|
||||
// value of these registers must be preserved by the cache.
|
||||
RegisterSet liveRegs_;
|
||||
LiveRegisterSet liveRegs_;
|
||||
|
||||
Register object_;
|
||||
PropertyName *name_;
|
||||
@ -700,7 +700,7 @@ class SetPropertyIC : public RepatchIonCache
|
||||
bool hasGenericProxyStub_;
|
||||
|
||||
public:
|
||||
SetPropertyIC(RegisterSet liveRegs, Register object, PropertyName *name,
|
||||
SetPropertyIC(LiveRegisterSet liveRegs, Register object, PropertyName *name,
|
||||
ConstantOrRegister value, bool strict, bool needsTypeBarrier)
|
||||
: liveRegs_(liveRegs),
|
||||
object_(object),
|
||||
@ -774,7 +774,7 @@ class SetPropertyIC : public RepatchIonCache
|
||||
class GetElementIC : public RepatchIonCache
|
||||
{
|
||||
protected:
|
||||
RegisterSet liveRegs_;
|
||||
LiveRegisterSet liveRegs_;
|
||||
|
||||
Register object_;
|
||||
ConstantOrRegister index_;
|
||||
@ -791,7 +791,7 @@ class GetElementIC : public RepatchIonCache
|
||||
static const size_t MAX_FAILED_UPDATES;
|
||||
|
||||
public:
|
||||
GetElementIC(RegisterSet liveRegs, Register object, ConstantOrRegister index,
|
||||
GetElementIC(LiveRegisterSet liveRegs, Register object, ConstantOrRegister index,
|
||||
TypedOrValueRegister output, bool monitoredResult, bool allowDoubleResult)
|
||||
: liveRegs_(liveRegs),
|
||||
object_(object),
|
||||
@ -1008,7 +1008,7 @@ class NameIC : public RepatchIonCache
|
||||
protected:
|
||||
// Registers live after the cache, excluding output registers. The initial
|
||||
// value of these registers must be preserved by the cache.
|
||||
RegisterSet liveRegs_;
|
||||
LiveRegisterSet liveRegs_;
|
||||
|
||||
bool typeOf_;
|
||||
Register scopeChain_;
|
||||
@ -1016,7 +1016,7 @@ class NameIC : public RepatchIonCache
|
||||
TypedOrValueRegister output_;
|
||||
|
||||
public:
|
||||
NameIC(RegisterSet liveRegs, bool typeOf,
|
||||
NameIC(LiveRegisterSet liveRegs, bool typeOf,
|
||||
Register scopeChain, PropertyName *name,
|
||||
TypedOrValueRegister output)
|
||||
: liveRegs_(liveRegs),
|
||||
|
@ -353,7 +353,7 @@ JitFrameIterator::machineState() const
|
||||
uint8_t *spillAlign = alignDoubleSpillWithOffset(reinterpret_cast<uint8_t *>(spill), 0);
|
||||
|
||||
char *floatSpill = reinterpret_cast<char *>(spillAlign);
|
||||
FloatRegisterSet fregs = reader.allFloatSpills();
|
||||
FloatRegisterSet fregs = reader.allFloatSpills().set();
|
||||
fregs = fregs.reduceSetForPush();
|
||||
for (FloatRegisterBackwardIterator iter(fregs); iter.more(); iter++) {
|
||||
floatSpill -= (*iter).size();
|
||||
@ -1072,8 +1072,8 @@ MarkIonJSFrame(JSTracer *trc, const JitFrameIterator &frame)
|
||||
}
|
||||
|
||||
uintptr_t *spill = frame.spillBase();
|
||||
GeneralRegisterSet gcRegs = safepoint.gcSpills();
|
||||
GeneralRegisterSet valueRegs = safepoint.valueSpills();
|
||||
LiveGeneralRegisterSet gcRegs = safepoint.gcSpills();
|
||||
LiveGeneralRegisterSet valueRegs = safepoint.valueSpills();
|
||||
for (GeneralRegisterBackwardIterator iter(safepoint.allGprSpills()); iter.more(); iter++) {
|
||||
--spill;
|
||||
if (gcRegs.has(*iter))
|
||||
@ -1159,7 +1159,7 @@ UpdateIonJSFrameForMinorGC(JSTracer *trc, const JitFrameIterator &frame)
|
||||
const SafepointIndex *si = ionScript->getSafepointIndex(frame.returnAddressToFp());
|
||||
SafepointReader safepoint(ionScript, si);
|
||||
|
||||
GeneralRegisterSet slotsRegs = safepoint.slotsOrElementsSpills();
|
||||
LiveGeneralRegisterSet slotsRegs = safepoint.slotsOrElementsSpills();
|
||||
uintptr_t *spill = frame.spillBase();
|
||||
for (GeneralRegisterBackwardIterator iter(safepoint.allGprSpills()); iter.more(); iter++) {
|
||||
--spill;
|
||||
|
@ -1323,15 +1323,15 @@ class LSafepoint : public TempObject
|
||||
// registers: if passed to the call, the values passed will be marked via
|
||||
// MarkJitExitFrame, and no registers can be live after the instruction
|
||||
// except its outputs.
|
||||
RegisterSet liveRegs_;
|
||||
LiveRegisterSet liveRegs_;
|
||||
|
||||
// The subset of liveRegs which contains gcthing pointers.
|
||||
GeneralRegisterSet gcRegs_;
|
||||
LiveGeneralRegisterSet gcRegs_;
|
||||
|
||||
#ifdef CHECK_OSIPOINT_REGISTERS
|
||||
// Clobbered regs of the current instruction. This set is never written to
|
||||
// the safepoint; it's only used by assertions during compilation.
|
||||
RegisterSet clobberedRegs_;
|
||||
LiveRegisterSet clobberedRegs_;
|
||||
#endif
|
||||
|
||||
// Offset to a position in the safepoint stream, or
|
||||
@ -1352,11 +1352,11 @@ class LSafepoint : public TempObject
|
||||
NunboxList nunboxParts_;
|
||||
#elif JS_PUNBOX64
|
||||
// The subset of liveRegs which have Values.
|
||||
GeneralRegisterSet valueRegs_;
|
||||
LiveGeneralRegisterSet valueRegs_;
|
||||
#endif
|
||||
|
||||
// The subset of liveRegs which contains pointers to slots/elements.
|
||||
GeneralRegisterSet slotsOrElementsRegs_;
|
||||
LiveGeneralRegisterSet slotsOrElementsRegs_;
|
||||
|
||||
// List of slots which have slots/elements pointers.
|
||||
SlotList slotsOrElementsSlots_;
|
||||
@ -1386,7 +1386,7 @@ class LSafepoint : public TempObject
|
||||
liveRegs_.addUnchecked(reg);
|
||||
assertInvariants();
|
||||
}
|
||||
const RegisterSet &liveRegs() const {
|
||||
const LiveRegisterSet &liveRegs() const {
|
||||
return liveRegs_;
|
||||
}
|
||||
#ifdef CHECK_OSIPOINT_REGISTERS
|
||||
@ -1394,7 +1394,7 @@ class LSafepoint : public TempObject
|
||||
clobberedRegs_.addUnchecked(reg);
|
||||
assertInvariants();
|
||||
}
|
||||
const RegisterSet &clobberedRegs() const {
|
||||
const LiveRegisterSet &clobberedRegs() const {
|
||||
return clobberedRegs_;
|
||||
}
|
||||
#endif
|
||||
@ -1402,7 +1402,7 @@ class LSafepoint : public TempObject
|
||||
gcRegs_.addUnchecked(reg);
|
||||
assertInvariants();
|
||||
}
|
||||
GeneralRegisterSet gcRegs() const {
|
||||
LiveGeneralRegisterSet gcRegs() const {
|
||||
return gcRegs_;
|
||||
}
|
||||
bool addGcSlot(bool stack, uint32_t slot) {
|
||||
@ -1418,7 +1418,7 @@ class LSafepoint : public TempObject
|
||||
SlotList &slotsOrElementsSlots() {
|
||||
return slotsOrElementsSlots_;
|
||||
}
|
||||
GeneralRegisterSet slotsOrElementsRegs() const {
|
||||
LiveGeneralRegisterSet slotsOrElementsRegs() const {
|
||||
return slotsOrElementsRegs_;
|
||||
}
|
||||
void addSlotsOrElementsRegister(Register reg) {
|
||||
@ -1567,7 +1567,7 @@ class LSafepoint : public TempObject
|
||||
valueRegs_.add(reg);
|
||||
assertInvariants();
|
||||
}
|
||||
GeneralRegisterSet valueRegs() const {
|
||||
LiveGeneralRegisterSet valueRegs() const {
|
||||
return valueRegs_;
|
||||
}
|
||||
|
||||
|
@ -995,11 +995,17 @@ LinearScanAllocator::findBestFreeRegister(CodePosition *freeUntil)
|
||||
// Compute free-until positions for all registers
|
||||
CodePosition freeUntilPos[AnyRegister::Total];
|
||||
bool needFloat = vregs[current->vreg()].isFloatReg();
|
||||
for (RegisterSet regs(allRegisters_); !regs.empty(needFloat); ) {
|
||||
// If the requested register is a FP, we may need to look at
|
||||
// all of the float32 and float64 registers.
|
||||
AnyRegister reg = regs.takeUnaliasedAny(needFloat);
|
||||
freeUntilPos[reg.code()] = CodePosition::MAX;
|
||||
if (needFloat) {
|
||||
// we may need to look at all of the float32 and float64 registers.
|
||||
for (LiveRegisterSet regs(allRegisters_.asLiveSet()); !regs.emptyFloat(); ) {
|
||||
AnyRegister reg(regs.takeAnyFloat());
|
||||
freeUntilPos[reg.code()] = CodePosition::MAX;
|
||||
}
|
||||
} else {
|
||||
for (LiveRegisterSet regs(allRegisters_.asLiveSet()); !regs.emptyGeneral(); ) {
|
||||
AnyRegister reg(regs.takeAnyGeneral());
|
||||
freeUntilPos[reg.code()] = CodePosition::MAX;
|
||||
}
|
||||
}
|
||||
for (IntervalIterator i(active.begin()); i != active.end(); i++) {
|
||||
LAllocation *alloc = i->getAllocation();
|
||||
@ -1125,9 +1131,16 @@ LinearScanAllocator::findBestBlockedRegister(CodePosition *nextUsed)
|
||||
// Compute next-used positions for all registers
|
||||
CodePosition nextUsePos[AnyRegister::Total];
|
||||
bool needFloat = vregs[current->vreg()].isFloatReg();
|
||||
for (RegisterSet regs(allRegisters_); !regs.empty(needFloat); ) {
|
||||
AnyRegister reg = regs.takeUnaliasedAny(needFloat);
|
||||
nextUsePos[reg.code()] = CodePosition::MAX;
|
||||
if (needFloat) {
|
||||
for (LiveRegisterSet regs(allRegisters_.asLiveSet()); !regs.emptyFloat(); ) {
|
||||
AnyRegister reg(regs.takeAnyFloat());
|
||||
nextUsePos[reg.code()] = CodePosition::MAX;
|
||||
}
|
||||
} else {
|
||||
for (LiveRegisterSet regs(allRegisters_.asLiveSet()); !regs.emptyGeneral(); ) {
|
||||
AnyRegister reg(regs.takeAnyGeneral());
|
||||
nextUsePos[reg.code()] = CodePosition::MAX;
|
||||
}
|
||||
}
|
||||
for (IntervalIterator i(active.begin()); i != active.end(); i++) {
|
||||
LAllocation *alloc = i->getAllocation();
|
||||
|
@ -645,18 +645,10 @@ LiveRangeAllocator<VREG, forLSRA>::buildLivenessInfo()
|
||||
for (LInstructionReverseIterator ins = block->rbegin(); ins != block->rend(); ins++) {
|
||||
// Calls may clobber registers, so force a spill and reload around the callsite.
|
||||
if (ins->isCall()) {
|
||||
for (AnyRegisterIterator iter(allRegisters_); iter.more(); iter++) {
|
||||
for (AnyRegisterIterator iter(allRegisters_.asLiveSet()); iter.more(); iter++) {
|
||||
if (forLSRA) {
|
||||
AnyRegister reg(*iter);
|
||||
// AnyRegisterIterator only iterates every allocatable
|
||||
// register once, and skip all aliased registers. Thus,
|
||||
// we have to record that each typed-variant/alias of
|
||||
// the same register has to be spilled if it got
|
||||
// allocated.
|
||||
for (size_t i = 0; i < reg.numAliased(); i++) {
|
||||
if (!addFixedRangeAtHead(reg.aliased(i), inputOf(*ins), outputOf(*ins)))
|
||||
return false;
|
||||
}
|
||||
if (!addFixedRangeAtHead(*iter, inputOf(*ins), outputOf(*ins)))
|
||||
return false;
|
||||
} else {
|
||||
bool found = false;
|
||||
|
||||
|
@ -1446,7 +1446,7 @@ MacroAssembler::initGCThing(Register obj, Register temp, JSObject *templateObj,
|
||||
RegisterSet regs = RegisterSet::Volatile();
|
||||
PushRegsInMask(regs);
|
||||
regs.takeUnchecked(obj);
|
||||
Register temp = regs.takeGeneral();
|
||||
Register temp = regs.takeAnyGeneral();
|
||||
|
||||
setupUnalignedABICall(2, temp);
|
||||
passABIArg(obj);
|
||||
@ -1595,7 +1595,7 @@ MacroAssembler::generateBailoutTail(Register scratch, Register bailoutInfo)
|
||||
bind(&baseline);
|
||||
{
|
||||
// Prepare a register set for use in this case.
|
||||
GeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
MOZ_ASSERT(!regs.has(BaselineStackReg));
|
||||
regs.take(bailoutInfo);
|
||||
|
||||
@ -1657,7 +1657,7 @@ MacroAssembler::generateBailoutTail(Register scratch, Register bailoutInfo)
|
||||
branchTest32(Zero, ReturnReg, ReturnReg, exceptionLabel());
|
||||
|
||||
// Restore values where they need to be and resume execution.
|
||||
GeneralRegisterSet enterMonRegs(GeneralRegisterSet::All());
|
||||
AllocatableGeneralRegisterSet enterMonRegs(GeneralRegisterSet::All());
|
||||
enterMonRegs.take(R0);
|
||||
enterMonRegs.take(BaselineStubReg);
|
||||
enterMonRegs.take(BaselineFrameReg);
|
||||
@ -1695,7 +1695,7 @@ MacroAssembler::generateBailoutTail(Register scratch, Register bailoutInfo)
|
||||
branchTest32(Zero, ReturnReg, ReturnReg, exceptionLabel());
|
||||
|
||||
// Restore values where they need to be and resume execution.
|
||||
GeneralRegisterSet enterRegs(GeneralRegisterSet::All());
|
||||
AllocatableGeneralRegisterSet enterRegs(GeneralRegisterSet::All());
|
||||
enterRegs.take(R0);
|
||||
enterRegs.take(R1);
|
||||
enterRegs.take(BaselineFrameReg);
|
||||
@ -1759,16 +1759,17 @@ MacroAssembler::assumeUnreachable(const char *output)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (!IsCompilingAsmJS()) {
|
||||
RegisterSet regs = RegisterSet::Volatile();
|
||||
PushRegsInMask(regs);
|
||||
Register temp = regs.takeGeneral();
|
||||
AllocatableRegisterSet regs(RegisterSet::Volatile());
|
||||
LiveRegisterSet save(regs.asLiveSet());
|
||||
PushRegsInMask(save);
|
||||
Register temp = regs.takeAnyGeneral();
|
||||
|
||||
setupUnalignedABICall(1, temp);
|
||||
movePtr(ImmPtr(output), temp);
|
||||
passABIArg(temp);
|
||||
callWithABI(JS_FUNC_TO_DATA_PTR(void *, AssumeUnreachable_));
|
||||
|
||||
PopRegsInMask(RegisterSet::Volatile());
|
||||
PopRegsInMask(save);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1800,17 +1801,18 @@ Printf0_(const char *output) {
|
||||
void
|
||||
MacroAssembler::printf(const char *output)
|
||||
{
|
||||
RegisterSet regs = RegisterSet::Volatile();
|
||||
PushRegsInMask(regs);
|
||||
AllocatableRegisterSet regs(RegisterSet::Volatile());
|
||||
LiveRegisterSet save(regs.asLiveSet());
|
||||
PushRegsInMask(save);
|
||||
|
||||
Register temp = regs.takeGeneral();
|
||||
Register temp = regs.takeAnyGeneral();
|
||||
|
||||
setupUnalignedABICall(1, temp);
|
||||
movePtr(ImmPtr(output), temp);
|
||||
passABIArg(temp);
|
||||
callWithABI(JS_FUNC_TO_DATA_PTR(void *, Printf0_));
|
||||
|
||||
PopRegsInMask(RegisterSet::Volatile());
|
||||
PopRegsInMask(save);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1823,12 +1825,13 @@ Printf1_(const char *output, uintptr_t value) {
|
||||
void
|
||||
MacroAssembler::printf(const char *output, Register value)
|
||||
{
|
||||
RegisterSet regs = RegisterSet::Volatile();
|
||||
PushRegsInMask(regs);
|
||||
AllocatableRegisterSet regs(RegisterSet::Volatile());
|
||||
LiveRegisterSet save(regs.asLiveSet());
|
||||
PushRegsInMask(save);
|
||||
|
||||
regs.takeUnchecked(value);
|
||||
|
||||
Register temp = regs.takeGeneral();
|
||||
Register temp = regs.takeAnyGeneral();
|
||||
|
||||
setupUnalignedABICall(2, temp);
|
||||
movePtr(ImmPtr(output), temp);
|
||||
@ -1836,7 +1839,7 @@ MacroAssembler::printf(const char *output, Register value)
|
||||
passABIArg(value);
|
||||
callWithABI(JS_FUNC_TO_DATA_PTR(void *, Printf1_));
|
||||
|
||||
PopRegsInMask(RegisterSet::Volatile());
|
||||
PopRegsInMask(save);
|
||||
}
|
||||
|
||||
#ifdef JS_TRACE_LOGGING
|
||||
@ -1846,12 +1849,12 @@ MacroAssembler::tracelogStartId(Register logger, uint32_t textId, bool force)
|
||||
if (!force && !TraceLogTextIdEnabled(textId))
|
||||
return;
|
||||
|
||||
PushRegsInMask(RegisterSet::Volatile());
|
||||
|
||||
RegisterSet regs = RegisterSet::Volatile();
|
||||
AllocatableRegisterSet regs(RegisterSet::Volatile());
|
||||
LiveRegisterSet save(regs.asLiveSet());
|
||||
PushRegsInMask(save);
|
||||
regs.takeUnchecked(logger);
|
||||
|
||||
Register temp = regs.takeGeneral();
|
||||
Register temp = regs.takeAnyGeneral();
|
||||
|
||||
setupUnalignedABICall(2, temp);
|
||||
passABIArg(logger);
|
||||
@ -1859,26 +1862,26 @@ MacroAssembler::tracelogStartId(Register logger, uint32_t textId, bool force)
|
||||
passABIArg(temp);
|
||||
callWithABI(JS_FUNC_TO_DATA_PTR(void *, TraceLogStartEventPrivate));
|
||||
|
||||
PopRegsInMask(RegisterSet::Volatile());
|
||||
PopRegsInMask(save);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::tracelogStartId(Register logger, Register textId)
|
||||
{
|
||||
PushRegsInMask(RegisterSet::Volatile());
|
||||
|
||||
RegisterSet regs = RegisterSet::Volatile();
|
||||
AllocatableRegisterSet regs(RegisterSet::Volatile());
|
||||
LiveRegisterSet save(regs.asLiveSet());
|
||||
PushRegsInMask(save);
|
||||
regs.takeUnchecked(logger);
|
||||
regs.takeUnchecked(textId);
|
||||
|
||||
Register temp = regs.takeGeneral();
|
||||
Register temp = regs.takeAnyGeneral();
|
||||
|
||||
setupUnalignedABICall(2, temp);
|
||||
passABIArg(logger);
|
||||
passABIArg(textId);
|
||||
callWithABI(JS_FUNC_TO_DATA_PTR(void *, TraceLogStartEventPrivate));
|
||||
|
||||
PopRegsInMask(RegisterSet::Volatile());
|
||||
PopRegsInMask(save);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1886,20 +1889,20 @@ MacroAssembler::tracelogStartEvent(Register logger, Register event)
|
||||
{
|
||||
void (&TraceLogFunc)(TraceLoggerThread *, const TraceLoggerEvent &) = TraceLogStartEvent;
|
||||
|
||||
PushRegsInMask(RegisterSet::Volatile());
|
||||
|
||||
RegisterSet regs = RegisterSet::Volatile();
|
||||
AllocatableRegisterSet regs(RegisterSet::Volatile());
|
||||
LiveRegisterSet save(regs.asLiveSet());
|
||||
PushRegsInMask(save);
|
||||
regs.takeUnchecked(logger);
|
||||
regs.takeUnchecked(event);
|
||||
|
||||
Register temp = regs.takeGeneral();
|
||||
Register temp = regs.takeAnyGeneral();
|
||||
|
||||
setupUnalignedABICall(2, temp);
|
||||
passABIArg(logger);
|
||||
passABIArg(event);
|
||||
callWithABI(JS_FUNC_TO_DATA_PTR(void *, TraceLogFunc));
|
||||
|
||||
PopRegsInMask(RegisterSet::Volatile());
|
||||
PopRegsInMask(save);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1908,12 +1911,12 @@ MacroAssembler::tracelogStopId(Register logger, uint32_t textId, bool force)
|
||||
if (!force && !TraceLogTextIdEnabled(textId))
|
||||
return;
|
||||
|
||||
PushRegsInMask(RegisterSet::Volatile());
|
||||
|
||||
RegisterSet regs = RegisterSet::Volatile();
|
||||
AllocatableRegisterSet regs(RegisterSet::Volatile());
|
||||
LiveRegisterSet save(regs.asLiveSet());
|
||||
PushRegsInMask(save);
|
||||
regs.takeUnchecked(logger);
|
||||
|
||||
Register temp = regs.takeGeneral();
|
||||
Register temp = regs.takeAnyGeneral();
|
||||
|
||||
setupUnalignedABICall(2, temp);
|
||||
passABIArg(logger);
|
||||
@ -1922,26 +1925,26 @@ MacroAssembler::tracelogStopId(Register logger, uint32_t textId, bool force)
|
||||
|
||||
callWithABI(JS_FUNC_TO_DATA_PTR(void *, TraceLogStopEventPrivate));
|
||||
|
||||
PopRegsInMask(RegisterSet::Volatile());
|
||||
PopRegsInMask(save);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::tracelogStopId(Register logger, Register textId)
|
||||
{
|
||||
PushRegsInMask(RegisterSet::Volatile());
|
||||
RegisterSet regs = RegisterSet::Volatile();
|
||||
AllocatableRegisterSet regs(RegisterSet::Volatile());
|
||||
LiveRegisterSet save(regs.asLiveSet());
|
||||
PushRegsInMask(save);
|
||||
regs.takeUnchecked(logger);
|
||||
|
||||
regs.takeUnchecked(textId);
|
||||
|
||||
Register temp = regs.takeGeneral();
|
||||
Register temp = regs.takeAnyGeneral();
|
||||
|
||||
setupUnalignedABICall(2, temp);
|
||||
passABIArg(logger);
|
||||
passABIArg(textId);
|
||||
callWithABI(JS_FUNC_TO_DATA_PTR(void *, TraceLogStopEventPrivate));
|
||||
|
||||
PopRegsInMask(RegisterSet::Volatile());
|
||||
PopRegsInMask(save);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -2529,39 +2532,39 @@ MacroAssembler::alignJitStackBasedOnNArgs(uint32_t nargs)
|
||||
// Stack manipulation functions.
|
||||
|
||||
void
|
||||
MacroAssembler::PushRegsInMask(RegisterSet set)
|
||||
MacroAssembler::PushRegsInMask(LiveRegisterSet set)
|
||||
{
|
||||
PushRegsInMask(set, FloatRegisterSet());
|
||||
PushRegsInMask(set, LiveFloatRegisterSet());
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::PushRegsInMask(GeneralRegisterSet set)
|
||||
MacroAssembler::PushRegsInMask(LiveGeneralRegisterSet set)
|
||||
{
|
||||
PushRegsInMask(RegisterSet(set, FloatRegisterSet()));
|
||||
PushRegsInMask(LiveRegisterSet(set.set(), FloatRegisterSet()));
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::PopRegsInMask(RegisterSet set)
|
||||
MacroAssembler::PopRegsInMask(LiveRegisterSet set)
|
||||
{
|
||||
PopRegsInMaskIgnore(set, RegisterSet());
|
||||
PopRegsInMaskIgnore(set, LiveRegisterSet());
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::PopRegsInMask(RegisterSet set, FloatRegisterSet simdSet)
|
||||
MacroAssembler::PopRegsInMask(LiveRegisterSet set, LiveFloatRegisterSet simdSet)
|
||||
{
|
||||
PopRegsInMaskIgnore(set, RegisterSet(), simdSet);
|
||||
PopRegsInMaskIgnore(set, LiveRegisterSet(), simdSet);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::PopRegsInMask(GeneralRegisterSet set)
|
||||
MacroAssembler::PopRegsInMask(LiveGeneralRegisterSet set)
|
||||
{
|
||||
PopRegsInMask(RegisterSet(set, FloatRegisterSet()));
|
||||
PopRegsInMask(LiveRegisterSet(set.set(), FloatRegisterSet()));
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore)
|
||||
MacroAssembler::PopRegsInMaskIgnore(LiveRegisterSet set, LiveRegisterSet ignore)
|
||||
{
|
||||
PopRegsInMaskIgnore(set, ignore, FloatRegisterSet());
|
||||
PopRegsInMaskIgnore(set, ignore, LiveFloatRegisterSet());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -296,16 +296,16 @@ class MacroAssembler : public MacroAssemblerSpecific
|
||||
// ===============================================================
|
||||
// Stack manipulation functions.
|
||||
|
||||
void PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet) PER_ARCH;
|
||||
void PushRegsInMask(RegisterSet set);
|
||||
void PushRegsInMask(GeneralRegisterSet set);
|
||||
void PushRegsInMask(LiveRegisterSet set, LiveFloatRegisterSet simdSet) PER_ARCH;
|
||||
void PushRegsInMask(LiveRegisterSet set);
|
||||
void PushRegsInMask(LiveGeneralRegisterSet set);
|
||||
|
||||
void PopRegsInMask(RegisterSet set);
|
||||
void PopRegsInMask(RegisterSet set, FloatRegisterSet simdSet);
|
||||
void PopRegsInMask(GeneralRegisterSet set);
|
||||
void PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore,
|
||||
FloatRegisterSet simdSet) PER_ARCH;
|
||||
void PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore);
|
||||
void PopRegsInMask(LiveRegisterSet set);
|
||||
void PopRegsInMask(LiveRegisterSet set, LiveFloatRegisterSet simdSet);
|
||||
void PopRegsInMask(LiveGeneralRegisterSet set);
|
||||
void PopRegsInMaskIgnore(LiveRegisterSet set, LiveRegisterSet ignore,
|
||||
LiveFloatRegisterSet simdSet) PER_ARCH;
|
||||
void PopRegsInMaskIgnore(LiveRegisterSet set, LiveRegisterSet ignore);
|
||||
|
||||
void Push(const Operand op) PER_ARCH ONLY_X86_X64;
|
||||
void Push(Register reg) PER_ARCH;
|
||||
@ -1231,7 +1231,7 @@ class MacroAssembler : public MacroAssemblerSpecific
|
||||
void alignFrameForICArguments(AfterICSaveLive &aic);
|
||||
void restoreFrameAlignmentForICArguments(AfterICSaveLive &aic);
|
||||
|
||||
AfterICSaveLive icSaveLive(RegisterSet &liveRegs) {
|
||||
AfterICSaveLive icSaveLive(LiveRegisterSet &liveRegs) {
|
||||
PushRegsInMask(liveRegs);
|
||||
AfterICSaveLive aic(framePushed());
|
||||
alignFrameForICArguments(aic);
|
||||
@ -1242,7 +1242,7 @@ class MacroAssembler : public MacroAssemblerSpecific
|
||||
return buildOOLFakeExitFrame(fakeReturnAddr);
|
||||
}
|
||||
|
||||
void icRestoreLive(RegisterSet &liveRegs, AfterICSaveLive &aic) {
|
||||
void icRestoreLive(LiveRegisterSet &liveRegs, AfterICSaveLive &aic) {
|
||||
restoreFrameAlignmentForICArguments(aic);
|
||||
MOZ_ASSERT(framePushed() == aic.initialStack);
|
||||
PopRegsInMask(liveRegs);
|
||||
|
@ -144,8 +144,8 @@ AllocationIntegrityState::check(bool populateSafepoints)
|
||||
return false;
|
||||
}
|
||||
MOZ_ASSERT_IF(ins->isCall() && !populateSafepoints,
|
||||
safepoint->liveRegs().empty(true) &&
|
||||
safepoint->liveRegs().empty(false));
|
||||
safepoint->liveRegs().emptyFloat() &&
|
||||
safepoint->liveRegs().emptyGeneral());
|
||||
}
|
||||
|
||||
size_t inputIndex = 0;
|
||||
|
@ -261,7 +261,7 @@ class RegisterAllocator
|
||||
LIRGraph &graph;
|
||||
|
||||
// Pool of all registers that should be considered allocateable
|
||||
RegisterSet allRegisters_;
|
||||
AllocatableRegisterSet allRegisters_;
|
||||
|
||||
// Computed data
|
||||
InstructionDataMap insData;
|
||||
|
@ -1248,10 +1248,10 @@ class ABIArg
|
||||
// Get the set of registers which should be saved by a block of code which
|
||||
// clobbers all registers besides |unused|, but does not clobber floating point
|
||||
// registers.
|
||||
inline GeneralRegisterSet
|
||||
SavedNonVolatileRegisters(GeneralRegisterSet unused)
|
||||
inline LiveGeneralRegisterSet
|
||||
SavedNonVolatileRegisters(AllocatableGeneralRegisterSet unused)
|
||||
{
|
||||
GeneralRegisterSet result;
|
||||
LiveGeneralRegisterSet result;
|
||||
|
||||
for (GeneralRegisterIterator iter(GeneralRegisterSet::NonVolatile()); iter.more(); iter++) {
|
||||
Register reg = *iter;
|
||||
|
@ -88,11 +88,11 @@ ReadFloatRegisterMask(CompactBufferReader &stream)
|
||||
void
|
||||
SafepointWriter::writeGcRegs(LSafepoint *safepoint)
|
||||
{
|
||||
GeneralRegisterSet gc = safepoint->gcRegs();
|
||||
GeneralRegisterSet spilledGpr = safepoint->liveRegs().gprs();
|
||||
FloatRegisterSet spilledFloat = safepoint->liveRegs().fpus();
|
||||
GeneralRegisterSet slots = safepoint->slotsOrElementsRegs();
|
||||
GeneralRegisterSet valueRegs;
|
||||
LiveGeneralRegisterSet gc(safepoint->gcRegs());
|
||||
LiveGeneralRegisterSet spilledGpr(safepoint->liveRegs().gprs());
|
||||
LiveFloatRegisterSet spilledFloat(safepoint->liveRegs().fpus());
|
||||
LiveGeneralRegisterSet slots(safepoint->slotsOrElementsRegs());
|
||||
LiveGeneralRegisterSet valueRegs;
|
||||
|
||||
WriteRegisterMask(stream_, spilledGpr.bits());
|
||||
if (!spilledGpr.empty()) {
|
||||
|
@ -92,20 +92,20 @@ class SafepointReader
|
||||
uint32_t osiCallPointOffset() const {
|
||||
return osiCallPointOffset_;
|
||||
}
|
||||
GeneralRegisterSet gcSpills() const {
|
||||
return gcSpills_;
|
||||
LiveGeneralRegisterSet gcSpills() const {
|
||||
return LiveGeneralRegisterSet(gcSpills_);
|
||||
}
|
||||
GeneralRegisterSet slotsOrElementsSpills() const {
|
||||
return slotsOrElementsSpills_;
|
||||
LiveGeneralRegisterSet slotsOrElementsSpills() const {
|
||||
return LiveGeneralRegisterSet(slotsOrElementsSpills_);
|
||||
}
|
||||
GeneralRegisterSet valueSpills() const {
|
||||
return valueSpills_;
|
||||
LiveGeneralRegisterSet valueSpills() const {
|
||||
return LiveGeneralRegisterSet(valueSpills_);
|
||||
}
|
||||
GeneralRegisterSet allGprSpills() const {
|
||||
return allGprSpills_;
|
||||
LiveGeneralRegisterSet allGprSpills() const {
|
||||
return LiveGeneralRegisterSet(allGprSpills_);
|
||||
}
|
||||
FloatRegisterSet allFloatSpills() const {
|
||||
return allFloatSpills_;
|
||||
LiveFloatRegisterSet allFloatSpills() const {
|
||||
return LiveFloatRegisterSet(allFloatSpills_);
|
||||
}
|
||||
uint32_t osiReturnPointOffset() const;
|
||||
|
||||
|
@ -76,12 +76,12 @@ StupidAllocator::init()
|
||||
// Assign physical registers to the tracked allocation.
|
||||
{
|
||||
registerCount = 0;
|
||||
RegisterSet remainingRegisters(allRegisters_);
|
||||
while (!remainingRegisters.empty(/* float = */ false))
|
||||
registers[registerCount++].reg = AnyRegister(remainingRegisters.takeUnaliasedGeneral());
|
||||
LiveRegisterSet remainingRegisters(allRegisters_.asLiveSet());
|
||||
while (!remainingRegisters.emptyGeneral())
|
||||
registers[registerCount++].reg = AnyRegister(remainingRegisters.takeAnyGeneral());
|
||||
|
||||
while (!remainingRegisters.empty(/* float = */ true))
|
||||
registers[registerCount++].reg = AnyRegister(remainingRegisters.takeUnaliasedFloat());
|
||||
while (!remainingRegisters.emptyFloat())
|
||||
registers[registerCount++].reg = AnyRegister(remainingRegisters.takeAnyFloat());
|
||||
|
||||
MOZ_ASSERT(registerCount <= MAX_REGISTERS);
|
||||
}
|
||||
|
@ -347,8 +347,8 @@ FloatRegisters::FromName(const char *name)
|
||||
FloatRegisterSet
|
||||
VFPRegister::ReduceSetForPush(const FloatRegisterSet &s)
|
||||
{
|
||||
FloatRegisterSet mod;
|
||||
for (TypedRegisterIterator<FloatRegister> iter(s); iter.more(); iter++) {
|
||||
LiveFloatRegisterSet mod;
|
||||
for (FloatRegisterIterator iter(s); iter.more(); iter++) {
|
||||
if ((*iter).isSingle()) {
|
||||
// Add in just this float.
|
||||
mod.addUnchecked(*iter);
|
||||
@ -361,7 +361,7 @@ VFPRegister::ReduceSetForPush(const FloatRegisterSet &s)
|
||||
mod.addUnchecked(*iter);
|
||||
}
|
||||
}
|
||||
return mod;
|
||||
return mod.set();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
|
@ -86,8 +86,8 @@ ICBinaryArith_Int32::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
Register scratchReg = R2.payloadReg();
|
||||
|
||||
// DIV and MOD need an extra non-volatile ValueOperand to hold R0.
|
||||
GeneralRegisterSet savedRegs = availableGeneralRegs(2);
|
||||
savedRegs = GeneralRegisterSet::Intersect(GeneralRegisterSet::NonVolatile(), savedRegs);
|
||||
AllocatableGeneralRegisterSet savedRegs(availableGeneralRegs(2));
|
||||
savedRegs.set() = GeneralRegisterSet::Intersect(GeneralRegisterSet::NonVolatile(), savedRegs.set());
|
||||
ValueOperand savedValue = savedRegs.takeAnyValue();
|
||||
|
||||
Label maybeNegZero, revertRegister;
|
||||
|
@ -5132,9 +5132,9 @@ MacroAssemblerARMCompat::asMasm() const
|
||||
// Stack manipulation functions.
|
||||
|
||||
void
|
||||
MacroAssembler::PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet)
|
||||
MacroAssembler::PushRegsInMask(LiveRegisterSet set, LiveFloatRegisterSet simdSet)
|
||||
{
|
||||
MOZ_ASSERT(!SupportsSimd() && simdSet.size() == 0);
|
||||
MOZ_ASSERT(!SupportsSimd() && simdSet.set().size() == 0);
|
||||
int32_t diffF = set.fpus().getPushSizeInBytes();
|
||||
int32_t diffG = set.gprs().size() * sizeof(intptr_t);
|
||||
|
||||
@ -5161,9 +5161,10 @@ MacroAssembler::PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet)
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore, FloatRegisterSet simdSet)
|
||||
MacroAssembler::PopRegsInMaskIgnore(LiveRegisterSet set, LiveRegisterSet ignore,
|
||||
LiveFloatRegisterSet simdSet)
|
||||
{
|
||||
MOZ_ASSERT(!SupportsSimd() && simdSet.size() == 0);
|
||||
MOZ_ASSERT(!SupportsSimd() && simdSet.set().size() == 0);
|
||||
int32_t diffG = set.gprs().size() * sizeof(intptr_t);
|
||||
int32_t diffF = set.fpus().getPushSizeInBytes();
|
||||
const int32_t reservedG = diffG;
|
||||
@ -5171,12 +5172,12 @@ MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore, FloatRe
|
||||
|
||||
// ARM can load multiple registers at once, but only if we want back all
|
||||
// the registers we previously saved to the stack.
|
||||
if (ignore.empty(true)) {
|
||||
if (ignore.emptyFloat()) {
|
||||
diffF -= transferMultipleByRuns(set.fpus(), IsLoad, StackPointer, IA);
|
||||
adjustFrame(-reservedF);
|
||||
} else {
|
||||
TypedRegisterSet<VFPRegister> fpset = set.fpus().reduceSetForPush();
|
||||
TypedRegisterSet<VFPRegister> fpignore = ignore.fpus().reduceSetForPush();
|
||||
LiveFloatRegisterSet fpset(set.fpus().reduceSetForPush());
|
||||
LiveFloatRegisterSet fpignore(ignore.fpus().reduceSetForPush());
|
||||
for (FloatRegisterBackwardIterator iter(fpset); iter.more(); iter++) {
|
||||
diffF -= (*iter).size();
|
||||
if (!fpignore.has(*iter))
|
||||
@ -5186,7 +5187,7 @@ MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore, FloatRe
|
||||
}
|
||||
MOZ_ASSERT(diffF == 0);
|
||||
|
||||
if (set.gprs().size() > 1 && ignore.empty(false)) {
|
||||
if (set.gprs().size() > 1 && ignore.emptyGeneral()) {
|
||||
startDataTransferM(IsLoad, StackPointer, IA, WriteBack);
|
||||
for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++) {
|
||||
diffG -= sizeof(intptr_t);
|
||||
|
@ -205,7 +205,7 @@ JitRuntime::generateEnterJIT(JSContext *cx, EnterJitType type)
|
||||
Label returnLabel;
|
||||
if (type == EnterJitBaseline) {
|
||||
// Handle OSR.
|
||||
GeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
regs.take(JSReturnOperand);
|
||||
regs.takeUnchecked(OsrFrameReg);
|
||||
regs.take(r11);
|
||||
@ -725,7 +725,7 @@ JitRuntime::generateVMWrapper(JSContext *cx, const VMFunction &f)
|
||||
|
||||
// Generate a separated code for the wrapper.
|
||||
MacroAssembler masm(cx);
|
||||
GeneralRegisterSet regs = GeneralRegisterSet(Register::Codes::WrapperMask);
|
||||
AllocatableGeneralRegisterSet regs(GeneralRegisterSet(Register::Codes::WrapperMask));
|
||||
|
||||
// Wrapper register set is a superset of Volatile register set.
|
||||
JS_STATIC_ASSERT((Register::Codes::VolatileMask & ~Register::Codes::WrapperMask) == 0);
|
||||
@ -904,13 +904,13 @@ JitRuntime::generatePreBarrier(JSContext *cx, MIRType type)
|
||||
{
|
||||
MacroAssembler masm(cx);
|
||||
|
||||
RegisterSet save;
|
||||
LiveRegisterSet save;
|
||||
if (cx->runtime()->jitSupportsFloatingPoint) {
|
||||
save = RegisterSet(GeneralRegisterSet(Registers::VolatileMask),
|
||||
FloatRegisterSet(FloatRegisters::VolatileDoubleMask));
|
||||
save.set() = RegisterSet(GeneralRegisterSet(Registers::VolatileMask),
|
||||
FloatRegisterSet(FloatRegisters::VolatileDoubleMask));
|
||||
} else {
|
||||
save = RegisterSet(GeneralRegisterSet(Registers::VolatileMask),
|
||||
FloatRegisterSet());
|
||||
save.set() = RegisterSet(GeneralRegisterSet(Registers::VolatileMask),
|
||||
FloatRegisterSet());
|
||||
}
|
||||
save.add(lr);
|
||||
masm.PushRegsInMask(save);
|
||||
|
@ -59,9 +59,8 @@ JitCode *JitRuntime::generateProfilerExitFrameTailStub(JSContext *) { MOZ_CRASH(
|
||||
// ===============================================================
|
||||
// Stack manipulation functions.
|
||||
|
||||
void MacroAssembler::PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet) { MOZ_CRASH(); }
|
||||
void MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore,
|
||||
FloatRegisterSet simdSet)
|
||||
void MacroAssembler::PushRegsInMask(LiveRegisterSet, LiveFloatRegisterSet) { MOZ_CRASH(); }
|
||||
void MacroAssembler::PopRegsInMaskIgnore(LiveRegisterSet, LiveRegisterSet, LiveFloatRegisterSet)
|
||||
{
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
@ -1053,8 +1053,8 @@ class AssemblerX86Shared : public AssemblerShared
|
||||
masm.setCC_r(static_cast<X86Encoding::Condition>(cond), r.code());
|
||||
}
|
||||
void testb(Register rhs, Register lhs) {
|
||||
MOZ_ASSERT(GeneralRegisterSet(Registers::SingleByteRegs).has(rhs));
|
||||
MOZ_ASSERT(GeneralRegisterSet(Registers::SingleByteRegs).has(lhs));
|
||||
MOZ_ASSERT(AllocatableGeneralRegisterSet(Registers::SingleByteRegs).has(rhs));
|
||||
MOZ_ASSERT(AllocatableGeneralRegisterSet(Registers::SingleByteRegs).has(lhs));
|
||||
masm.testb_rr(rhs.code(), lhs.code());
|
||||
}
|
||||
void testw(Register rhs, Register lhs) {
|
||||
|
@ -159,7 +159,7 @@ CodeGeneratorShared::restoreLive(LInstruction *ins)
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorShared::restoreLiveIgnore(LInstruction *ins, RegisterSet ignore)
|
||||
CodeGeneratorShared::restoreLiveIgnore(LInstruction *ins, LiveRegisterSet ignore)
|
||||
{
|
||||
MOZ_ASSERT(!ins->isCall());
|
||||
LSafepoint *safepoint = ins->safepoint();
|
||||
@ -171,7 +171,8 @@ CodeGeneratorShared::saveLiveVolatile(LInstruction *ins)
|
||||
{
|
||||
MOZ_ASSERT(!ins->isCall());
|
||||
LSafepoint *safepoint = ins->safepoint();
|
||||
RegisterSet regs = RegisterSet::Intersect(safepoint->liveRegs(), RegisterSet::Volatile());
|
||||
LiveRegisterSet regs;
|
||||
regs.set() = RegisterSet::Intersect(safepoint->liveRegs().set(), RegisterSet::Volatile());
|
||||
masm.PushRegsInMask(regs);
|
||||
}
|
||||
|
||||
@ -180,7 +181,8 @@ CodeGeneratorShared::restoreLiveVolatile(LInstruction *ins)
|
||||
{
|
||||
MOZ_ASSERT(!ins->isCall());
|
||||
LSafepoint *safepoint = ins->safepoint();
|
||||
RegisterSet regs = RegisterSet::Intersect(safepoint->liveRegs(), RegisterSet::Volatile());
|
||||
LiveRegisterSet regs;
|
||||
regs.set() = RegisterSet::Intersect(safepoint->liveRegs().set(), RegisterSet::Volatile());
|
||||
masm.PopRegsInMask(regs);
|
||||
}
|
||||
|
||||
|
@ -1048,7 +1048,7 @@ CodeGeneratorShared::markOsiPoint(LOsiPoint *ins)
|
||||
#ifdef CHECK_OSIPOINT_REGISTERS
|
||||
template <class Op>
|
||||
static void
|
||||
HandleRegisterDump(Op op, MacroAssembler &masm, RegisterSet liveRegs, Register activation,
|
||||
HandleRegisterDump(Op op, MacroAssembler &masm, LiveRegisterSet liveRegs, Register activation,
|
||||
Register scratch)
|
||||
{
|
||||
const size_t baseOffset = JitActivation::offsetOfRegs();
|
||||
@ -1107,14 +1107,14 @@ class StoreOp
|
||||
};
|
||||
|
||||
static void
|
||||
StoreAllLiveRegs(MacroAssembler &masm, RegisterSet liveRegs)
|
||||
StoreAllLiveRegs(MacroAssembler &masm, LiveRegisterSet liveRegs)
|
||||
{
|
||||
// Store a copy of all live registers before performing the call.
|
||||
// When we reach the OsiPoint, we can use this to check nothing
|
||||
// modified them in the meantime.
|
||||
|
||||
// Load pointer to the JitActivation in a scratch register.
|
||||
GeneralRegisterSet allRegs(GeneralRegisterSet::All());
|
||||
AllocatableGeneralRegisterSet allRegs(GeneralRegisterSet::All());
|
||||
Register scratch = allRegs.takeAny();
|
||||
masm.push(scratch);
|
||||
masm.loadJitActivation(scratch);
|
||||
@ -1164,7 +1164,7 @@ CodeGeneratorShared::verifyOsiPointRegs(LSafepoint *safepoint)
|
||||
// the call and this OsiPoint. Try-catch relies on this invariant.
|
||||
|
||||
// Load pointer to the JitActivation in a scratch register.
|
||||
GeneralRegisterSet allRegs(GeneralRegisterSet::All());
|
||||
AllocatableGeneralRegisterSet allRegs(GeneralRegisterSet::All());
|
||||
Register scratch = allRegs.takeAny();
|
||||
masm.push(scratch);
|
||||
masm.loadJitActivation(scratch);
|
||||
@ -1191,8 +1191,9 @@ CodeGeneratorShared::verifyOsiPointRegs(LSafepoint *safepoint)
|
||||
// instructions (including this OsiPoint) will depend on them. Also
|
||||
// backtracking can also use the same register for an input and an output.
|
||||
// These are marked as clobbered and shouldn't get checked.
|
||||
RegisterSet liveRegs = safepoint->liveRegs();
|
||||
liveRegs = RegisterSet::Intersect(liveRegs, RegisterSet::Not(safepoint->clobberedRegs()));
|
||||
LiveRegisterSet liveRegs;
|
||||
liveRegs.set() = RegisterSet::Intersect(safepoint->liveRegs().set(),
|
||||
RegisterSet::Not(safepoint->clobberedRegs().set()));
|
||||
|
||||
VerifyOp op(masm, &failure);
|
||||
HandleRegisterDump<VerifyOp>(op, masm, liveRegs, scratch, allRegs.getAny());
|
||||
@ -1230,7 +1231,7 @@ CodeGeneratorShared::shouldVerifyOsiPointRegs(LSafepoint *safepoint)
|
||||
if (!checkOsiPointRegisters)
|
||||
return false;
|
||||
|
||||
if (safepoint->liveRegs().empty(true) && safepoint->liveRegs().empty(false))
|
||||
if (safepoint->liveRegs().emptyGeneral() && safepoint->liveRegs().emptyFloat())
|
||||
return false; // No registers to check.
|
||||
|
||||
return true;
|
||||
@ -1244,7 +1245,7 @@ CodeGeneratorShared::resetOsiPointRegs(LSafepoint *safepoint)
|
||||
|
||||
// Set checkRegs to 0. If we perform a VM call, the instruction
|
||||
// will set it to 1.
|
||||
GeneralRegisterSet allRegs(GeneralRegisterSet::All());
|
||||
AllocatableGeneralRegisterSet allRegs(GeneralRegisterSet::All());
|
||||
Register scratch = allRegs.takeAny();
|
||||
masm.push(scratch);
|
||||
masm.loadJitActivation(scratch);
|
||||
@ -1645,9 +1646,9 @@ CodeGeneratorShared::emitTracelogScript(bool isStart)
|
||||
|
||||
Label done;
|
||||
|
||||
RegisterSet regs = RegisterSet::Volatile();
|
||||
Register logger = regs.takeGeneral();
|
||||
Register script = regs.takeGeneral();
|
||||
AllocatableRegisterSet regs(RegisterSet::Volatile());
|
||||
Register logger = regs.takeAnyGeneral();
|
||||
Register script = regs.takeAnyGeneral();
|
||||
|
||||
masm.Push(logger);
|
||||
|
||||
@ -1681,8 +1682,8 @@ CodeGeneratorShared::emitTracelogTree(bool isStart, uint32_t textId)
|
||||
return;
|
||||
|
||||
Label done;
|
||||
RegisterSet regs = RegisterSet::Volatile();
|
||||
Register logger = regs.takeGeneral();
|
||||
AllocatableRegisterSet regs(RegisterSet::Volatile());
|
||||
Register logger = regs.takeAnyGeneral();
|
||||
|
||||
masm.Push(logger);
|
||||
|
||||
|
@ -407,36 +407,36 @@ class CodeGeneratorShared : public LElementVisitor
|
||||
// instruction [this is purely an optimization]. All other volatiles must
|
||||
// be saved and restored in case future LIR instructions need those values.)
|
||||
void saveVolatile(Register output) {
|
||||
RegisterSet regs = RegisterSet::Volatile();
|
||||
LiveRegisterSet regs(RegisterSet::Volatile());
|
||||
regs.takeUnchecked(output);
|
||||
masm.PushRegsInMask(regs);
|
||||
}
|
||||
void restoreVolatile(Register output) {
|
||||
RegisterSet regs = RegisterSet::Volatile();
|
||||
LiveRegisterSet regs(RegisterSet::Volatile());
|
||||
regs.takeUnchecked(output);
|
||||
masm.PopRegsInMask(regs);
|
||||
}
|
||||
void saveVolatile(FloatRegister output) {
|
||||
RegisterSet regs = RegisterSet::Volatile();
|
||||
LiveRegisterSet regs(RegisterSet::Volatile());
|
||||
regs.takeUnchecked(output);
|
||||
masm.PushRegsInMask(regs);
|
||||
}
|
||||
void restoreVolatile(FloatRegister output) {
|
||||
RegisterSet regs = RegisterSet::Volatile();
|
||||
LiveRegisterSet regs(RegisterSet::Volatile());
|
||||
regs.takeUnchecked(output);
|
||||
masm.PopRegsInMask(regs);
|
||||
}
|
||||
void saveVolatile(RegisterSet temps) {
|
||||
masm.PushRegsInMask(RegisterSet::VolatileNot(temps));
|
||||
void saveVolatile(LiveRegisterSet temps) {
|
||||
masm.PushRegsInMask(LiveRegisterSet(RegisterSet::VolatileNot(temps.set())));
|
||||
}
|
||||
void restoreVolatile(RegisterSet temps) {
|
||||
masm.PopRegsInMask(RegisterSet::VolatileNot(temps));
|
||||
void restoreVolatile(LiveRegisterSet temps) {
|
||||
masm.PopRegsInMask(LiveRegisterSet(RegisterSet::VolatileNot(temps.set())));
|
||||
}
|
||||
void saveVolatile() {
|
||||
masm.PushRegsInMask(RegisterSet::Volatile());
|
||||
masm.PushRegsInMask(LiveRegisterSet(RegisterSet::Volatile()));
|
||||
}
|
||||
void restoreVolatile() {
|
||||
masm.PopRegsInMask(RegisterSet::Volatile());
|
||||
masm.PopRegsInMask(LiveRegisterSet(RegisterSet::Volatile()));
|
||||
}
|
||||
|
||||
// These functions have to be called before and after any callVM and before
|
||||
@ -445,7 +445,7 @@ class CodeGeneratorShared : public LElementVisitor
|
||||
// frame produced by callVM.
|
||||
inline void saveLive(LInstruction *ins);
|
||||
inline void restoreLive(LInstruction *ins);
|
||||
inline void restoreLiveIgnore(LInstruction *ins, RegisterSet reg);
|
||||
inline void restoreLiveIgnore(LInstruction *ins, LiveRegisterSet reg);
|
||||
|
||||
// Save/restore all registers that are both live and volatile.
|
||||
inline void saveLiveVolatile(LInstruction *ins);
|
||||
@ -683,8 +683,8 @@ struct StoreNothing
|
||||
{
|
||||
inline void generate(CodeGeneratorShared *codegen) const {
|
||||
}
|
||||
inline RegisterSet clobbered() const {
|
||||
return RegisterSet(); // No register gets clobbered
|
||||
inline LiveRegisterSet clobbered() const {
|
||||
return LiveRegisterSet(); // No register gets clobbered
|
||||
}
|
||||
};
|
||||
|
||||
@ -701,8 +701,8 @@ class StoreRegisterTo
|
||||
inline void generate(CodeGeneratorShared *codegen) const {
|
||||
codegen->storeResultTo(out_);
|
||||
}
|
||||
inline RegisterSet clobbered() const {
|
||||
RegisterSet set = RegisterSet();
|
||||
inline LiveRegisterSet clobbered() const {
|
||||
LiveRegisterSet set;
|
||||
set.add(out_);
|
||||
return set;
|
||||
}
|
||||
@ -721,8 +721,8 @@ class StoreFloatRegisterTo
|
||||
inline void generate(CodeGeneratorShared *codegen) const {
|
||||
codegen->storeFloatResultTo(out_);
|
||||
}
|
||||
inline RegisterSet clobbered() const {
|
||||
RegisterSet set = RegisterSet();
|
||||
inline LiveRegisterSet clobbered() const {
|
||||
LiveRegisterSet set;
|
||||
set.add(out_);
|
||||
return set;
|
||||
}
|
||||
@ -742,8 +742,8 @@ class StoreValueTo_
|
||||
inline void generate(CodeGeneratorShared *codegen) const {
|
||||
codegen->storeResultValueTo(out_);
|
||||
}
|
||||
inline RegisterSet clobbered() const {
|
||||
RegisterSet set = RegisterSet();
|
||||
inline LiveRegisterSet clobbered() const {
|
||||
LiveRegisterSet set;
|
||||
set.add(out_);
|
||||
return set;
|
||||
}
|
||||
|
@ -179,12 +179,12 @@ MacroAssemblerX86Shared::asMasm() const
|
||||
// Stack manipulation functions.
|
||||
|
||||
void
|
||||
MacroAssembler::PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet)
|
||||
MacroAssembler::PushRegsInMask(LiveRegisterSet set, LiveFloatRegisterSet simdSet)
|
||||
{
|
||||
FloatRegisterSet doubleSet(FloatRegisterSet::Subtract(set.fpus(), simdSet));
|
||||
FloatRegisterSet doubleSet(FloatRegisterSet::Subtract(set.fpus(), simdSet.set()));
|
||||
MOZ_ASSERT_IF(simdSet.empty(), doubleSet == set.fpus());
|
||||
doubleSet = doubleSet.reduceSetForPush();
|
||||
unsigned numSimd = simdSet.size();
|
||||
unsigned numSimd = simdSet.set().size();
|
||||
unsigned numDouble = doubleSet.size();
|
||||
int32_t diffF = doubleSet.getPushSizeInBytes() + numSimd * Simd128DataSize;
|
||||
int32_t diffG = set.gprs().size() * sizeof(intptr_t);
|
||||
@ -229,12 +229,13 @@ MacroAssembler::PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet)
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore, FloatRegisterSet simdSet)
|
||||
MacroAssembler::PopRegsInMaskIgnore(LiveRegisterSet set, LiveRegisterSet ignore,
|
||||
LiveFloatRegisterSet simdSet)
|
||||
{
|
||||
FloatRegisterSet doubleSet(FloatRegisterSet::Subtract(set.fpus(), simdSet));
|
||||
FloatRegisterSet doubleSet(FloatRegisterSet::Subtract(set.fpus(), simdSet.set()));
|
||||
MOZ_ASSERT_IF(simdSet.empty(), doubleSet == set.fpus());
|
||||
doubleSet = doubleSet.reduceSetForPush();
|
||||
unsigned numSimd = simdSet.size();
|
||||
unsigned numSimd = simdSet.set().size();
|
||||
unsigned numDouble = doubleSet.size();
|
||||
int32_t diffG = set.gprs().size() * sizeof(intptr_t);
|
||||
int32_t diffF = doubleSet.getPushSizeInBytes() + numSimd * Simd128DataSize;
|
||||
@ -278,7 +279,7 @@ MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore, FloatRe
|
||||
// On x86, use pop to pop the integer registers, if we're not going to
|
||||
// ignore any slots, as it's fast on modern hardware and it's a small
|
||||
// instruction.
|
||||
if (ignore.empty(false)) {
|
||||
if (ignore.emptyGeneral()) {
|
||||
for (GeneralRegisterForwardIterator iter(set.gprs()); iter.more(); iter++) {
|
||||
diffG -= sizeof(intptr_t);
|
||||
Pop(*iter);
|
||||
|
@ -17,16 +17,16 @@
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
#define CHECK_BYTEREG(reg) \
|
||||
JS_BEGIN_MACRO \
|
||||
GeneralRegisterSet byteRegs(Registers::SingleByteRegs); \
|
||||
MOZ_ASSERT(byteRegs.has(reg)); \
|
||||
#define CHECK_BYTEREG(reg) \
|
||||
JS_BEGIN_MACRO \
|
||||
AllocatableGeneralRegisterSet byteRegs(Registers::SingleByteRegs); \
|
||||
MOZ_ASSERT(byteRegs.has(reg)); \
|
||||
JS_END_MACRO
|
||||
#define CHECK_BYTEREGS(r1, r2) \
|
||||
JS_BEGIN_MACRO \
|
||||
GeneralRegisterSet byteRegs(Registers::SingleByteRegs); \
|
||||
MOZ_ASSERT(byteRegs.has(r1)); \
|
||||
MOZ_ASSERT(byteRegs.has(r2)); \
|
||||
#define CHECK_BYTEREGS(r1, r2) \
|
||||
JS_BEGIN_MACRO \
|
||||
AllocatableGeneralRegisterSet byteRegs(Registers::SingleByteRegs); \
|
||||
MOZ_ASSERT(byteRegs.has(r1)); \
|
||||
MOZ_ASSERT(byteRegs.has(r2)); \
|
||||
JS_END_MACRO
|
||||
#else
|
||||
#define CHECK_BYTEREG(reg) (void)0
|
||||
@ -728,7 +728,7 @@ class MacroAssemblerX86Shared : public Assembler
|
||||
AutoEnsureByteRegister(MacroAssemblerX86Shared *masm, T address, Register reg)
|
||||
: masm(masm), original_(reg)
|
||||
{
|
||||
GeneralRegisterSet singleByteRegs(Registers::SingleByteRegs);
|
||||
AllocatableGeneralRegisterSet singleByteRegs(Registers::SingleByteRegs);
|
||||
if (singleByteRegs.has(reg)) {
|
||||
substitute_ = reg;
|
||||
} else {
|
||||
@ -1397,7 +1397,7 @@ class MacroAssemblerX86Shared : public Assembler
|
||||
|
||||
void emitSet(Assembler::Condition cond, Register dest,
|
||||
Assembler::NaNCond ifNaN = Assembler::NaN_HandledByCond) {
|
||||
if (GeneralRegisterSet(Registers::SingleByteRegs).has(dest)) {
|
||||
if (AllocatableGeneralRegisterSet(Registers::SingleByteRegs).has(dest)) {
|
||||
// If the register we're defining is a single byte register,
|
||||
// take advantage of the setCC instruction
|
||||
setCC(cond, dest);
|
||||
|
@ -307,12 +307,22 @@ Assembler::TraceJumpRelocations(JSTracer *trc, JitCode *code, CompactBufferReade
|
||||
FloatRegisterSet
|
||||
FloatRegister::ReduceSetForPush(const FloatRegisterSet &s)
|
||||
{
|
||||
if (JitSupportsSimd())
|
||||
return s;
|
||||
SetType bits = s.bits();
|
||||
|
||||
// Ignore all SIMD register.
|
||||
return FloatRegisterSet(s.bits() & (Codes::AllPhysMask * Codes::SpreadScalar));
|
||||
// Ignore all SIMD register, if not supported.
|
||||
if (!JitSupportsSimd())
|
||||
bits &= Codes::AllPhysMask * Codes::SpreadScalar;
|
||||
|
||||
// Exclude registers which are already pushed with a larger type. High bits
|
||||
// are associated with larger register types. Thus we keep the set of
|
||||
// registers which are not included in larger type.
|
||||
bits &= ~(bits >> (1 * Codes::TotalPhys));
|
||||
bits &= ~(bits >> (2 * Codes::TotalPhys));
|
||||
bits &= ~(bits >> (3 * Codes::TotalPhys));
|
||||
|
||||
return FloatRegisterSet(bits);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
FloatRegister::GetPushSizeInBytes(const FloatRegisterSet &s)
|
||||
{
|
||||
|
@ -19,9 +19,9 @@ using namespace js::jit;
|
||||
|
||||
// All registers to save and restore. This includes the stack pointer, since we
|
||||
// use the ability to reference register values on the stack by index.
|
||||
static const RegisterSet AllRegs =
|
||||
RegisterSet(GeneralRegisterSet(Registers::AllMask),
|
||||
FloatRegisterSet(FloatRegisters::AllMask));
|
||||
static const LiveRegisterSet AllRegs =
|
||||
LiveRegisterSet(GeneralRegisterSet(Registers::AllMask),
|
||||
FloatRegisterSet(FloatRegisters::AllMask));
|
||||
|
||||
// Generates a trampoline for calling Jit compiled code from a C++ function.
|
||||
// The trampoline use the EnterJitCode signature, with the standard x64 fastcall
|
||||
@ -150,7 +150,7 @@ JitRuntime::generateEnterJIT(JSContext *cx, EnterJitType type)
|
||||
CodeLabel returnLabel;
|
||||
if (type == EnterJitBaseline) {
|
||||
// Handle OSR.
|
||||
GeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
regs.takeUnchecked(OsrFrameReg);
|
||||
regs.take(rbp);
|
||||
regs.take(reg_code);
|
||||
@ -516,12 +516,11 @@ PushBailoutFrame(MacroAssembler &masm, Register spArg)
|
||||
// the float registers to have the maximal possible size
|
||||
// (Simd128DataSize). To work around this, we just spill the double
|
||||
// registers by hand here, using the register dump offset directly.
|
||||
RegisterSet set = AllRegs;
|
||||
for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++)
|
||||
for (GeneralRegisterBackwardIterator iter(AllRegs.gprs()); iter.more(); iter++)
|
||||
masm.Push(*iter);
|
||||
|
||||
masm.reserveStack(sizeof(RegisterDump::FPUArray));
|
||||
for (FloatRegisterBackwardIterator iter(set.fpus()); iter.more(); iter++) {
|
||||
for (FloatRegisterBackwardIterator iter(AllRegs.fpus()); iter.more(); iter++) {
|
||||
FloatRegister reg = *iter;
|
||||
Address spillAddress(StackPointer, reg.getRegisterDumpOffsetInBytes());
|
||||
masm.storeDouble(reg, spillAddress);
|
||||
@ -602,7 +601,7 @@ JitRuntime::generateVMWrapper(JSContext *cx, const VMFunction &f)
|
||||
|
||||
// Avoid conflicts with argument registers while discarding the result after
|
||||
// the function call.
|
||||
GeneralRegisterSet regs = GeneralRegisterSet(Register::Codes::WrapperMask);
|
||||
AllocatableGeneralRegisterSet regs(Register::Codes::WrapperMask);
|
||||
|
||||
// Wrapper register set is a superset of Volatile register set.
|
||||
JS_STATIC_ASSERT((Register::Codes::VolatileMask & ~Register::Codes::WrapperMask) == 0);
|
||||
@ -777,8 +776,9 @@ JitRuntime::generatePreBarrier(JSContext *cx, MIRType type)
|
||||
{
|
||||
MacroAssembler masm;
|
||||
|
||||
RegisterSet regs = RegisterSet(GeneralRegisterSet(Registers::VolatileMask),
|
||||
FloatRegisterSet(FloatRegisters::VolatileMask));
|
||||
LiveRegisterSet regs =
|
||||
LiveRegisterSet(GeneralRegisterSet(Registers::VolatileMask),
|
||||
FloatRegisterSet(FloatRegisters::VolatileMask));
|
||||
masm.PushRegsInMask(regs);
|
||||
|
||||
MOZ_ASSERT(PreBarrierReg == rdx);
|
||||
|
@ -105,12 +105,22 @@ Assembler::TraceJumpRelocations(JSTracer *trc, JitCode *code, CompactBufferReade
|
||||
FloatRegisterSet
|
||||
FloatRegister::ReduceSetForPush(const FloatRegisterSet &s)
|
||||
{
|
||||
if (JitSupportsSimd())
|
||||
return s;
|
||||
SetType bits = s.bits();
|
||||
|
||||
// Ignore all SIMD register.
|
||||
return FloatRegisterSet(s.bits() & (Codes::AllPhysMask * Codes::SpreadScalar));
|
||||
// Ignore all SIMD register, if not supported.
|
||||
if (!JitSupportsSimd())
|
||||
bits &= Codes::AllPhysMask * Codes::SpreadScalar;
|
||||
|
||||
// Exclude registers which are already pushed with a larger type. High bits
|
||||
// are associated with larger register types. Thus we keep the set of
|
||||
// registers which are not included in larger type.
|
||||
bits &= ~(bits >> (1 * Codes::TotalPhys));
|
||||
bits &= ~(bits >> (2 * Codes::TotalPhys));
|
||||
bits &= ~(bits >> (3 * Codes::TotalPhys));
|
||||
|
||||
return FloatRegisterSet(bits);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
FloatRegister::GetPushSizeInBytes(const FloatRegisterSet &s)
|
||||
{
|
||||
|
@ -25,9 +25,9 @@ using namespace js::jit;
|
||||
|
||||
// All registers to save and restore. This includes the stack pointer, since we
|
||||
// use the ability to reference register values on the stack by index.
|
||||
static const RegisterSet AllRegs =
|
||||
RegisterSet(GeneralRegisterSet(Registers::AllMask),
|
||||
FloatRegisterSet(FloatRegisters::AllMask));
|
||||
static const LiveRegisterSet AllRegs =
|
||||
LiveRegisterSet(GeneralRegisterSet(Registers::AllMask),
|
||||
FloatRegisterSet(FloatRegisters::AllMask));
|
||||
|
||||
enum EnterJitEbpArgumentOffset {
|
||||
ARG_JITCODE = 2 * sizeof(void *),
|
||||
@ -142,7 +142,7 @@ JitRuntime::generateEnterJIT(JSContext *cx, EnterJitType type)
|
||||
CodeLabel returnLabel;
|
||||
if (type == EnterJitBaseline) {
|
||||
// Handle OSR.
|
||||
GeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
regs.take(JSReturnOperand);
|
||||
regs.takeUnchecked(OsrFrameReg);
|
||||
regs.take(ebp);
|
||||
@ -510,12 +510,11 @@ PushBailoutFrame(MacroAssembler &masm, uint32_t frameClass, Register spArg)
|
||||
// the float registers to have the maximal possible size
|
||||
// (Simd128DataSize). To work around this, we just spill the double
|
||||
// registers by hand here, using the register dump offset directly.
|
||||
RegisterSet set = AllRegs;
|
||||
for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++)
|
||||
for (GeneralRegisterBackwardIterator iter(AllRegs.gprs()); iter.more(); iter++)
|
||||
masm.Push(*iter);
|
||||
|
||||
masm.reserveStack(sizeof(RegisterDump::FPUArray));
|
||||
for (FloatRegisterBackwardIterator iter(set.fpus()); iter.more(); iter++) {
|
||||
for (FloatRegisterBackwardIterator iter(AllRegs.fpus()); iter.more(); iter++) {
|
||||
FloatRegister reg = *iter;
|
||||
Address spillAddress(StackPointer, reg.getRegisterDumpOffsetInBytes());
|
||||
masm.storeDouble(reg, spillAddress);
|
||||
@ -628,7 +627,7 @@ JitRuntime::generateVMWrapper(JSContext *cx, const VMFunction &f)
|
||||
|
||||
// Avoid conflicts with argument registers while discarding the result after
|
||||
// the function call.
|
||||
GeneralRegisterSet regs = GeneralRegisterSet(Register::Codes::WrapperMask);
|
||||
AllocatableGeneralRegisterSet regs(Register::Codes::WrapperMask);
|
||||
|
||||
// Wrapper register set is a superset of Volatile register set.
|
||||
JS_STATIC_ASSERT((Register::Codes::VolatileMask & ~Register::Codes::WrapperMask) == 0);
|
||||
@ -798,13 +797,13 @@ JitRuntime::generatePreBarrier(JSContext *cx, MIRType type)
|
||||
{
|
||||
MacroAssembler masm;
|
||||
|
||||
RegisterSet save;
|
||||
LiveRegisterSet save;
|
||||
if (cx->runtime()->jitSupportsFloatingPoint) {
|
||||
save = RegisterSet(GeneralRegisterSet(Registers::VolatileMask),
|
||||
FloatRegisterSet(FloatRegisters::VolatileMask));
|
||||
save.set() = RegisterSet(GeneralRegisterSet(Registers::VolatileMask),
|
||||
FloatRegisterSet(FloatRegisters::VolatileMask));
|
||||
} else {
|
||||
save = RegisterSet(GeneralRegisterSet(Registers::VolatileMask),
|
||||
FloatRegisterSet());
|
||||
save.set() = RegisterSet(GeneralRegisterSet(Registers::VolatileMask),
|
||||
FloatRegisterSet());
|
||||
}
|
||||
masm.PushRegsInMask(save);
|
||||
|
||||
|
@ -47,8 +47,8 @@ BEGIN_TEST(testJitRegisterSet_GPR)
|
||||
{
|
||||
BEGIN_INDEX_WALK(Registers::Total)
|
||||
|
||||
LiveSet<GeneralRegisterSet> liveRegs;
|
||||
Allocator<GeneralRegisterSet> pool(GeneralRegisterSet::All());
|
||||
LiveGeneralRegisterSet liveRegs;
|
||||
AllocatableGeneralRegisterSet pool(GeneralRegisterSet::All());
|
||||
CHECK(liveRegs.empty());
|
||||
CHECK(pool.set() == GeneralRegisterSet::All());
|
||||
|
||||
@ -94,8 +94,8 @@ BEGIN_TEST(testJitRegisterSet_FPU)
|
||||
{
|
||||
BEGIN_INDEX_WALK(FloatRegisters::Total)
|
||||
|
||||
LiveSet<FloatRegisterSet> liveRegs;
|
||||
Allocator<FloatRegisterSet> pool(FloatRegisterSet::All());
|
||||
LiveFloatRegisterSet liveRegs;
|
||||
AllocatableFloatRegisterSet pool(FloatRegisterSet::All());
|
||||
CHECK(liveRegs.empty());
|
||||
CHECK(pool.set() == FloatRegisterSet::All());
|
||||
|
||||
|
@ -100,12 +100,12 @@ UnboxedLayout::makeConstructorCode(JSContext *cx, HandleObjectGroup group)
|
||||
MOZ_ASSERT(propertiesReg.volatile_());
|
||||
MOZ_ASSERT(newKindReg.volatile_());
|
||||
|
||||
GeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
regs.take(propertiesReg);
|
||||
regs.take(newKindReg);
|
||||
Register object = regs.takeAny(), scratch1 = regs.takeAny(), scratch2 = regs.takeAny();
|
||||
|
||||
GeneralRegisterSet savedNonVolatileRegisters = SavedNonVolatileRegisters(regs);
|
||||
LiveGeneralRegisterSet savedNonVolatileRegisters = SavedNonVolatileRegisters(regs);
|
||||
for (GeneralRegisterForwardIterator iter(savedNonVolatileRegisters); iter.more(); ++iter)
|
||||
masm.Push(*iter);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user