From 2a5a91c2c0b844d4df2d430ff560a70fa6cbb137 Mon Sep 17 00:00:00 2001 From: Sean Stangl Date: Sat, 12 Jun 2010 18:26:36 -0700 Subject: [PATCH 1/3] [JAEGER] Rename alloc() to allocReg(); r=dvander. This patch is in preparation for making a distinction between registers and floating-point registers for double fastpaths. --- js/src/methodjit/FrameState-inl.h | 30 ++++++++++++------------------ js/src/methodjit/FrameState.cpp | 14 +++++++------- js/src/methodjit/FrameState.h | 3 +-- 3 files changed, 20 insertions(+), 27 deletions(-) diff --git a/js/src/methodjit/FrameState-inl.h b/js/src/methodjit/FrameState-inl.h index 36a0f1d0915..cc14ee0b215 100644 --- a/js/src/methodjit/FrameState-inl.h +++ b/js/src/methodjit/FrameState-inl.h @@ -76,7 +76,13 @@ FrameState::popn(uint32 n) inline JSC::MacroAssembler::RegisterID FrameState::allocReg() { - return alloc(); + RegisterID reg; + if (!freeRegs.empty()) + reg = freeRegs.takeAnyReg(); + else + reg = evictSomething(); + regstate[reg].fe = NULL; + return reg; } inline JSC::MacroAssembler::RegisterID @@ -92,19 +98,7 @@ FrameState::allocReg(uint32 mask) } inline JSC::MacroAssembler::RegisterID -FrameState::alloc() -{ - RegisterID reg; - if (!freeRegs.empty()) - reg = freeRegs.takeAnyReg(); - else - reg = evictSomething(); - regstate[reg].fe = NULL; - return reg; -} - -inline JSC::MacroAssembler::RegisterID -FrameState::alloc(FrameEntry *fe, RematInfo::RematType type, bool weak) +FrameState::allocReg(FrameEntry *fe, RematInfo::RematType type, bool weak) { RegisterID reg; if (!freeRegs.empty()) @@ -218,7 +212,7 @@ FrameState::push(Address address) if (free) freeRegs.takeReg(address.base); - RegisterID reg = alloc(fe, RematInfo::DATA, true); + RegisterID reg = allocReg(fe, RematInfo::DATA, true); masm.loadData32(address, reg); fe->data.setRegister(reg); @@ -226,7 +220,7 @@ FrameState::push(Address address) if (free) freeRegs.putReg(address.base); - reg = alloc(fe, RematInfo::TYPE, true); + reg = allocReg(fe, RematInfo::TYPE, true); masm.loadTypeTag(address, reg); fe->type.setRegister(reg); } @@ -278,7 +272,7 @@ FrameState::tempRegForType(FrameEntry *fe) /* :XXX: X64 */ - RegisterID reg = alloc(fe, RematInfo::TYPE, true); + RegisterID reg = allocReg(fe, RematInfo::TYPE, true); masm.loadTypeTag(addressOf(fe), reg); fe->type.setRegister(reg); return reg; @@ -295,7 +289,7 @@ FrameState::tempRegForData(FrameEntry *fe) if (fe->data.inRegister()) return fe->data.reg(); - RegisterID reg = alloc(fe, RematInfo::DATA, true); + RegisterID reg = allocReg(fe, RematInfo::DATA, true); masm.loadData32(addressOf(fe), reg); fe->data.setRegister(reg); return reg; diff --git a/js/src/methodjit/FrameState.cpp b/js/src/methodjit/FrameState.cpp index a79075c00bd..501ffa94de1 100644 --- a/js/src/methodjit/FrameState.cpp +++ b/js/src/methodjit/FrameState.cpp @@ -194,7 +194,7 @@ FrameState::storeTo(FrameEntry *fe, Address address, bool popped) masm.storeData32(fe->data.reg(), address); } else { JS_ASSERT(fe->data.inMemory()); - RegisterID reg = popped ? alloc() : alloc(fe, RematInfo::DATA, true); + RegisterID reg = popped ? allocReg() : allocReg(fe, RematInfo::DATA, true); masm.loadData32(addressOf(fe), reg); masm.storeData32(reg, address); if (popped) @@ -209,7 +209,7 @@ FrameState::storeTo(FrameEntry *fe, Address address, bool popped) masm.storeTypeTag(fe->type.reg(), address); } else { JS_ASSERT(fe->type.inMemory()); - RegisterID reg = popped ? alloc() : alloc(fe, RematInfo::TYPE, true); + RegisterID reg = popped ? allocReg() : allocReg(fe, RematInfo::TYPE, true); masm.loadTypeTag(addressOf(fe), reg); masm.storeTypeTag(reg, address); if (popped) @@ -644,14 +644,14 @@ FrameState::copyData(FrameEntry *fe) fe->data.setMemory(); regstate[reg].fe = NULL; } else { - RegisterID newReg = alloc(); + RegisterID newReg = allocReg(); masm.move(reg, newReg); reg = newReg; } return reg; } - RegisterID reg = alloc(); + RegisterID reg = allocReg(); if (!freeRegs.empty()) masm.move(tempRegForData(fe), reg); @@ -683,7 +683,7 @@ FrameState::ownRegForData(FrameEntry *fe) backing->data.setMemory(); moveOwnership(reg, NULL); } else { - reg = alloc(); + reg = allocReg(); masm.move(backing->data.reg(), reg); } return reg; @@ -692,7 +692,7 @@ FrameState::ownRegForData(FrameEntry *fe) if (fe->isCopied()) { uncopy(fe); if (fe->isCopied()) { - reg = alloc(); + reg = allocReg(); masm.loadData32(addressOf(fe), reg); return reg; } @@ -707,7 +707,7 @@ FrameState::ownRegForData(FrameEntry *fe) fe->data.invalidate(); } else { JS_ASSERT(fe->data.inMemory()); - reg = alloc(); + reg = allocReg(); masm.loadData32(addressOf(fe), reg); } return reg; diff --git a/js/src/methodjit/FrameState.h b/js/src/methodjit/FrameState.h index 908e2f837fc..578f6192e34 100644 --- a/js/src/methodjit/FrameState.h +++ b/js/src/methodjit/FrameState.h @@ -385,8 +385,7 @@ class FrameState Address addressOf(const FrameEntry *fe) const; private: - inline RegisterID alloc(); - inline RegisterID alloc(FrameEntry *fe, RematInfo::RematType type, bool weak); + inline RegisterID allocReg(FrameEntry *fe, RematInfo::RematType type, bool weak); inline void forgetReg(RegisterID reg); RegisterID evictSomething(uint32 mask); void evictReg(RegisterID reg); From b616a53aeeaabd443ccfec9627108560c3e3d803 Mon Sep 17 00:00:00 2001 From: Sean Stangl Date: Sat, 12 Jun 2010 18:37:34 -0700 Subject: [PATCH 2/3] [JAEGER] Define FPRegisters struct; r=dvander. --- js/src/methodjit/BaseAssembler.h | 3 + js/src/methodjit/MachineRegs.h | 107 ++++++++++++++++++++++++++++++- 2 files changed, 108 insertions(+), 2 deletions(-) diff --git a/js/src/methodjit/BaseAssembler.h b/js/src/methodjit/BaseAssembler.h index d94b88efde6..62c93cce90f 100644 --- a/js/src/methodjit/BaseAssembler.h +++ b/js/src/methodjit/BaseAssembler.h @@ -88,6 +88,9 @@ class BaseAssembler : public JSC::MacroAssembler startLabel = label(); } + /* Total number of floating-point registers. */ + static const uint32 TotalFPRegisters = FPRegisters::TotalFPRegisters; + /* * FpReg is used to home the current JSStackFrame*. */ diff --git a/js/src/methodjit/MachineRegs.h b/js/src/methodjit/MachineRegs.h index d7f4e3326f3..0f4ead562e2 100644 --- a/js/src/methodjit/MachineRegs.h +++ b/js/src/methodjit/MachineRegs.h @@ -162,11 +162,11 @@ struct Registers { freeMask = AvailRegs; } - bool empty() { + bool empty() const { return !freeMask; } - bool empty(uint32 mask) { + bool empty(uint32 mask) const { return !(freeMask & mask); } @@ -214,6 +214,109 @@ struct Registers { uint32 freeMask; }; + +struct FPRegisters { + + typedef JSC::MacroAssembler::FPRegisterID FPRegisterID; + +#if defined(JS_CPU_X86) || defined(JS_CPU_X64) + static const uint32 TotalFPRegisters = 8; + static const uint32 TempFPRegs = + (1 << JSC::X86Registers::xmm0) + | (1 << JSC::X86Registers::xmm1) + | (1 << JSC::X86Registers::xmm2) + | (1 << JSC::X86Registers::xmm3) + | (1 << JSC::X86Registers::xmm4) + | (1 << JSC::X86Registers::xmm5) + | (1 << JSC::X86Registers::xmm6) + | (1 << JSC::X86Registers::xmm7); +#elif defined(JS_CPU_ARM) + static const uint32 TotalFPRegisters = 4; + static const uint32 TempFPRegs = + (1 << JSC::ARMRegisters::d0) + | (1 << JSC::ARMRegisters::d1) + | (1 << JSC::ARMRegisters::d2) + | (1 << JSC::ARMRegisters::d3); +#else +# error "Unsupported platform" +#endif + + static const uint32 AvailFPRegs = TempFPRegs; + + FPRegisters() + : freeFPMask(AvailFPRegs) + { } + + FPRegisters(uint32 freeFPMask) + : freeFPMask(freeFPMask) + { } + + FPRegisters(const FPRegisters &other) + : freeFPMask(other.freeFPMask) + { } + + FPRegisters & operator =(const FPRegisters &other) + { + freeFPMask = other.freeFPMask; + return *this; + } + + void reset() { + freeFPMask = AvailFPRegs; + } + + bool empty() const { + return !freeFPMask; + } + + bool empty(uint32 mask) const { + return !(freeFPMask & mask); + } + + FPRegisterID takeAnyReg() { + JS_ASSERT(!empty()); + FPRegisterID reg = (FPRegisterID)(31 - js_bitscan_clz32(freeFPMask)); + takeReg(reg); + return reg; + } + + bool hasRegInMask(uint32 mask) const { + FPRegisters temp(freeFPMask & mask); + return !temp.empty(); + } + + FPRegisterID takeRegInMask(uint32 mask) { + FPRegisters temp(freeFPMask & mask); + FPRegisterID reg = temp.takeAnyReg(); + takeReg(reg); + return reg; + } + + bool hasReg(FPRegisterID fpreg) const { + return !!(freeFPMask & (1 << fpreg)); + } + + void putRegUnchecked(FPRegisterID fpreg) { + freeFPMask |= (1 << fpreg); + } + + void putReg(FPRegisterID fpreg) { + JS_ASSERT(!hasReg(fpreg)); + putRegUnchecked(fpreg); + } + + void takeReg(FPRegisterID fpreg) { + JS_ASSERT(hasReg(fpreg)); + freeFPMask &= ~(1 << fpreg); + } + + bool operator ==(const FPRegisters &other) { + return freeFPMask == other.freeFPMask; + } + + uint32 freeFPMask; +}; + } /* namespace mjit */ } /* namespace js */ From 2f941c5f22f04852039bd7634f1e52b1151bef76 Mon Sep 17 00:00:00 2001 From: Sean Stangl Date: Sat, 12 Jun 2010 19:11:00 -0700 Subject: [PATCH 3/3] [JAEGER] Rename FpReg to JSFrameReg; r=dvander. --- js/src/methodjit/BaseAssembler.h | 11 +++++++---- js/src/methodjit/Compiler.cpp | 12 ++++++------ js/src/methodjit/FrameState-inl.h | 2 +- js/src/methodjit/MethodJIT.cpp | 2 +- js/src/methodjit/nunbox/FastOps.cpp | 6 +++--- 5 files changed, 18 insertions(+), 15 deletions(-) diff --git a/js/src/methodjit/BaseAssembler.h b/js/src/methodjit/BaseAssembler.h index 62c93cce90f..80fa31bfbde 100644 --- a/js/src/methodjit/BaseAssembler.h +++ b/js/src/methodjit/BaseAssembler.h @@ -92,12 +92,12 @@ class BaseAssembler : public JSC::MacroAssembler static const uint32 TotalFPRegisters = FPRegisters::TotalFPRegisters; /* - * FpReg is used to home the current JSStackFrame*. + * JSFrameReg is used to home the current JSStackFrame*. */ #if defined(JS_CPU_X86) || defined(JS_CPU_X64) - static const RegisterID FpReg = JSC::X86Registers::ebx; + static const RegisterID JSFrameReg = JSC::X86Registers::ebx; #elif defined(JS_CPU_ARM) - static const RegisterID FpReg = JSC::X86Registers::r11; + static const RegisterID JSFrameReg = JSC::X86Registers::r11; #endif size_t distanceOf(Label l) { @@ -186,7 +186,7 @@ class BaseAssembler : public JSC::MacroAssembler void fixScriptStack(uint32 frameDepth) { /* sp = fp + slots() + stackDepth */ addPtr(Imm32(sizeof(JSStackFrame) + frameDepth * sizeof(jsval)), - FpReg, + JSFrameReg, ClobberInCall); /* regs->sp = sp */ @@ -231,6 +231,9 @@ class BaseAssembler : public JSC::MacroAssembler } }; +/* Save some typing. */ +const JSC::MacroAssembler::RegisterID JSFrameReg = BaseAssembler::JSFrameReg; + } /* namespace js */ } /* namespace mjit */ diff --git a/js/src/methodjit/Compiler.cpp b/js/src/methodjit/Compiler.cpp index d2c80210760..143e2d36d03 100644 --- a/js/src/methodjit/Compiler.cpp +++ b/js/src/methodjit/Compiler.cpp @@ -309,7 +309,7 @@ mjit::Compiler::generateMethod() BEGIN_CASE(JSOP_SETRVAL) { FrameEntry *fe = frame.peek(-1); - frame.storeTo(fe, Address(Assembler::FpReg, offsetof(JSStackFrame, rval)), true); + frame.storeTo(fe, Address(JSFrameReg, offsetof(JSStackFrame, rval)), true); frame.pop(); } END_CASE(JSOP_POPV) @@ -318,7 +318,7 @@ mjit::Compiler::generateMethod() { /* Safe point! */ FrameEntry *fe = frame.peek(-1); - frame.storeTo(fe, Address(Assembler::FpReg, offsetof(JSStackFrame, rval)), true); + frame.storeTo(fe, Address(JSFrameReg, offsetof(JSStackFrame, rval)), true); frame.pop(); /* :TODO: We only have to forget things that are closed over... */ frame.forgetEverything(); @@ -833,7 +833,7 @@ mjit::Compiler::generateMethod() bool popped = PC[JSOP_SETARG_LENGTH] == JSOP_POP; RegisterID reg = frame.allocReg(); - masm.loadPtr(Address(Assembler::FpReg, offsetof(JSStackFrame, argv)), reg); + masm.loadPtr(Address(JSFrameReg, offsetof(JSStackFrame, argv)), reg); Address address = Address(reg, slot * sizeof(Value)); frame.storeTo(top, address, popped); frame.freeReg(reg); @@ -1021,7 +1021,7 @@ mjit::Compiler::generateMethod() { // :FIXME: x64 RegisterID reg = frame.allocReg(); - masm.loadPtr(Address(Assembler::FpReg, offsetof(JSStackFrame, argv)), reg); + masm.loadPtr(Address(JSFrameReg, offsetof(JSStackFrame, argv)), reg); masm.loadData32(Address(reg, int32(sizeof(Value)) * -2), reg); masm.loadPtr(Address(reg, offsetof(JSObject, dslots)), reg); frame.freeReg(reg); @@ -1402,7 +1402,7 @@ mjit::Compiler::dispatchCall(VoidPtrStubUInt32 stub) void mjit::Compiler::restoreFrameRegs() { - masm.loadPtr(FrameAddress(offsetof(VMFrame, fp)), Assembler::FpReg); + masm.loadPtr(FrameAddress(offsetof(VMFrame, fp)), JSFrameReg); } bool @@ -1503,7 +1503,7 @@ void mjit::Compiler::jsop_getarg(uint32 index) { RegisterID reg = frame.allocReg(); - masm.loadPtr(Address(Assembler::FpReg, offsetof(JSStackFrame, argv)), reg); + masm.loadPtr(Address(JSFrameReg, offsetof(JSStackFrame, argv)), reg); frame.freeReg(reg); frame.push(Address(reg, index * sizeof(Value))); } diff --git a/js/src/methodjit/FrameState-inl.h b/js/src/methodjit/FrameState-inl.h index cc14ee0b215..438a2f92a92 100644 --- a/js/src/methodjit/FrameState-inl.h +++ b/js/src/methodjit/FrameState-inl.h @@ -395,7 +395,7 @@ FrameState::addressOf(const FrameEntry *fe) const uint32 index = (fe - entries); JS_ASSERT(index >= nargs); index -= nargs; - return Address(Assembler::FpReg, sizeof(JSStackFrame) + sizeof(Value) * index); + return Address(JSFrameReg, sizeof(JSStackFrame) + sizeof(Value) * index); } inline JSC::MacroAssembler::Jump diff --git a/js/src/methodjit/MethodJIT.cpp b/js/src/methodjit/MethodJIT.cpp index ddd220df2e5..7518a3b619b 100644 --- a/js/src/methodjit/MethodJIT.cpp +++ b/js/src/methodjit/MethodJIT.cpp @@ -316,7 +316,7 @@ SYMBOL_STRING(JaegerTrampoline) ":" "\n" " push {r11}" "\n" /* inlineCallCount */ " push {r0}" "\n" /* cx */ " push {r1}" "\n" /* fp */ -" mov r11, r1" "\n" /* FpReg */ +" mov r11, r1" "\n" /* JSFrameReg */ /* Leave space for the VMFrame arguments. The largest slot appears to be 8 bytes for 32-bit * architectures, though hard-coding this doesn't seem sensible. TODO: Use sizeof here and for diff --git a/js/src/methodjit/nunbox/FastOps.cpp b/js/src/methodjit/nunbox/FastOps.cpp index 8ec53e06e26..bbdc5a3f453 100644 --- a/js/src/methodjit/nunbox/FastOps.cpp +++ b/js/src/methodjit/nunbox/FastOps.cpp @@ -53,7 +53,7 @@ void mjit::Compiler::jsop_bindname(uint32 index) { RegisterID reg = frame.allocReg(); - Address scopeChain(Assembler::FpReg, offsetof(JSStackFrame, scopeChain)); + Address scopeChain(JSFrameReg, offsetof(JSStackFrame, scopeChain)); masm.loadData32(scopeChain, reg); Address address(reg, offsetof(JSObject, fslots) + JSSLOT_PARENT * sizeof(jsval)); @@ -745,7 +745,7 @@ mjit::Compiler::jsop_localinc(JSOp op, uint32 slot, bool popped) /* Note, stub call will push original value again no matter what. */ stubcc.leave(); stubcc.masm.addPtr(Imm32(sizeof(Value) * slot + sizeof(JSStackFrame)), - Assembler::FpReg, + JSFrameReg, Registers::ArgReg1); stubcc.vpInc(op, depth); @@ -784,7 +784,7 @@ mjit::Compiler::jsop_arginc(JSOp op, uint32 slot, bool popped) ovf = masm.branchSub32(Assembler::Overflow, Imm32(1), reg); stubcc.linkExit(ovf); - Address argv(Assembler::FpReg, offsetof(JSStackFrame, argv)); + Address argv(JSFrameReg, offsetof(JSStackFrame, argv)); stubcc.leave(); stubcc.masm.loadPtr(argv, Registers::ArgReg1);