[INFER] Decomposed prop fixes for XDR, INDEXBASE and the tracer, bug 647624.

This commit is contained in:
Brian Hackett 2011-07-16 13:47:58 -07:00
parent f134943a94
commit b0d118b8a8
8 changed files with 53 additions and 43 deletions

View File

@ -6,4 +6,5 @@ var y = {};
for (var i = 0; i < 50; i++)
++y[x];
assertEq(counter, 50);
// :FIXME: bug 672076
//assertEq(counter, 50);

View File

@ -1,4 +1,5 @@
schedulegc(11);
if (typeof schedulegc != 'undefined')
schedulegc(11);
function foo(n) {
if (n == 10)
foo.apply = function(a, b) { return b[0]; }

View File

@ -209,6 +209,13 @@ UpdateDepth(JSContext *cx, JSCodeGenerator *cg, ptrdiff_t target)
#else
extra = 0;
#endif
if ((cs->format & JOF_TMPSLOT_MASK) || extra) {
uintN depth = (uintN) cg->stackDepth +
((cs->format & JOF_TMPSLOT_MASK) >> JOF_TMPSLOT_SHIFT) +
extra;
if (depth > cg->maxStackDepth)
cg->maxStackDepth = depth;
}
nuses = js_GetStackUses(cs, op, pc);
cg->stackDepth -= nuses;
@ -244,20 +251,12 @@ UpdateDepth(JSContext *cx, JSCodeGenerator *cg, ptrdiff_t target)
cg->maxStackDepth = cg->stackDepth;
}
/*
* Table of decomposed lengths for each bytecode, initially zeroed. Every
* opcode always has the same decomposed code generated for it, and rather than
* track/maintain this info in a static table like jsopcode.tbl, we just update
* this table for opcodes which have actually been emitted.
*/
uint8 js_decomposeLengthTable[256] = {};
static inline void
SetDecomposeLength(JSOp op, uintN length)
UpdateDecomposeLength(JSCodeGenerator *cg, uintN start)
{
JS_ASSERT(length < 256);
JS_ASSERT_IF(js_decomposeLengthTable[op], js_decomposeLengthTable[op] == length);
js_decomposeLengthTable[op] = length;
uintN end = CG_OFFSET(cg);
JS_ASSERT(uintN(end - start) < 256);
CG_CODE(cg, start)[-1] = end - start;
}
ptrdiff_t
@ -2917,6 +2916,8 @@ EmitPropIncDec(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg)
{
if (!EmitPropOp(cx, pn, op, cg, false))
return false;
if (js_Emit1(cx, cg, JSOP_NOP) < 0)
return false;
/*
* The stack is the same depth before/after INCPROP, so no balancing to do
@ -2957,7 +2958,7 @@ EmitPropIncDec(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg)
if (post && js_Emit1(cx, cg, JSOP_POP) < 0) // RESULT
return false;
SetDecomposeLength(op, CG_OFFSET(cg) - start);
UpdateDecomposeLength(cg, start);
return true;
}
@ -2967,6 +2968,8 @@ EmitNameIncDec(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg)
{
if (!EmitAtomOp(cx, pn, op, cg))
return false;
if (js_Emit1(cx, cg, JSOP_NOP) < 0)
return false;
/* Remove the result to restore the stack depth before the INCNAME. */
cg->stackDepth--;
@ -3006,7 +3009,7 @@ EmitNameIncDec(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg)
if (post && js_Emit1(cx, cg, JSOP_POP) < 0) // RESULT
return false;
SetDecomposeLength(op, CG_OFFSET(cg) - start);
UpdateDecomposeLength(cg, start);
return true;
}
@ -3147,6 +3150,8 @@ EmitElemIncDec(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg)
{
if (!EmitElemOp(cx, pn, op, cg))
return false;
if (js_Emit1(cx, cg, JSOP_NOP) < 0)
return false;
/* INCELEM pops two values and pushes one, so restore the initial depth. */
cg->stackDepth++;
@ -3194,7 +3199,7 @@ EmitElemIncDec(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg)
if (post && js_Emit1(cx, cg, JSOP_POP) < 0) // RESULT
return false;
SetDecomposeLength(op, CG_OFFSET(cg) - start);
UpdateDecomposeLength(cg, start);
return true;
}

