[JAEGER] Added JSOP_ARGINC,ARGDEC,INCARG,DECARG.
This commit is contained in:
@@ -252,10 +252,10 @@ OPDEF(JSOP_DEFSHARP, 93, "defsharp", NULL, 5, 0, 0, 0, JOF_UINT16
|
|||||||
OPDEF(JSOP_USESHARP, 94, "usesharp", NULL, 5, 0, 1, 0, JOF_UINT16PAIR|JOF_SHARPSLOT)
|
OPDEF(JSOP_USESHARP, 94, "usesharp", NULL, 5, 0, 1, 0, JOF_UINT16PAIR|JOF_SHARPSLOT)
|
||||||
|
|
||||||
/* Fast inc/dec ops for args and locals. */
|
/* Fast inc/dec ops for args and locals. */
|
||||||
OPDEF(JSOP_INCARG, 95, "incarg", NULL, 3, 0, 1, 15, JOF_QARG |JOF_NAME|JOF_INC)
|
OPDEF(JSOP_INCARG, 95, "incarg", NULL, 3, 0, 1, 15, JOF_QARG |JOF_NAME|JOF_INC|JOF_TMPSLOT2)
|
||||||
OPDEF(JSOP_DECARG, 96, "decarg", NULL, 3, 0, 1, 15, JOF_QARG |JOF_NAME|JOF_DEC)
|
OPDEF(JSOP_DECARG, 96, "decarg", NULL, 3, 0, 1, 15, JOF_QARG |JOF_NAME|JOF_DEC|JOF_TMPSLOT2)
|
||||||
OPDEF(JSOP_ARGINC, 97, "arginc", NULL, 3, 0, 1, 15, JOF_QARG |JOF_NAME|JOF_INC|JOF_POST)
|
OPDEF(JSOP_ARGINC, 97, "arginc", NULL, 3, 0, 1, 15, JOF_QARG |JOF_NAME|JOF_INC|JOF_POST|JOF_TMPSLOT2)
|
||||||
OPDEF(JSOP_ARGDEC, 98, "argdec", NULL, 3, 0, 1, 15, JOF_QARG |JOF_NAME|JOF_DEC|JOF_POST)
|
OPDEF(JSOP_ARGDEC, 98, "argdec", NULL, 3, 0, 1, 15, JOF_QARG |JOF_NAME|JOF_DEC|JOF_POST|JOF_TMPSLOT2)
|
||||||
|
|
||||||
OPDEF(JSOP_INCLOCAL, 99, "inclocal", NULL, 3, 0, 1, 15, JOF_LOCAL|JOF_NAME|JOF_INC)
|
OPDEF(JSOP_INCLOCAL, 99, "inclocal", NULL, 3, 0, 1, 15, JOF_LOCAL|JOF_NAME|JOF_INC)
|
||||||
OPDEF(JSOP_DECLOCAL, 100,"declocal", NULL, 3, 0, 1, 15, JOF_LOCAL|JOF_NAME|JOF_DEC)
|
OPDEF(JSOP_DECLOCAL, 100,"declocal", NULL, 3, 0, 1, 15, JOF_LOCAL|JOF_NAME|JOF_DEC)
|
||||||
|
|||||||
@@ -885,6 +885,23 @@ mjit::Compiler::generateMethod()
|
|||||||
}
|
}
|
||||||
END_CASE(JSOP_INITELEM)
|
END_CASE(JSOP_INITELEM)
|
||||||
|
|
||||||
|
BEGIN_CASE(JSOP_INCARG)
|
||||||
|
BEGIN_CASE(JSOP_DECARG)
|
||||||
|
BEGIN_CASE(JSOP_ARGINC)
|
||||||
|
BEGIN_CASE(JSOP_ARGDEC)
|
||||||
|
{
|
||||||
|
jsbytecode *next = &PC[JSOP_ARGINC_LENGTH];
|
||||||
|
bool popped = false;
|
||||||
|
if (JSOp(*next) == JSOP_POP && !analysis[next].nincoming)
|
||||||
|
popped = true;
|
||||||
|
jsop_arginc(op, GET_SLOTNO(PC), popped);
|
||||||
|
PC += JSOP_ARGINC_LENGTH;
|
||||||
|
if (popped)
|
||||||
|
PC += JSOP_POP_LENGTH;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
END_CASE(JSOP_ARGDEC)
|
||||||
|
|
||||||
BEGIN_CASE(JSOP_FORNAME)
|
BEGIN_CASE(JSOP_FORNAME)
|
||||||
prepareStubCall();
|
prepareStubCall();
|
||||||
masm.move(ImmPtr(script->getAtom(fullAtomIndex(PC))), Registers::ArgReg1);
|
masm.move(ImmPtr(script->getAtom(fullAtomIndex(PC))), Registers::ArgReg1);
|
||||||
|
|||||||
@@ -151,6 +151,7 @@ class Compiler
|
|||||||
void jsop_objtostr();
|
void jsop_objtostr();
|
||||||
void jsop_not();
|
void jsop_not();
|
||||||
void jsop_typeof();
|
void jsop_typeof();
|
||||||
|
void jsop_arginc(JSOp op, uint32 slot, bool popped);
|
||||||
|
|
||||||
#define STUB_CALL_TYPE(type) \
|
#define STUB_CALL_TYPE(type) \
|
||||||
Call stubCall(type stub, Uses uses, Defs defs) { \
|
Call stubCall(type stub, Uses uses, Defs defs) { \
|
||||||
|
|||||||
@@ -378,6 +378,14 @@ FrameState::syncData(const FrameEntry *fe, Address to, Assembler &masm) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
FrameState::forgetType(FrameEntry *fe)
|
||||||
|
{
|
||||||
|
JS_ASSERT(fe->isTypeKnown() && !fe->type.synced());
|
||||||
|
syncType(fe, addressOf(fe), masm);
|
||||||
|
fe->type.setMemory();
|
||||||
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
FrameState::learnType(FrameEntry *fe, JSValueMask32 tag)
|
FrameState::learnType(FrameEntry *fe, JSValueMask32 tag)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -326,6 +326,11 @@ class FrameState
|
|||||||
*/
|
*/
|
||||||
inline void learnType(FrameEntry *fe, JSValueMask32 tag);
|
inline void learnType(FrameEntry *fe, JSValueMask32 tag);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Forget a type, syncing in the process.
|
||||||
|
*/
|
||||||
|
inline void forgetType(FrameEntry *fe);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper function. Tests if a slot's type is an integer. Condition should
|
* Helper function. Tests if a slot's type is an integer. Condition should
|
||||||
* be Equal or NotEqual.
|
* be Equal or NotEqual.
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ StubCompiler::leave()
|
|||||||
jumpList[i].linkTo(masm.label(), &masm);
|
jumpList[i].linkTo(masm.label(), &masm);
|
||||||
jumpList.clear();
|
jumpList.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
StubCompiler::rejoin(uint32 invalidationDepth)
|
StubCompiler::rejoin(uint32 invalidationDepth)
|
||||||
{
|
{
|
||||||
@@ -146,29 +146,29 @@ StubCompiler::finalize(uint8 *ncode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
JSC::MacroAssembler::Call
|
JSC::MacroAssembler::Call
|
||||||
StubCompiler::vpInc(JSOp op, bool pushed)
|
StubCompiler::vpInc(JSOp op, uint32 depth)
|
||||||
{
|
{
|
||||||
uint32 slots = frame.stackDepth() + script->nfixed;
|
uint32 slots = depth + script->nfixed;
|
||||||
if (pushed) {
|
|
||||||
JS_ASSERT(frame.stackDepth());
|
|
||||||
slots--;
|
|
||||||
}
|
|
||||||
|
|
||||||
VoidVpStub stub = NULL;
|
VoidVpStub stub = NULL;
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case JSOP_GLOBALINC:
|
case JSOP_GLOBALINC:
|
||||||
|
case JSOP_ARGINC:
|
||||||
stub = stubs::VpInc;
|
stub = stubs::VpInc;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JSOP_GLOBALDEC:
|
case JSOP_GLOBALDEC:
|
||||||
|
case JSOP_ARGDEC:
|
||||||
stub = stubs::VpDec;
|
stub = stubs::VpDec;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JSOP_INCGLOBAL:
|
case JSOP_INCGLOBAL:
|
||||||
|
case JSOP_INCARG:
|
||||||
stub = stubs::IncVp;
|
stub = stubs::IncVp;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JSOP_DECGLOBAL:
|
case JSOP_DECGLOBAL:
|
||||||
|
case JSOP_DECARG:
|
||||||
stub = stubs::DecVp;
|
stub = stubs::DecVp;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ class StubCompiler
|
|||||||
return masm.buffer();
|
return masm.buffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
Call vpInc(JSOp op, bool pushed);
|
Call vpInc(JSOp op, uint32 depth);
|
||||||
|
|
||||||
#define STUB_CALL_TYPE(type) \
|
#define STUB_CALL_TYPE(type) \
|
||||||
Call call(type stub) { \
|
Call call(type stub) { \
|
||||||
@@ -125,6 +125,7 @@ class StubCompiler
|
|||||||
void linkExit(Jump j);
|
void linkExit(Jump j);
|
||||||
|
|
||||||
void leave();
|
void leave();
|
||||||
|
void leaveWithDepth(uint32 depth);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Rejoins slow-path code back to the fast-path. The invalidation param
|
* Rejoins slow-path code back to the fast-path. The invalidation param
|
||||||
|
|||||||
@@ -326,6 +326,7 @@ mjit::Compiler::jsop_globalinc(JSOp op, uint32 index)
|
|||||||
RegisterID data;
|
RegisterID data;
|
||||||
RegisterID reg = frame.allocReg();
|
RegisterID reg = frame.allocReg();
|
||||||
Address addr = masm.objSlotRef(globalObj, reg, slot);
|
Address addr = masm.objSlotRef(globalObj, reg, slot);
|
||||||
|
uint32 depth = frame.stackDepth();
|
||||||
|
|
||||||
if (post && !popped) {
|
if (post && !popped) {
|
||||||
frame.push(addr);
|
frame.push(addr);
|
||||||
@@ -349,7 +350,7 @@ mjit::Compiler::jsop_globalinc(JSOp op, uint32 index)
|
|||||||
|
|
||||||
stubcc.leave();
|
stubcc.leave();
|
||||||
stubcc.masm.lea(addr, Registers::ArgReg1);
|
stubcc.masm.lea(addr, Registers::ArgReg1);
|
||||||
stubcc.vpInc(op, post && !popped);
|
stubcc.vpInc(op, depth);
|
||||||
|
|
||||||
masm.storeData32(data, addr);
|
masm.storeData32(data, addr);
|
||||||
|
|
||||||
@@ -695,3 +696,52 @@ mjit::Compiler::jsop_typeof()
|
|||||||
frame.pushTypedPayload(JSVAL_MASK32_STRING, Registers::ReturnReg);
|
frame.pushTypedPayload(JSVAL_MASK32_STRING, Registers::ReturnReg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mjit::Compiler::jsop_arginc(JSOp op, uint32 slot, bool popped)
|
||||||
|
{
|
||||||
|
int amt = (js_CodeSpec[op].format & JOF_INC) ? 1 : -1;
|
||||||
|
bool post = !!(js_CodeSpec[op].format & JOF_POST);
|
||||||
|
uint32 depth = frame.stackDepth();
|
||||||
|
|
||||||
|
jsop_getarg(slot);
|
||||||
|
if (post && !popped)
|
||||||
|
frame.dup();
|
||||||
|
|
||||||
|
FrameEntry *fe = frame.peek(-1);
|
||||||
|
Jump notInt = frame.testInt32(Assembler::NotEqual, fe);
|
||||||
|
stubcc.linkExit(notInt);
|
||||||
|
|
||||||
|
RegisterID reg = frame.ownRegForData(fe);
|
||||||
|
frame.pop();
|
||||||
|
|
||||||
|
Jump ovf;
|
||||||
|
if (amt > 0)
|
||||||
|
ovf = masm.branchAdd32(Assembler::Overflow, Imm32(1), reg);
|
||||||
|
else
|
||||||
|
ovf = masm.branchSub32(Assembler::Overflow, Imm32(1), reg);
|
||||||
|
stubcc.linkExit(ovf);
|
||||||
|
|
||||||
|
Address argv(Assembler::FpReg, offsetof(JSStackFrame, argv));
|
||||||
|
|
||||||
|
stubcc.leave();
|
||||||
|
stubcc.masm.loadPtr(argv, Registers::ArgReg1);
|
||||||
|
stubcc.masm.addPtr(Imm32(sizeof(Value) * slot), Registers::ArgReg1, Registers::ArgReg1);
|
||||||
|
stubcc.vpInc(op, depth);
|
||||||
|
|
||||||
|
frame.pushTypedPayload(JSVAL_MASK32_INT32, reg);
|
||||||
|
fe = frame.peek(-1);
|
||||||
|
|
||||||
|
reg = frame.allocReg();
|
||||||
|
masm.loadPtr(argv, reg);
|
||||||
|
Address address = Address(reg, slot * sizeof(Value));
|
||||||
|
frame.storeTo(fe, address, popped);
|
||||||
|
frame.freeReg(reg);
|
||||||
|
|
||||||
|
if (post || popped)
|
||||||
|
frame.pop();
|
||||||
|
else
|
||||||
|
frame.forgetType(fe);
|
||||||
|
|
||||||
|
stubcc.rejoin(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user