mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backed out changeset 48928150aa27 due to Tinderbox breakage.
This commit is contained in:
parent
85c5abe0a7
commit
320a2cfb64
@ -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 {
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user