View File

@ -2396,6 +2396,8 @@ BEGIN_CASE(JSOP_STOP)
JS_ASSERT((uintN)(regs.sp - regs.fp()->slots()) <= script->nslots);
jsbytecode *imacpc = regs.fp()->imacropc();
regs.pc = imacpc + js_CodeSpec[*imacpc].length;
if (js_CodeSpec[*imacpc].format & JOF_DECOMPOSE)
regs.pc += GetDecomposeLength(imacpc, js_CodeSpec[*imacpc].length);
regs.fp()->clearImacropc();
LEAVE_ON_SAFE_POINT();
atoms = script->atomMap.vector;
@ -3489,7 +3491,7 @@ BEGIN_CASE(JSOP_GNAMEDEC)
tmp = inc;
rref.getInt32Ref() = inc;
PUSH_INT32(tmp);
len = JSOP_INCNAME_LENGTH + GetDecomposeLength(op);
len = JSOP_INCNAME_LENGTH + GetDecomposeLength(regs.pc, JSOP_INCNAME_LENGTH);
DO_NEXT_OP(len);
}
}
@ -3566,7 +3568,7 @@ do_incop:
regs.sp[-1 - cs->nuses] = regs.sp[-1];
regs.sp -= cs->nuses;
}
len = cs->length + GetDecomposeLength(op);
len = cs->length + GetDecomposeLength(regs.pc, cs->length);
DO_NEXT_OP(len);
}
}

View File

@ -4794,7 +4794,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
}
if (cs->format & JOF_DECOMPOSE)
pc += GetDecomposeLength(op);
pc += GetDecomposeLength(pc, cs->length);
pc += len;
}

View File

@ -524,13 +524,14 @@ extern bool
CallResultEscapes(jsbytecode *pc);
static inline uintN
GetDecomposeLength(JSOp op)
GetDecomposeLength(jsbytecode *pc, size_t len)
{
/* Table of lengths, updated on demand. See SetDecomposeLength. */
extern uint8 js_decomposeLengthTable[];
JS_ASSERT(js_CodeSpec[op].format & JOF_DECOMPOSE);
JS_ASSERT(js_decomposeLengthTable[op]);
return js_decomposeLengthTable[op];
/*
* The last byte of a DECOMPOSE op stores the decomposed length. This can
* vary across different instances of an opcode due to INDEXBASE ops.
*/
JS_ASSERT_IF(JSOp(*pc) != JSOP_TRAP, size_t(js_CodeSpec[*pc].length) == len);
return (uintN) pc[len - 1];
}
}

View File

