From 521e364261448423329565a36a8fc4eb53ac8282 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Sun, 8 Aug 2010 19:26:38 -0700 Subject: [PATCH] [JAEGER] Another semi-rewrite of LOCALINC for edge cases (bug 585408). --- js/src/jsopcode.tbl | 8 +- js/src/methodjit/FastOps.cpp | 82 ++++++++++++--------- js/src/methodjit/FrameState-inl.h | 3 - js/src/trace-test/tests/jaeger/bug585408.js | 7 ++ 4 files changed, 57 insertions(+), 43 deletions(-) create mode 100644 js/src/trace-test/tests/jaeger/bug585408.js diff --git a/js/src/jsopcode.tbl b/js/src/jsopcode.tbl index 593f52acfc2..7b882dee371 100644 --- a/js/src/jsopcode.tbl +++ b/js/src/jsopcode.tbl @@ -257,10 +257,10 @@ OPDEF(JSOP_DECARG, 96, "decarg", NULL, 3, 0, 1, 15, JOF_QARG | 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|JOF_TMPSLOT2) -OPDEF(JSOP_INCLOCAL, 99, "inclocal", NULL, 3, 0, 1, 15, JOF_LOCAL|JOF_NAME|JOF_INC|JOF_TMPSLOT2) -OPDEF(JSOP_DECLOCAL, 100,"declocal", NULL, 3, 0, 1, 15, JOF_LOCAL|JOF_NAME|JOF_DEC|JOF_TMPSLOT2) -OPDEF(JSOP_LOCALINC, 101,"localinc", NULL, 3, 0, 1, 15, JOF_LOCAL|JOF_NAME|JOF_INC|JOF_POST|JOF_TMPSLOT2) -OPDEF(JSOP_LOCALDEC, 102,"localdec", NULL, 3, 0, 1, 15, JOF_LOCAL|JOF_NAME|JOF_DEC|JOF_POST|JOF_TMPSLOT2) +OPDEF(JSOP_INCLOCAL, 99, "inclocal", NULL, 3, 0, 1, 15, JOF_LOCAL|JOF_NAME|JOF_INC|JOF_TMPSLOT3) +OPDEF(JSOP_DECLOCAL, 100,"declocal", NULL, 3, 0, 1, 15, JOF_LOCAL|JOF_NAME|JOF_DEC|JOF_TMPSLOT3) +OPDEF(JSOP_LOCALINC, 101,"localinc", NULL, 3, 0, 1, 15, JOF_LOCAL|JOF_NAME|JOF_INC|JOF_POST|JOF_TMPSLOT3) +OPDEF(JSOP_LOCALDEC, 102,"localdec", NULL, 3, 0, 1, 15, JOF_LOCAL|JOF_NAME|JOF_DEC|JOF_POST|JOF_TMPSLOT3) OPDEF(JSOP_IMACOP, 103,"imacop", NULL, 1, 0, 0, 0, JOF_BYTE) diff --git a/js/src/methodjit/FastOps.cpp b/js/src/methodjit/FastOps.cpp index 12a3177ca8d..0d7537c0088 100644 --- a/js/src/methodjit/FastOps.cpp +++ b/js/src/methodjit/FastOps.cpp @@ -941,7 +941,6 @@ mjit::Compiler::jsop_localinc(JSOp op, uint32 slot, bool popped) { bool post = (op == JSOP_LOCALINC || op == JSOP_LOCALDEC); int32 amt = (op == JSOP_INCLOCAL || op == JSOP_LOCALINC) ? 1 : -1; - uint32 ndefs = 1; frame.pushLocal(slot); @@ -965,21 +964,43 @@ mjit::Compiler::jsop_localinc(JSOp op, uint32 slot, bool popped) return; } - if (post && !popped) { - frame.dup(); - fe = frame.peek(-1); - ndefs++; + /* + * If the local variable is not known to be an int32, or the pre-value + * is observed, then do the simple thing and decompose x++ into simpler + * opcodes. + */ + if (fe->isNotType(JSVAL_TYPE_INT32) || (post && !popped)) { + /* V */ + jsop_pos(); + /* N */ + + if (post && !popped) { + frame.dup(); + /* N N */ + } + + frame.push(Int32Value(1)); + /* N? N 1 */ + + if (amt == 1) + jsop_binary(JSOP_ADD, stubs::Add); + else + jsop_binary(JSOP_SUB, stubs::Sub); + /* N? N+1 */ + + frame.storeLocal(slot, post || popped); + /* N? N+1 */ + + if (post || popped) + frame.pop(); + + return; } - if (!fe->isTypeKnown() || fe->getKnownType() != JSVAL_TYPE_INT32) { - /* :TODO: do something smarter for the known-type-is-bad case. */ - if (fe->isTypeKnown()) { - Jump j = masm.jump(); - stubcc.linkExit(j, Uses(ndefs)); - } else { - Jump intFail = frame.testInt32(Assembler::NotEqual, fe); - stubcc.linkExit(intFail, Uses(ndefs)); - } + /* If the pre value is not observed, we can emit better code. */ + if (!fe->isTypeKnown()) { + Jump intFail = frame.testInt32(Assembler::NotEqual, fe); + stubcc.linkExit(intFail, Uses(1)); } RegisterID reg = frame.copyDataIntoReg(fe); @@ -989,38 +1010,27 @@ mjit::Compiler::jsop_localinc(JSOp op, uint32 slot, bool popped) ovf = masm.branchAdd32(Assembler::Overflow, Imm32(1), reg); else ovf = masm.branchSub32(Assembler::Overflow, Imm32(1), reg); - stubcc.linkExit(ovf, Uses(ndefs)); + stubcc.linkExit(ovf, Uses(1)); - /* Note, stub call will push original value again no matter what. */ + /* Note, stub call will push the original value again no matter what. */ stubcc.leave(); stubcc.masm.move(Imm32(slot), Registers::ArgReg1); - if (post && !popped) { - if (op == JSOP_LOCALINC) - stubcc.call(stubs::LocalInc); - else - stubcc.call(stubs::LocalDec); - } else { - if (op == JSOP_LOCALINC || op == JSOP_INCLOCAL) - stubcc.call(stubs::IncLocal); - else - stubcc.call(stubs::DecLocal); - } + if (op == JSOP_LOCALINC || op == JSOP_INCLOCAL) + stubcc.call(stubs::IncLocal); + else + stubcc.call(stubs::DecLocal); frame.pop(); frame.pushTypedPayload(JSVAL_TYPE_INT32, reg); - frame.storeLocal(slot, post || popped, false); + frame.storeLocal(slot, popped, false); - if (popped) { - /* No value will be observed. */ - frame.popn(ndefs); - } else { - if (post) - frame.pop(); + if (popped) + frame.pop(); + else frame.forgetType(frame.peek(-1)); - } - stubcc.rejoin(Changes((post || popped) ? 1 : 0)); + stubcc.rejoin(Changes(0)); } void diff --git a/js/src/methodjit/FrameState-inl.h b/js/src/methodjit/FrameState-inl.h index c9d348acddf..e59e06d7bc5 100644 --- a/js/src/methodjit/FrameState-inl.h +++ b/js/src/methodjit/FrameState-inl.h @@ -517,9 +517,6 @@ FrameState::syncData(const FrameEntry *fe, Address to, Assembler &masm) const inline void FrameState::forgetType(FrameEntry *fe) { - if (!fe->isTypeKnown()) - return; - JS_ASSERT(fe->isTypeKnown() && !fe->type.synced()); syncType(fe, addressOf(fe), masm); fe->type.setMemory(); diff --git a/js/src/trace-test/tests/jaeger/bug585408.js b/js/src/trace-test/tests/jaeger/bug585408.js new file mode 100644 index 00000000000..118f219e333 --- /dev/null +++ b/js/src/trace-test/tests/jaeger/bug585408.js @@ -0,0 +1,7 @@ +(function() { + function a() {} + a.e = a++ +})() + +/* Don't assert. */ +