Backed out changeset 48928150aa27 due to Tinderbox breakage.

This commit is contained in:
Nicholas Nethercote 2009-09-02 12:14:09 +10:00
parent 85c5abe0a7
commit 320a2cfb64
2 changed files with 55 additions and 57 deletions

View File

@ -340,54 +340,60 @@ namespace nanojit
LInsp LirReader::read()
{
NanoAssert(_i);
LInsp ret = _i;
LInsp cur = _i;
uintptr_t i = uintptr_t(cur);
LOpcode iop = ((LInsp)i)->opcode();
// Check the invariant: _i never points to a skip.
LOpcode iop = _i->opcode();
// We pass over skip instructions below. Also, the last instruction
// for a fragment shouldn't be a skip(*). Therefore we shouldn't see
// a skip here.
//
// (*) Actually, if the last *inserted* instruction exactly fills up a
// page, a new page will be created, and thus the last *written*
// instruction will be a skip -- the one needed for the cross-page
// link. But the last *inserted* instruction is what is recorded and
// used to initialise each LirReader, and that is what is seen here,
// and therefore this assertion holds.
NanoAssert(iop != LIR_skip);
// Step back one instruction.
// Nb: this switch is table-driven in most cases to avoid branch
// mispredictions -- if we do a vanilla switch on the iop or
// LInsRepKind the extra branch mispredictions cause a noticeable
// slowdown.
switch (iop)
do
{
default:
_i = (LInsp)(uintptr_t(_i) - insSizes[_i->opcode()]);
break;
// Nb: this switch is table-driven (because sizeof_LInsXYZ() is
// table-driven) in most cases to avoid branch mispredictions --
// if we do a vanilla switch on the iop or LInsRepKind the extra
// branch mispredictions cause a small but noticeable slowdown.
switch (iop)
{
default:
i -= insSizes[((LInsp)i)->opcode()];
break;
case LIR_icall:
case LIR_fcall:
case LIR_qcall: {
// Step over the instruction itself and the arguments.
_i = (LInsp)(uintptr_t(_i) - sizeof(LInsC) - _i->argc()*sizeof(LInsp));
break;
case LIR_icall:
case LIR_fcall:
case LIR_qcall: {
int argc = ((LInsp)i)->argc();
i -= sizeof(LInsC); // step over the instruction
i -= argc*sizeof(LInsp); // step over the arguments
break;
}
case LIR_skip:
// Ignore the skip, move onto its predecessor.
NanoAssert(((LInsp)i)->prevLIns() != (LInsp)i);
i = uintptr_t(((LInsp)i)->prevLIns());
break;
case LIR_start:
// Once we hit here, this method shouldn't be called again.
// The assertion at the top of this method checks this.
_i = 0;
return cur;
}
#ifdef _DEBUG
case LIR_skip:
NanoAssert(0);
break;
case LIR_start:
// Once we hit here, this method shouldn't be called again.
// The assertion at the top of this method checks this.
// (In the non-debug case, _i ends up pointing to junk just
// prior to the LIR_start, but it should be ok because,
// again, this method shouldn't be called again.)
_i = 0;
return ret;
#endif
iop = ((LInsp)i)->opcode();
}
// Make sure we don't end up with _i pointing to a skip.
while (LIR_skip == _i->opcode()) {
NanoAssert(_i->prevLIns() != _i);
_i = _i->prevLIns();
}
return ret;
while (LIR_skip == iop);
_i = (LInsp)i;
return cur;
}
bool LIns::isFloat() const {

View File

@ -1206,30 +1206,22 @@ namespace nanojit
// concrete
class LirReader : public LirFilter
{
LInsp _i; // next instruction to be read; invariant: is never a skip
LInsp _i; // current instruction that this decoder is operating on.
public:
LirReader(LInsp i) : LirFilter(0), _i(i)
{
// The last instruction for a fragment shouldn't be a skip.
// (Actually, if the last *inserted* instruction exactly fills up
// a page, a new page will be created, and thus the last *written*
// instruction will be a skip -- the one needed for the cross-page
// link. But the last *inserted* instruction is what is recorded
// and used to initialise each LirReader, and that is what is seen
// here, and therefore this assertion holds.)
NanoAssert(i && !i->isop(LIR_skip));
LirReader(LInsp i) : LirFilter(0), _i(i) {
NanoAssert(_i);
}
virtual ~LirReader() {}
// Returns next instruction and advances to the prior instruction.
// Invariant: never returns a skip.
LInsp read();
// Returns next instruction. Invariant: never returns a skip.
// LirReader i/f
LInsp read(); // advance to the prior instruction
LInsp pos() {
return _i;
}
void setpos(LIns *i) {
_i = i;
}
};
class Assembler;