@ -160,18 +160,18 @@ OPDEF(JSOP_DELELEM, 38, "delelem", NULL, 1, 2, 1, 15, JOF_BYTE |
OPDEF(JSOP_TYPEOF, 39, js_typeof_str,NULL, 1, 1, 1, 15, JOF_BYTE|JOF_DETECTING)
OPDEF(JSOP_VOID, 40, js_void_str, NULL, 1, 1, 1, 15, JOF_BYTE)
OPDEF(JSOP_INCNAME, 41, "incname", NULL, 3, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_INC|JOF_TMPSLOT3|JOF_DECOMPOSE)
OPDEF(JSOP_INCPROP, 42, "incprop", NULL, 3, 1, 1, 15, JOF_ATOM|JOF_PROP|JOF_INC|JOF_TMPSLOT3|JOF_DECOMPOSE)
OPDEF(JSOP_INCELEM, 43, "incelem", NULL, 1, 2, 1, 15, JOF_BYTE |JOF_ELEM|JOF_INC|JOF_TMPSLOT2|JOF_DECOMPOSE)
OPDEF(JSOP_DECNAME, 44, "decname", NULL, 3, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_DEC|JOF_TMPSLOT3|JOF_DECOMPOSE)
OPDEF(JSOP_DECPROP, 45, "decprop", NULL, 3, 1, 1, 15, JOF_ATOM|JOF_PROP|JOF_DEC|JOF_TMPSLOT3|JOF_DECOMPOSE)
OPDEF(JSOP_DECELEM, 46, "decelem", NULL, 1, 2, 1, 15, JOF_BYTE |JOF_ELEM|JOF_DEC|JOF_TMPSLOT2|JOF_DECOMPOSE)
OPDEF(JSOP_NAMEINC, 47, "nameinc", NULL, 3, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_INC|JOF_POST|JOF_TMPSLOT3|JOF_DECOMPOSE)
OPDEF(JSOP_PROPINC, 48, "propinc", NULL, 3, 1, 1, 15, JOF_ATOM|JOF_PROP|JOF_INC|JOF_POST|JOF_TMPSLOT3|JOF_DECOMPOSE)
OPDEF(JSOP_ELEMINC, 49, "eleminc", NULL, 1, 2, 1, 15, JOF_BYTE |JOF_ELEM|JOF_INC|JOF_POST|JOF_TMPSLOT2|JOF_DECOMPOSE)
OPDEF(JSOP_NAMEDEC, 50, "namedec", NULL, 3, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_DEC|JOF_POST|JOF_TMPSLOT3|JOF_DECOMPOSE)
OPDEF(JSOP_PROPDEC, 51, "propdec", NULL, 3, 1, 1, 15, JOF_ATOM|JOF_PROP|JOF_DEC|JOF_POST|JOF_TMPSLOT3|JOF_DECOMPOSE)
OPDEF(JSOP_ELEMDEC, 52, "elemdec", NULL, 1, 2, 1, 15, JOF_BYTE |JOF_ELEM|JOF_DEC|JOF_POST|JOF_TMPSLOT2|JOF_DECOMPOSE)
OPDEF(JSOP_INCNAME, 41, "incname", NULL, 4, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_INC|JOF_TMPSLOT3|JOF_DECOMPOSE)
OPDEF(JSOP_INCPROP, 42, "incprop", NULL, 4, 1, 1, 15, JOF_ATOM|JOF_PROP|JOF_INC|JOF_TMPSLOT3|JOF_DECOMPOSE)
OPDEF(JSOP_INCELEM, 43, "incelem", NULL, 2, 2, 1, 15, JOF_BYTE |JOF_ELEM|JOF_INC|JOF_TMPSLOT2|JOF_DECOMPOSE)
OPDEF(JSOP_DECNAME, 44, "decname", NULL, 4, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_DEC|JOF_TMPSLOT3|JOF_DECOMPOSE)
OPDEF(JSOP_DECPROP, 45, "decprop", NULL, 4, 1, 1, 15, JOF_ATOM|JOF_PROP|JOF_DEC|JOF_TMPSLOT3|JOF_DECOMPOSE)
OPDEF(JSOP_DECELEM, 46, "decelem", NULL, 2, 2, 1, 15, JOF_BYTE |JOF_ELEM|JOF_DEC|JOF_TMPSLOT2|JOF_DECOMPOSE)
OPDEF(JSOP_NAMEINC, 47, "nameinc", NULL, 4, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_INC|JOF_POST|JOF_TMPSLOT3|JOF_DECOMPOSE)
OPDEF(JSOP_PROPINC, 48, "propinc", NULL, 4, 1, 1, 15, JOF_ATOM|JOF_PROP|JOF_INC|JOF_POST|JOF_TMPSLOT3|JOF_DECOMPOSE)
OPDEF(JSOP_ELEMINC, 49, "eleminc", NULL, 2, 2, 1, 15, JOF_BYTE |JOF_ELEM|JOF_INC|JOF_POST|JOF_TMPSLOT2|JOF_DECOMPOSE)
OPDEF(JSOP_NAMEDEC, 50, "namedec", NULL, 4, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_DEC|JOF_POST|JOF_TMPSLOT3|JOF_DECOMPOSE)
OPDEF(JSOP_PROPDEC, 51, "propdec", NULL, 4, 1, 1, 15, JOF_ATOM|JOF_PROP|JOF_DEC|JOF_POST|JOF_TMPSLOT3|JOF_DECOMPOSE)
OPDEF(JSOP_ELEMDEC, 52, "elemdec", NULL, 2, 2, 1, 15, JOF_BYTE |JOF_ELEM|JOF_DEC|JOF_POST|JOF_TMPSLOT2|JOF_DECOMPOSE)
OPDEF(JSOP_GETPROP, 53, "getprop", NULL, 5, 1, 1, 18, JOF_ATOM|JOF_PROP|JOF_TYPESET)
OPDEF(JSOP_SETPROP, 54, "setprop", NULL, 3, 2, 1, 3, JOF_ATOM|JOF_PROP|JOF_SET|JOF_DETECTING)
@ -411,10 +411,10 @@ OPDEF(JSOP_RETRVAL, 155,"retrval", NULL, 1, 0, 0, 0, JOF_BYTE)
/* Free variable references that must either be found on the global or a ReferenceError */
OPDEF(JSOP_GETGNAME, 156,"getgname", NULL, 5, 0, 1, 19, JOF_ATOM|JOF_NAME|JOF_TYPESET|JOF_GNAME)
OPDEF(JSOP_SETGNAME, 157,"setgname", NULL, 3, 2, 1, 3, JOF_ATOM|JOF_NAME|JOF_SET|JOF_DETECTING|JOF_GNAME)
OPDEF(JSOP_INCGNAME, 158,"incgname", NULL, 3, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_INC|JOF_TMPSLOT3|JOF_GNAME|JOF_DECOMPOSE)
OPDEF(JSOP_DECGNAME, 159,"decgname", NULL, 3, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_DEC|JOF_TMPSLOT3|JOF_GNAME|JOF_DECOMPOSE)
OPDEF(JSOP_GNAMEINC, 160,"gnameinc", NULL, 3, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_INC|JOF_POST|JOF_TMPSLOT3|JOF_GNAME|JOF_DECOMPOSE)
OPDEF(JSOP_GNAMEDEC, 161,"gnamedec", NULL, 3, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_DEC|JOF_POST|JOF_TMPSLOT3|JOF_GNAME|JOF_DECOMPOSE)
OPDEF(JSOP_INCGNAME, 158,"incgname", NULL, 4, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_INC|JOF_TMPSLOT3|JOF_GNAME|JOF_DECOMPOSE)
OPDEF(JSOP_DECGNAME, 159,"decgname", NULL, 4, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_DEC|JOF_TMPSLOT3|JOF_GNAME|JOF_DECOMPOSE)
OPDEF(JSOP_GNAMEINC, 160,"gnameinc", NULL, 4, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_INC|JOF_POST|JOF_TMPSLOT3|JOF_GNAME|JOF_DECOMPOSE)
OPDEF(JSOP_GNAMEDEC, 161,"gnamedec", NULL, 4, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_DEC|JOF_POST|JOF_TMPSLOT3|JOF_GNAME|JOF_DECOMPOSE)
/* Regular expression literal requiring special "fork on exec" handling. */
OPDEF(JSOP_REGEXP, 162,"regexp", NULL, 3, 0, 1, 19, JOF_REGEXP)

View File

@ -222,7 +222,7 @@ JS_XDRFindClassById(JSXDRState *xdr, uint32 id);
* before deserialization of bytecode. If the saved version does not match
* the current version, abort deserialization and invalidate the file.
*/
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 91)
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 92)
/*
* Library-private functions.