diff --git a/js/src/nanojit/Assembler.cpp b/js/src/nanojit/Assembler.cpp index 0e4f9dc2bf8d..c179da819221 100644 --- a/js/src/nanojit/Assembler.cpp +++ b/js/src/nanojit/Assembler.cpp @@ -505,8 +505,9 @@ namespace nanojit RegisterMask prefer = hint(i, allow); // if we didn't have a reservation, allocate one now - if (!resv) - resv = i->initResv(); + if (!resv) { + (resv = i->resv())->init(); + } r = resv->reg; @@ -555,7 +556,7 @@ namespace nanojit { Reservation* resv = getresv(i); if (!resv) - resv = i->initResv(); + (resv = i->resv())->init(); if (!resv->arIndex) { resv->arIndex = arReserve(i); NanoAssert(resv->arIndex <= _activation.highwatermark); @@ -598,7 +599,7 @@ namespace nanojit } if (index) arFree(index); // free any stack stack space associated with entry - i->clearResv(); + i->resv()->clear(); } void Assembler::evict(Register r) @@ -947,7 +948,7 @@ namespace nanojit if (!resv->arIndex && resv->reg == UnknownReg) { - i->clearResv(); + i->resv()->clear(); } } } diff --git a/js/src/nanojit/LIR.cpp b/js/src/nanojit/LIR.cpp index 7325ab2087ea..27d68daeee69 100644 --- a/js/src/nanojit/LIR.cpp +++ b/js/src/nanojit/LIR.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 4 -*- */ +/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -178,8 +178,8 @@ namespace nanojit // because we know we have enough space, having just started a new // page. LInsp l = (LInsp)_unused; - l->initOpcodeAndClearResv(LIR_skip); - l->setOprnd1((LInsp)addrOfLastLInsOnCurrentPage); + l->setIns1(LIR_skip, (LInsp)addrOfLastLInsOnCurrentPage); + l->resv()->clear(); _unused += sizeof(LIns); _stats.lir++; } @@ -227,34 +227,32 @@ namespace nanojit { LOpcode op = val->isQuad() ? LIR_stqi : LIR_sti; LInsp l = (LInsp)_buf->makeRoom(sizeof(LIns)); - l->initOpcodeAndClearResv(op); - l->setOprnd1(val); - l->setOprnd2(base); - l->setDisp(d); + l->setStorei(op, val, base, d); + l->resv()->clear(); return l; } LInsp LirBufWriter::ins0(LOpcode op) { LInsp l = (LInsp)_buf->makeRoom(sizeof(LIns)); - l->initOpcodeAndClearResv(op); + l->setIns0(op); + l->resv()->clear(); return l; } LInsp LirBufWriter::ins1(LOpcode op, LInsp o1) { LInsp l = (LInsp)_buf->makeRoom(sizeof(LIns)); - l->initOpcodeAndClearResv(op); - l->setOprnd1(o1); + l->setIns1(op, o1); + l->resv()->clear(); return l; } LInsp LirBufWriter::ins2(LOpcode op, LInsp o1, LInsp o2) { LInsp l = (LInsp)_buf->makeRoom(sizeof(LIns)); - l->initOpcodeAndClearResv(op); - l->setOprnd1(o1); - l->setOprnd2(o2); + l->setIns2(op, o1, o2); + l->resv()->clear(); return l; } @@ -278,19 +276,16 @@ namespace nanojit { size = (size+3)>>2; // # of required 32bit words LInsp l = (LInsp)_buf->makeRoom(sizeof(LIns)); - l->initOpcodeAndClearResv(LIR_alloc); - l->i.imm32 = size; + l->setAlloc(LIR_alloc, size); + l->resv()->clear(); return l; } LInsp LirBufWriter::insParam(int32_t arg, int32_t kind) { LInsp l = (LInsp)_buf->makeRoom(sizeof(LIns)); - l->initOpcodeAndClearResv(LIR_param); - NanoAssert(isU8(arg) && isU8(kind)); - l->c.imm8a = arg; - l->c.imm8b = kind; - l->c.ci = NULL; + l->setParam(LIR_param, arg, kind); + l->resv()->clear(); if (kind) { NanoAssert(arg < NumSavedRegs); _buf->savedRegs[arg] = l; @@ -302,17 +297,16 @@ namespace nanojit LInsp LirBufWriter::insImm(int32_t imm) { LInsp l = (LInsp)_buf->makeRoom(sizeof(LIns)); - l->initOpcodeAndClearResv(LIR_int); - l->setimm32(imm); + l->setImm(LIR_int, imm); + l->resv()->clear(); return l; } LInsp LirBufWriter::insImmq(uint64_t imm) { LInsp l = (LInsp)_buf->makeRoom(sizeof(LIns)); - l->initOpcodeAndClearResv(LIR_quad); - l->i64.imm64_0 = int32_t(imm); - l->i64.imm64_1 = int32_t(imm>>32); + l->setImmq(LIR_quad, imm); + l->resv()->clear(); return l; } @@ -331,8 +325,8 @@ namespace nanojit LInsp l = (LInsp)(payload + payload_szB); NanoAssert(prevLInsAddr >= pageDataStart(prevLInsAddr)); NanoAssert(samepage(prevLInsAddr, l)); - l->initOpcodeAndClearResv(LIR_skip); - l->setOprnd1((LInsp)prevLInsAddr); + l->setIns1(LIR_skip, (LInsp)prevLInsAddr); + l->resv()->clear(); return l; } @@ -538,31 +532,11 @@ namespace nanojit return nanojit::isCseOpcode(firstWord.code) || (isCall() && callInfo()->_cse); } - void LIns::initOpcodeAndClearResv(LOpcode op) - { - NanoAssert(4*sizeof(void*) == sizeof(LIns)); - firstWord.code = op; - firstWord.used = 0; - } - - Reservation* LIns::initResv() - { - firstWord.reg = UnknownReg; - firstWord.arIndex = 0; - firstWord.used = 1; - return &firstWord; - } - - void LIns::clearResv() - { - firstWord.used = 0; - } - void LIns::setTarget(LInsp label) { NanoAssert(label && label->isop(LIR_label)); NanoAssert(isBranch()); - setOprnd2(label); + u.oprnd_2 = label; } LInsp LIns::getTarget() @@ -1075,13 +1049,11 @@ namespace nanojit // Write the call instruction itself. LInsp l = (LInsp)(uintptr_t(newargs) + argc*sizeof(LInsp)); #ifndef NANOJIT_64BIT - l->initOpcodeAndClearResv(op==LIR_callh ? LIR_call : op); + l->setCall(op==LIR_callh ? LIR_call : op, argc, ci); #else - l->initOpcodeAndClearResv(op); + l->setCall(op, argc, ci); #endif - l->c.imm8a = 0; - l->c.imm8b = argc; - l->c.ci = ci; + l->resv()->clear(); return l; } diff --git a/js/src/nanojit/LIR.h b/js/src/nanojit/LIR.h index 9acf1d46999b..388f0a6f8b3d 100644 --- a/js/src/nanojit/LIR.h +++ b/js/src/nanojit/LIR.h @@ -1,4 +1,4 @@ -/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 4 -*- */ +/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -164,6 +164,17 @@ namespace nanojit Register reg:7; // register UnknownReg implies not in register uint32_t used:1; // when set, the reservation is active LOpcode code:8; + + inline void init() { + reg = UnknownReg; + arIndex = 0; + used = 1; + } + + inline void clear() + { + used = 0; + } }; // Low-level Instruction. 4 words per instruction -- it's important this @@ -172,8 +183,6 @@ namespace nanojit // The first word is the same for all LIns kinds; the last three differ. class LIns { - friend class LirBufWriter; - // 2-operand form. Used for most LIns kinds, including LIR_skip (for // which oprnd_1 is the target). struct u_type @@ -254,9 +263,9 @@ namespace nanojit uint64_t imm64() const; double imm64f() const; Reservation* resv() { return &firstWord; } - void* payload() const; - inline Page* page() { return (Page*) alignTo(this,NJ_PAGE_SIZE); } - inline int32_t size() const { + void* payload() const; + inline Page* page() { return (Page*) alignTo(this,NJ_PAGE_SIZE); } + inline int32_t size() const { NanoAssert(isop(LIR_alloc)); return i.imm32<<2; } @@ -323,25 +332,70 @@ namespace nanojit bool isBranch() const { return isop(LIR_jt) || isop(LIR_jf) || isop(LIR_j); } - void setimm32(int32_t x) { NanoAssert(isconst()); i.imm32 = x; } - // Set the opcode and clear resv. - void initOpcodeAndClearResv(LOpcode); - Reservation* initResv(); - void clearResv(); - // operand-setting methods - void setOprnd1(LIns* r) { - NanoAssert(isOp1() || isOp2() || isLoad() || isStore()); - u.oprnd_1 = r; + void setIns0(LOpcode op) { + firstWord.code = op; + } + void setIns1(LOpcode op, LIns* oprnd1) { + firstWord.code = op; + u.oprnd_1 = oprnd1; + NanoAssert(isOp1()); } - void setOprnd2(LIns* r) { - NanoAssert(isOp2() || isLoad() || isStore()); - u.oprnd_2 = r; + void setIns2(LOpcode op, LIns* oprnd1, LIns* oprnd2) { + firstWord.code = op; + u.oprnd_1 = oprnd1; + u.oprnd_2 = oprnd2; + NanoAssert(isOp2() || isLoad() || isGuard() || isBranch()); } - void setDisp(int32_t d) { - NanoAssert(isStore()); + void setLoad(LOpcode op, LIns* base, LIns* d) { + setIns2(op, base, d); + } + void setGuard(LOpcode op, LIns* cond, LIns* data) { + setIns2(op, cond, data); + } + void setBranch(LOpcode op, LIns* cond, LIns* target) { + setIns2(op, cond, target); + } + void setStorei(LOpcode op, LIns* val, LIns* base, int32_t d) { + firstWord.code = op; + u.oprnd_1 = val; + u.oprnd_2 = base; sti.disp = d; + NanoAssert(isStore()); } + void setImm(LOpcode op, int32_t imm32) { + firstWord.code = op; + i.imm32 = imm32; + NanoAssert(op == LIR_alloc || op == LIR_int); + } + void setAlloc(LOpcode op, int32_t size) { + setImm(op, size); + } + void setParam(LOpcode op, int32_t arg, int32_t kind) + { + firstWord.code = op; + NanoAssert(isU8(arg) && isU8(kind)); + c.imm8a = arg; + c.imm8b = kind; + c.ci = NULL; + NanoAssert(op == LIR_param); + } + void setCall(LOpcode op, int32_t argc, const CallInfo* ci) + { + firstWord.code = op; + NanoAssert(isU8(argc)); + c.imm8a = 0; + c.imm8b = argc; + c.ci = ci; + NanoAssert(op == LIR_call || op == LIR_fcall); + } + void setImmq(LOpcode op, int64_t imm64) { + firstWord.code = op; + i64.imm64_0 = int32_t(imm64); + i64.imm64_1 = int32_t(imm64>>32); + NanoAssert(op == LIR_quad); + } + void setTarget(LIns* t); LIns* getTarget(); diff --git a/js/src/nanojit/Nativei386.cpp b/js/src/nanojit/Nativei386.cpp index 234ebf6f1ace..555222d6da1d 100644 --- a/js/src/nanojit/Nativei386.cpp +++ b/js/src/nanojit/Nativei386.cpp @@ -419,7 +419,7 @@ namespace nanojit } else if (i->isconst()) { if (!resv->arIndex) { - i->clearResv(); + i->resv()->clear(); } LDi(r, i->imm32()); }