diff --git a/js/src/nanojit/Assembler.cpp b/js/src/nanojit/Assembler.cpp index 2bb9fb1925ec..2c860ec15872 100755 --- a/js/src/nanojit/Assembler.cpp +++ b/js/src/nanojit/Assembler.cpp @@ -417,6 +417,30 @@ namespace nanojit return r; } + // Like findSpecificRegFor(), but only for when 'r' is known to be free + // and 'ins' is known to not already have a register allocated. Updates + // the register state (maintaining the invariants) but does not generate + // any code. The return value is redundant, always being 'r', but it's + // sometimes useful to have it there for assignments. + Register Assembler::findSpecificRegForUnallocated(LIns* ins, Register r) + { + if (ins->isop(LIR_alloc)) { + // never allocate a reg for this w/out stack space too + findMemFor(ins); + } + + NanoAssert(ins->isUnusedOrHasUnknownReg()); + NanoAssert(_allocator.free & rmask(r)); + + if (!ins->isUsed()) + ins->markAsUsed(); + ins->setReg(r); + _allocator.removeFree(r); + _allocator.addActive(r, ins); + + return r; + } + int Assembler::findMemFor(LIns *ins) { if (!ins->isUsed()) @@ -1379,7 +1403,7 @@ namespace nanojit for (int i=0, n = NumSavedRegs; i < n; i++) { LIns *p = b->savedRegs[i]; if (p) - findSpecificRegFor(p, savedRegs[p->paramArg()]); + findSpecificRegForUnallocated(p, savedRegs[p->paramArg()]); } } @@ -1398,10 +1422,10 @@ namespace nanojit { LInsp state = _thisfrag->lirbuf->state; if (state) - findSpecificRegFor(state, argRegs[state->paramArg()]); + findSpecificRegForUnallocated(state, argRegs[state->paramArg()]); LInsp param1 = _thisfrag->lirbuf->param1; if (param1) - findSpecificRegFor(param1, argRegs[param1->paramArg()]); + findSpecificRegForUnallocated(param1, argRegs[param1->paramArg()]); } void Assembler::handleLoopCarriedExprs(InsList& pending_lives) diff --git a/js/src/nanojit/Assembler.h b/js/src/nanojit/Assembler.h index ab7024084327..56059824921f 100644 --- a/js/src/nanojit/Assembler.h +++ b/js/src/nanojit/Assembler.h @@ -229,7 +229,8 @@ namespace nanojit Register findRegFor(LIns* i, RegisterMask allow); void findRegFor2(RegisterMask allow, LIns* ia, Reservation* &resva, LIns *ib, Reservation* &resvb); void findRegFor2b(RegisterMask allow, LIns* ia, Register &ra, LIns *ib, Register &rb); - Register findSpecificRegFor(LIns* i, Register w); + Register findSpecificRegFor(LIns* i, Register r); + Register findSpecificRegForUnallocated(LIns* i, Register r); Register prepResultReg(LIns *i, RegisterMask allow); void freeRsrcOf(LIns *i, bool pop); void evictIfActive(Register r); diff --git a/js/src/nanojit/Nativei386.cpp b/js/src/nanojit/Nativei386.cpp index 02634612a7cf..bffb1decf265 100644 --- a/js/src/nanojit/Nativei386.cpp +++ b/js/src/nanojit/Nativei386.cpp @@ -870,7 +870,7 @@ namespace nanojit // if this is last use of lhs in reg, we can re-use result reg // else, lhs already has a register assigned. Register ra = ( lhs->isUnusedOrHasUnknownReg() - ? findSpecificRegFor(lhs, rr) + ? findSpecificRegForUnallocated(lhs, rr) : lhs->getReg() ); if (forceReg) @@ -996,7 +996,7 @@ namespace nanojit // if this is last use of lhs in reg, we can re-use result reg // else, lhs already has a register assigned. Register ra = ( lhs->isUnusedOrHasUnknownReg() - ? findSpecificRegFor(lhs, rr) + ? findSpecificRegForUnallocated(lhs, rr) : lhs->getReg() ); if (op == LIR_not) @@ -1048,12 +1048,12 @@ namespace nanojit * @todo -- If LHS is const, we could eliminate a register use. */ Register rleft = ( lhs->isUnusedOrHasUnknownReg() - ? findSpecificRegFor(lhs, rr) + ? findSpecificRegForUnallocated(lhs, rr) : lhs->getReg() ); /* Does RHS have a register yet? If not, try to re-use the result reg. */ Register rright = ( rr != rleft && rhs->isUnusedOrHasUnknownReg() - ? findSpecificRegFor(rhs, rr) + ? findSpecificRegForUnallocated(rhs, rr) : findRegFor(rhs, GpRegs & ~(rmask(rleft))) ); if (op == LIR_ldcb) @@ -1268,7 +1268,7 @@ namespace nanojit // if this is last use of lhs in reg, we can re-use result reg // else, lhs already has a register assigned. if (lhs->isUnusedOrHasUnknownReg()) { - ra = findSpecificRegFor(lhs, rr); + ra = findSpecificRegForUnallocated(lhs, rr); } else { ra = lhs->getReg(); if ((rmask(ra) & XmmRegs) == 0) { @@ -1296,7 +1296,7 @@ namespace nanojit // if this is last use of lhs in reg, we can re-use result reg // else, lhs already has a different reg assigned if (lhs->isUnusedOrHasUnknownReg()) - findSpecificRegFor(lhs, rr); + findSpecificRegForUnallocated(lhs, rr); NanoAssert(lhs->getReg()==FST0); // assume that the lhs is in ST(0) and rhs is on stack @@ -1457,7 +1457,7 @@ namespace nanojit // if this is last use of lhs in reg, we can re-use result reg if (lhs->isUnusedOrHasUnknownReg()) { - ra = findSpecificRegFor(lhs, rr); + ra = findSpecificRegForUnallocated(lhs, rr); } else if ((rmask(lhs->getReg()) & XmmRegs) == 0) { // We need this case on AMD64, because it's possible that // an earlier instruction has done a quadword load and reserved a @@ -1499,7 +1499,7 @@ namespace nanojit // last use of lhs in reg, can reuse rr // else, lhs already has a different reg assigned if (lhs->isUnusedOrHasUnknownReg()) - findSpecificRegFor(lhs, rr); + findSpecificRegForUnallocated(lhs, rr); NanoAssert(lhs->getReg()==FST0); // assume that the lhs is in ST(0) and rhs is on stack @@ -1747,7 +1747,7 @@ namespace nanojit // compare two different numbers int d = findMemFor(rhs); int pop = lhs->isUnusedOrHasUnknownReg(); - findSpecificRegFor(lhs, FST0); + findSpecificRegForUnallocated(lhs, FST0); // lhs is in ST(0) and rhs is on stack FCOM(pop, d, FP); } @@ -1755,7 +1755,7 @@ namespace nanojit { // compare n to itself, this is a NaN test. int pop = lhs->isUnusedOrHasUnknownReg(); - findSpecificRegFor(lhs, FST0); + findSpecificRegForUnallocated(lhs, FST0); // value in ST(0) if (pop) FCOMPP(); diff --git a/js/src/nanojit/RegAlloc.h b/js/src/nanojit/RegAlloc.h index ac02919ae156..39e92d8bac5f 100644 --- a/js/src/nanojit/RegAlloc.h +++ b/js/src/nanojit/RegAlloc.h @@ -74,6 +74,12 @@ namespace nanojit free |= rmask(r); } + void removeFree(Register r) + { + NanoAssert(isFree(r)); + free &= ~rmask(r); + } + void addActive(Register r, LIns* v) { // Count++;