From 030f0907b7bef4d5d6e6d0a5bd88fbedc802c0a0 Mon Sep 17 00:00:00 2001 From: "Nicolas B. Pierron" Date: Sat, 28 Mar 2015 01:08:12 +0100 Subject: [PATCH] Bug 1143011 - Use AllocatableSet or LiveSet for all register set uses. r=jandem --- js/src/asmjs/AsmJSValidate.cpp | 51 ++++--- .../irregexp/NativeRegExpMacroAssembler.cpp | 6 +- js/src/irregexp/NativeRegExpMacroAssembler.h | 4 +- js/src/jit/BacktrackingAllocator.cpp | 10 +- js/src/jit/BaselineCompiler.cpp | 13 +- js/src/jit/BaselineDebugModeOSR.cpp | 4 +- js/src/jit/BaselineIC.cpp | 128 +++++++++--------- js/src/jit/BaselineIC.h | 24 ++-- js/src/jit/CodeGenerator.cpp | 56 ++++---- js/src/jit/CodeGenerator.h | 4 +- js/src/jit/IonCaches.cpp | 100 +++++++------- js/src/jit/IonCaches.h | 16 +-- js/src/jit/JitFrames.cpp | 8 +- js/src/jit/LIR.h | 20 +-- js/src/jit/LinearScan.cpp | 29 ++-- js/src/jit/LiveRangeAllocator.cpp | 14 +- js/src/jit/MacroAssembler.cpp | 109 +++++++-------- js/src/jit/MacroAssembler.h | 22 +-- js/src/jit/RegisterAllocator.cpp | 4 +- js/src/jit/RegisterAllocator.h | 2 +- js/src/jit/RegisterSets.h | 6 +- js/src/jit/Safepoints.cpp | 10 +- js/src/jit/Safepoints.h | 20 +-- js/src/jit/StupidAllocator.cpp | 10 +- js/src/jit/arm/Architecture-arm.cpp | 6 +- js/src/jit/arm/BaselineIC-arm.cpp | 4 +- js/src/jit/arm/MacroAssembler-arm.cpp | 17 +-- js/src/jit/arm/Trampoline-arm.cpp | 14 +- js/src/jit/none/Trampoline-none.cpp | 5 +- js/src/jit/shared/Assembler-x86-shared.h | 4 +- js/src/jit/shared/CodeGenerator-shared-inl.h | 8 +- js/src/jit/shared/CodeGenerator-shared.cpp | 27 ++-- js/src/jit/shared/CodeGenerator-shared.h | 38 +++--- .../jit/shared/MacroAssembler-x86-shared.cpp | 15 +- js/src/jit/shared/MacroAssembler-x86-shared.h | 22 +-- js/src/jit/x64/Assembler-x64.cpp | 18 ++- js/src/jit/x64/Trampoline-x64.cpp | 20 +-- js/src/jit/x86/Assembler-x86.cpp | 18 ++- js/src/jit/x86/Trampoline-x86.cpp | 25 ++-- js/src/jsapi-tests/testJitRegisterSet.cpp | 8 +- js/src/vm/UnboxedObject.cpp | 4 +- 41 files changed, 487 insertions(+), 436 deletions(-) diff --git a/js/src/asmjs/AsmJSValidate.cpp b/js/src/asmjs/AsmJSValidate.cpp index ef5fa72f02b..52b7dc3daa2 100644 --- a/js/src/asmjs/AsmJSValidate.cpp +++ b/js/src/asmjs/AsmJSValidate.cpp @@ -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<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. diff --git a/js/src/jit/BaselineDebugModeOSR.cpp b/js/src/jit/BaselineDebugModeOSR.cpp index ac5bcff55c3..fb44bec7b00 100644 --- a/js/src/jit/BaselineDebugModeOSR.cpp +++ b/js/src/jit/BaselineDebugModeOSR.cpp @@ -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(); diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index 1c16950f4e4..6172722e77d 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -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(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::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( 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); diff --git a/js/src/jit/BaselineIC.h b/js/src/jit/BaselineIC.h index f7c685c5812..3db6df36f6d 100644 --- a/js/src/jit/BaselineIC.h +++ b/js/src/jit/BaselineIC.h @@ -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 diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index 32ff4c4354f..610070e1bc6 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -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 &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; diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h index caf3d52fc04..264d73da90a 100644 --- a/js/src/jit/CodeGenerator.h +++ b/js/src/jit/CodeGenerator.h @@ -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, diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp index f6a43929e98..6378d9792cb 100644 --- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -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(); 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()); @@ -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); diff --git a/js/src/jit/IonCaches.h b/js/src/jit/IonCaches.h index 2c78604f046..742e37f91b8 100644 --- a/js/src/jit/IonCaches.h +++ b/js/src/jit/IonCaches.h @@ -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), diff --git a/js/src/jit/JitFrames.cpp b/js/src/jit/JitFrames.cpp index 742392b6921..77fb7db69dd 100644 --- a/js/src/jit/JitFrames.cpp +++ b/js/src/jit/JitFrames.cpp @@ -353,7 +353,7 @@ JitFrameIterator::machineState() const uint8_t *spillAlign = alignDoubleSpillWithOffset(reinterpret_cast(spill), 0); char *floatSpill = reinterpret_cast(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; diff --git a/js/src/jit/LIR.h b/js/src/jit/LIR.h index 0d25e88d21f..001ee2adc60 100644 --- a/js/src/jit/LIR.h +++ b/js/src/jit/LIR.h @@ -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_; } diff --git a/js/src/jit/LinearScan.cpp b/js/src/jit/LinearScan.cpp index 03aa25f99bf..58c0cd70489 100644 --- a/js/src/jit/LinearScan.cpp +++ b/js/src/jit/LinearScan.cpp @@ -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(); diff --git a/js/src/jit/LiveRangeAllocator.cpp b/js/src/jit/LiveRangeAllocator.cpp index 4828f085a9d..3cb630f9eee 100644 --- a/js/src/jit/LiveRangeAllocator.cpp +++ b/js/src/jit/LiveRangeAllocator.cpp @@ -645,18 +645,10 @@ LiveRangeAllocator::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; diff --git a/js/src/jit/MacroAssembler.cpp b/js/src/jit/MacroAssembler.cpp index 758034da1c7..432be808dcc 100644 --- a/js/src/jit/MacroAssembler.cpp +++ b/js/src/jit/MacroAssembler.cpp @@ -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 diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index 0dd64f5fccf..2eebe31a4e2 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -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); diff --git a/js/src/jit/RegisterAllocator.cpp b/js/src/jit/RegisterAllocator.cpp index 968b5a4524d..c160e51195e 100644 --- a/js/src/jit/RegisterAllocator.cpp +++ b/js/src/jit/RegisterAllocator.cpp @@ -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; diff --git a/js/src/jit/RegisterAllocator.h b/js/src/jit/RegisterAllocator.h index 16b81ab8292..e1eb1198906 100644 --- a/js/src/jit/RegisterAllocator.h +++ b/js/src/jit/RegisterAllocator.h @@ -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; diff --git a/js/src/jit/RegisterSets.h b/js/src/jit/RegisterSets.h index 65dfd9278be..50996c4b407 100644 --- a/js/src/jit/RegisterSets.h +++ b/js/src/jit/RegisterSets.h @@ -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; diff --git a/js/src/jit/Safepoints.cpp b/js/src/jit/Safepoints.cpp index 71ece3d2c09..303b731d292 100644 --- a/js/src/jit/Safepoints.cpp +++ b/js/src/jit/Safepoints.cpp @@ -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()) { diff --git a/js/src/jit/Safepoints.h b/js/src/jit/Safepoints.h index e0cb4b6275b..c17d3496ea9 100644 --- a/js/src/jit/Safepoints.h +++ b/js/src/jit/Safepoints.h @@ -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; diff --git a/js/src/jit/StupidAllocator.cpp b/js/src/jit/StupidAllocator.cpp index a4e72cecaed..a78fe302f7d 100644 --- a/js/src/jit/StupidAllocator.cpp +++ b/js/src/jit/StupidAllocator.cpp @@ -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); } diff --git a/js/src/jit/arm/Architecture-arm.cpp b/js/src/jit/arm/Architecture-arm.cpp index 8d1b058ddeb..0ee59b0bb87 100644 --- a/js/src/jit/arm/Architecture-arm.cpp +++ b/js/src/jit/arm/Architecture-arm.cpp @@ -347,8 +347,8 @@ FloatRegisters::FromName(const char *name) FloatRegisterSet VFPRegister::ReduceSetForPush(const FloatRegisterSet &s) { - FloatRegisterSet mod; - for (TypedRegisterIterator 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 diff --git a/js/src/jit/arm/BaselineIC-arm.cpp b/js/src/jit/arm/BaselineIC-arm.cpp index 9fc0a543d1a..bbcceae7574 100644 --- a/js/src/jit/arm/BaselineIC-arm.cpp +++ b/js/src/jit/arm/BaselineIC-arm.cpp @@ -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; diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp index 8a362e140a6..0c27e34b5d2 100644 --- a/js/src/jit/arm/MacroAssembler-arm.cpp +++ b/js/src/jit/arm/MacroAssembler-arm.cpp @@ -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 fpset = set.fpus().reduceSetForPush(); - TypedRegisterSet 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); diff --git a/js/src/jit/arm/Trampoline-arm.cpp b/js/src/jit/arm/Trampoline-arm.cpp index 98957d5a78b..8580332f027 100644 --- a/js/src/jit/arm/Trampoline-arm.cpp +++ b/js/src/jit/arm/Trampoline-arm.cpp @@ -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); diff --git a/js/src/jit/none/Trampoline-none.cpp b/js/src/jit/none/Trampoline-none.cpp index 720ceda8789..1dbf6b712d9 100644 --- a/js/src/jit/none/Trampoline-none.cpp +++ b/js/src/jit/none/Trampoline-none.cpp @@ -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(); } diff --git a/js/src/jit/shared/Assembler-x86-shared.h b/js/src/jit/shared/Assembler-x86-shared.h index 9f542c460c5..1d5f5546ed3 100644 --- a/js/src/jit/shared/Assembler-x86-shared.h +++ b/js/src/jit/shared/Assembler-x86-shared.h @@ -1053,8 +1053,8 @@ class AssemblerX86Shared : public AssemblerShared masm.setCC_r(static_cast(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) { diff --git a/js/src/jit/shared/CodeGenerator-shared-inl.h b/js/src/jit/shared/CodeGenerator-shared-inl.h index a3d54885bd8..aaa26e0b115 100644 --- a/js/src/jit/shared/CodeGenerator-shared-inl.h +++ b/js/src/jit/shared/CodeGenerator-shared-inl.h @@ -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); } diff --git a/js/src/jit/shared/CodeGenerator-shared.cpp b/js/src/jit/shared/CodeGenerator-shared.cpp index 16ffbcd79f4..42e9a307a7d 100644 --- a/js/src/jit/shared/CodeGenerator-shared.cpp +++ b/js/src/jit/shared/CodeGenerator-shared.cpp @@ -1048,7 +1048,7 @@ CodeGeneratorShared::markOsiPoint(LOsiPoint *ins) #ifdef CHECK_OSIPOINT_REGISTERS template 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(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); diff --git a/js/src/jit/shared/CodeGenerator-shared.h b/js/src/jit/shared/CodeGenerator-shared.h index cd5b8a7ba16..9f325b97b99 100644 --- a/js/src/jit/shared/CodeGenerator-shared.h +++ b/js/src/jit/shared/CodeGenerator-shared.h @@ -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; } diff --git a/js/src/jit/shared/MacroAssembler-x86-shared.cpp b/js/src/jit/shared/MacroAssembler-x86-shared.cpp index d790fbbc901..8e5a7638558 100644 --- a/js/src/jit/shared/MacroAssembler-x86-shared.cpp +++ b/js/src/jit/shared/MacroAssembler-x86-shared.cpp @@ -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); diff --git a/js/src/jit/shared/MacroAssembler-x86-shared.h b/js/src/jit/shared/MacroAssembler-x86-shared.h index c06e4036d57..d8b825bffef 100644 --- a/js/src/jit/shared/MacroAssembler-x86-shared.h +++ b/js/src/jit/shared/MacroAssembler-x86-shared.h @@ -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); diff --git a/js/src/jit/x64/Assembler-x64.cpp b/js/src/jit/x64/Assembler-x64.cpp index 75446dadbfa..ffa877c0dec 100644 --- a/js/src/jit/x64/Assembler-x64.cpp +++ b/js/src/jit/x64/Assembler-x64.cpp @@ -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) { diff --git a/js/src/jit/x64/Trampoline-x64.cpp b/js/src/jit/x64/Trampoline-x64.cpp index 92147f84755..360b19441e8 100644 --- a/js/src/jit/x64/Trampoline-x64.cpp +++ b/js/src/jit/x64/Trampoline-x64.cpp @@ -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); diff --git a/js/src/jit/x86/Assembler-x86.cpp b/js/src/jit/x86/Assembler-x86.cpp index d073b74f241..1ad929f09dd 100644 --- a/js/src/jit/x86/Assembler-x86.cpp +++ b/js/src/jit/x86/Assembler-x86.cpp @@ -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) { diff --git a/js/src/jit/x86/Trampoline-x86.cpp b/js/src/jit/x86/Trampoline-x86.cpp index 892fdbc60c1..6be89524b7f 100644 --- a/js/src/jit/x86/Trampoline-x86.cpp +++ b/js/src/jit/x86/Trampoline-x86.cpp @@ -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); diff --git a/js/src/jsapi-tests/testJitRegisterSet.cpp b/js/src/jsapi-tests/testJitRegisterSet.cpp index 694a11db3db..61acf834ce7 100644 --- a/js/src/jsapi-tests/testJitRegisterSet.cpp +++ b/js/src/jsapi-tests/testJitRegisterSet.cpp @@ -47,8 +47,8 @@ BEGIN_TEST(testJitRegisterSet_GPR) { BEGIN_INDEX_WALK(Registers::Total) - LiveSet liveRegs; - Allocator 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 liveRegs; - Allocator pool(FloatRegisterSet::All()); + LiveFloatRegisterSet liveRegs; + AllocatableFloatRegisterSet pool(FloatRegisterSet::All()); CHECK(liveRegs.empty()); CHECK(pool.set() == FloatRegisterSet::All()); diff --git a/js/src/vm/UnboxedObject.cpp b/js/src/vm/UnboxedObject.cpp index 5a3ded31fad..e2582ce182f 100644 --- a/js/src/vm/UnboxedObject.cpp +++ b/js/src/vm/UnboxedObject.cpp @@ -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);