From b7a14c0256097f062c5fefb7999944054d5f1340 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 22 Jun 2009 10:48:36 +1000 Subject: [PATCH] Fix assertion failure in trace-test.js with TRACEMONKEY=verbose (bug 499154, r=graydon). --- js/src/nanojit/LIR.cpp | 45 +++++++++++++++++++++++------------------- js/src/nanojit/LIR.h | 2 -- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/js/src/nanojit/LIR.cpp b/js/src/nanojit/LIR.cpp index c7b6eed1ab96..408a6ad69363 100644 --- a/js/src/nanojit/LIR.cpp +++ b/js/src/nanojit/LIR.cpp @@ -163,13 +163,6 @@ namespace nanojit return page; } - LInsp LirBuffer::lastWritten() - { - // Make sure there is a most-recently-written instruction. - NanoAssert(_unused >= pageDataStart(_unused)); - return (LInsp)(_unused - sizeof(LIns)); // step back one instruction - } - // Allocate a new page, and write the first instruction to it -- a skip // linking to last instruction of the previous page. void LirBuffer::moveToNewPage(uintptr_t addrOfLastLInsOnCurrentPage) @@ -202,8 +195,10 @@ namespace nanojit // If the instruction won't fit on the current page, move to the next // page. - if (_unused + szB - 1 > pageBottom(_unused)) - moveToNewPage((uintptr_t)lastWritten()); + if (_unused + szB - 1 > pageBottom(_unused)) { + uintptr_t addrOfLastLInsOnPage = _unused - sizeof(LIns); + moveToNewPage(addrOfLastLInsOnPage); + } // We now know that we are on a page that has the requested amount of // room: record the starting address of the requested space and bump @@ -349,9 +344,19 @@ namespace nanojit return 0; uintptr_t i = uintptr_t(cur); LOpcode iop = ((LInsp)i)->opcode(); - // We pass over skip instructions below, which means we shouldn't see - // one here. + + // 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); + do { switch (iop) @@ -1509,24 +1514,24 @@ namespace nanojit } }; - void live(GC *gc, LirBuffer *lirbuf) + void live(GC *gc, Fragment *frag) { // traverse backwards to find live exprs and a few other stats. LiveTable live(gc); uint32_t exits = 0; - LirReader br(lirbuf); - StackFilter sf(&br, gc, lirbuf, lirbuf->sp); - StackFilter r(&sf, gc, lirbuf, lirbuf->rp); + LirReader br(frag->lastIns); + StackFilter sf(&br, gc, frag->lirbuf, frag->lirbuf->sp); + StackFilter r(&sf, gc, frag->lirbuf, frag->lirbuf->rp); int total = 0; - if (lirbuf->state) - live.add(lirbuf->state, r.pos()); + if (frag->lirbuf->state) + live.add(frag->lirbuf->state, r.pos()); for (LInsp i = r.read(); i != 0; i = r.read()) { total++; // first handle side-effect instructions - if (!i->isCse(lirbuf->_functions)) + if (!i->isCse(frag->lirbuf->_functions)) { live.add(i,0); if (i->isGuard()) @@ -1566,7 +1571,7 @@ namespace nanojit nj_dprintf("side exits %u\n", exits); // print live exprs, going forwards - LirNameMap *names = lirbuf->names; + LirNameMap *names = frag->lirbuf->names; bool newblock = true; for (int j=live.retired.size()-1; j >= 0; j--) { @@ -1992,7 +1997,7 @@ namespace nanojit verbose_only( assm->_outputCache = &asmOutput; ) verbose_only(if (assm->_verbose && core->config.verbose_live) - live(gc, triggerFrag->lirbuf);) + live(gc, triggerFrag);) bool treeCompile = core->config.tree_opt && (triggerFrag->kind == BranchTrace); RegAllocMap regMap(gc); diff --git a/js/src/nanojit/LIR.h b/js/src/nanojit/LIR.h index cd21985a24f9..a53f32918bcd 100644 --- a/js/src/nanojit/LIR.h +++ b/js/src/nanojit/LIR.h @@ -677,7 +677,6 @@ namespace nanojit void clear(); void rewind(); uintptr_t makeRoom(size_t szB); // make room for an instruction - LInsp lastWritten(); // most recently written instruction bool outOMem() { return _noMem != 0; } debug_only (void validate() const;) @@ -756,7 +755,6 @@ namespace nanojit LInsp _i; // current instruction that this decoder is operating on. public: - LirReader(LirBuffer* buf) : LirFilter(0), _i(buf->lastWritten()) { } LirReader(LInsp i) : LirFilter(0), _i(i) { } virtual ~LirReader() {}