bug 441686 - eliminating JSStackFrame.(nvars|vars). r=brendan

This commit is contained in:
Igor Bukanov
2008-07-20 22:13:17 +02:00
parent 4b6980a693
commit e9875f6677
17 changed files with 473 additions and 423 deletions

View File

@@ -159,6 +159,44 @@ js_GetIndexFromBytecode(JSContext *cx, JSScript *script, jsbytecode *pc,
return base + GET_UINT16(pc + pcoff);
}
uintN
js_GetVariableBytecodeLength(jsbytecode *pc)
{
JSOp op;
uintN jmplen, ncases;
jsint low, high;
op = (JSOp) *pc;
JS_ASSERT(js_CodeSpec[op].length == -1);
switch (op) {
case JSOP_TABLESWITCHX:
jmplen = JUMPX_OFFSET_LEN;
goto do_table;
case JSOP_TABLESWITCH:
jmplen = JUMP_OFFSET_LEN;
do_table:
/* Structure: default-jump case-low case-high case1-jump ... */
pc += jmplen;
low = GET_JUMP_OFFSET(pc);
pc += JUMP_OFFSET_LEN;
high = GET_JUMP_OFFSET(pc);
ncases = (uintN)(high - low + 1);
return 1 + jmplen + INDEX_LEN + INDEX_LEN + ncases * jmplen;
case JSOP_LOOKUPSWITCHX:
jmplen = JUMPX_OFFSET_LEN;
goto do_lookup;
default:
JS_ASSERT(op == JSOP_LOOKUPSWITCH);
jmplen = JUMP_OFFSET_LEN;
do_lookup:
/* Structure: default-jump case-count (case1-value case1-jump) ... */
pc += jmplen;
ncases = GET_UINT16(pc);
return 1 + jmplen + INDEX_LEN + ncases * (INDEX_LEN + jmplen);
}
}
#ifdef DEBUG
JS_FRIEND_API(JSBool)
@@ -351,13 +389,13 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
break;
case JOF_QVAR:
fprintf(fp, " %u", GET_VARNO(pc));
fprintf(fp, " %u", GET_SLOTNO(pc));
break;
case JOF_SLOTATOM:
case JOF_SLOTOBJECT:
fprintf(fp, " %u", GET_VARNO(pc));
index = js_GetIndexFromBytecode(cx, script, pc, VARNO_LEN);
fprintf(fp, " %u", GET_SLOTNO(pc));
index = js_GetIndexFromBytecode(cx, script, pc, SLOTNO_LEN);
if (type == JOF_SLOTATOM) {
JS_GET_SCRIPT_ATOM(script, index, atom);
v = ATOM_KEY(atom);
@@ -638,7 +676,7 @@ struct JSPrinter {
#define JS_IN_GROUP_CONTEXT 0x10000
JSPrinter *
JS_NEW_PRINTER(JSContext *cx, const char *name, JSFunction *fun,
JS_NEW_PRINTER(JSContext *cx, const char *name, JSFunction *fun,
uintN indent, JSBool pretty)
{
JSPrinter *jp;
@@ -891,8 +929,8 @@ PushOff(SprintStack *ss, ptrdiff_t off, JSOp op)
/* ss->top points to the next free slot; be paranoid about overflow. */
top = ss->top;
JS_ASSERT(top < ss->printer->script->depth);
if (top >= ss->printer->script->depth) {
JS_ASSERT(top < StackDepth(ss->printer->script));
if (top >= StackDepth(ss->printer->script)) {
JS_ReportOutOfMemory(ss->sprinter.context);
return JS_FALSE;
}
@@ -1187,7 +1225,8 @@ GetLocal(SprintStack *ss, jsint i)
cx = ss->sprinter.context;
script = ss->printer->script;
LOCAL_ASSERT(script->objectsOffset != 0);
for (j = 0, n = JS_SCRIPT_OBJECTS(script)->length; j < n; j++) {
for (j = 0, n = JS_SCRIPT_OBJECTS(script)->length; ; j++) {
LOCAL_ASSERT(j < n);
JS_GET_SCRIPT_OBJECT(script, j, obj);
if (OBJ_GET_CLASS(cx, obj) == &js_BlockClass) {
depth = OBJ_BLOCK_DEPTH(cx, obj);
@@ -1197,7 +1236,6 @@ GetLocal(SprintStack *ss, jsint i)
}
}
LOCAL_ASSERT(j < n);
i -= depth;
for (sprop = OBJ_SCOPE(obj)->lastProp; sprop; sprop = sprop->parent) {
if (sprop->shortid == i)
@@ -1269,7 +1307,7 @@ DecompileDestructuringLHS(SprintStack *ss, jsbytecode *pc, jsbytecode *endpc,
/* FALL THROUGH */
case JSOP_SETLOCALPOP:
i = GET_UINT16(pc);
i = GET_SLOTNO(pc);
atom = NULL;
lval = NULL;
if (op == JSOP_SETARG || op == JSOP_SETVAR) {
@@ -1278,7 +1316,7 @@ DecompileDestructuringLHS(SprintStack *ss, jsbytecode *pc, jsbytecode *endpc,
} else if (op == JSOP_SETGVAR) {
GET_ATOM_FROM_BYTECODE(jp->script, pc, 0, atom);
} else {
lval = GetLocal(ss, i);
lval = GetLocal(ss, i - jp->script->nfixed);
}
if (atom)
lval = js_AtomToPrintableString(cx, atom);
@@ -1666,7 +1704,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
static const char ss_format[] = "%s%s";
/* Argument and variables decompilation uses the following to share code. */
JS_STATIC_ASSERT(ARGNO_LEN == VARNO_LEN);
JS_STATIC_ASSERT(ARGNO_LEN == SLOTNO_LEN);
/*
* Local macros
@@ -2253,7 +2291,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
goto do_forloop;
}
if (SN_TYPE(sn) == SRC_DECL) {
if (ss->top == jp->script->depth) {
if (ss->top == StackDepth(jp->script)) {
/*
* This must be an empty destructuring
* in the head of a let whose body block
@@ -2556,7 +2594,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
} else {
#endif
LOCAL_ASSERT(*pc == JSOP_SETLOCALPOP);
i = GET_UINT16(pc);
i = GET_SLOTNO(pc) - jp->script->nfixed;
pc += JSOP_SETLOCALPOP_LENGTH;
atom = atomv[i - OBJ_BLOCK_DEPTH(cx, obj)];
str = ATOM_TO_STRING(atom);
@@ -2650,7 +2688,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
case JSOP_CALLLOCAL:
case JSOP_GETLOCAL:
i = GET_UINT16(pc);
i = GET_SLOTNO(pc) - jp->script->nfixed;
LOCAL_ASSERT((uintN)i < ss->top);
sn = js_GetSrcNote(jp->script, pc);
@@ -2671,25 +2709,25 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
case JSOP_SETLOCAL:
case JSOP_SETLOCALPOP:
i = GET_UINT16(pc);
i = GET_SLOTNO(pc) - jp->script->nfixed;
lval = GetStr(ss, i);
rval = POP_STR();
goto do_setlval;
case JSOP_INCLOCAL:
case JSOP_DECLOCAL:
i = GET_UINT16(pc);
i = GET_SLOTNO(pc) - jp->script->nfixed;
lval = GetLocal(ss, i);
goto do_inclval;
case JSOP_LOCALINC:
case JSOP_LOCALDEC:
i = GET_UINT16(pc);
i = GET_SLOTNO(pc) - jp->script->nfixed;
lval = GetLocal(ss, i);
goto do_lvalinc;
case JSOP_FORLOCAL:
i = GET_UINT16(pc);
i = GET_SLOTNO(pc) - jp->script->nfixed;
lval = GetStr(ss, i);
atom = NULL;
goto do_forlvalinloop;
@@ -3047,7 +3085,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
case JSOP_FORVAR:
case JSOP_FORCONST:
atom = GetSlotAtom(jp, JS_FALSE, GET_VARNO(pc));
atom = GetSlotAtom(jp, JS_FALSE, GET_SLOTNO(pc));
LOCAL_ASSERT(atom);
goto do_fornameinloop;
@@ -3281,7 +3319,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
goto do_setname;
case JSOP_SETVAR:
atom = GetSlotAtom(jp, JS_FALSE, GET_VARNO(pc));
atom = GetSlotAtom(jp, JS_FALSE, GET_SLOTNO(pc));
LOCAL_ASSERT(atom);
goto do_setname;
@@ -3462,7 +3500,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
case JSOP_INCVAR:
case JSOP_DECVAR:
atom = GetSlotAtom(jp, JS_FALSE, GET_VARNO(pc));
atom = GetSlotAtom(jp, JS_FALSE, GET_SLOTNO(pc));
LOCAL_ASSERT(atom);
goto do_incatom;
@@ -3524,7 +3562,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
case JSOP_VARINC:
case JSOP_VARDEC:
atom = GetSlotAtom(jp, JS_FALSE, GET_VARNO(pc));
atom = GetSlotAtom(jp, JS_FALSE, GET_SLOTNO(pc));
LOCAL_ASSERT(atom);
goto do_atominc;
@@ -3622,7 +3660,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
case JSOP_GETLOCALPROP:
LOAD_ATOM(2);
i = GET_UINT16(pc);
i = GET_SLOTNO(pc) - jp->script->nfixed;
LOCAL_ASSERT((uintN)i < ss->top);
lval = GetLocal(ss, i);
if (!lval)
@@ -3731,7 +3769,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
case JSOP_CALLVAR:
case JSOP_GETVAR:
atom = GetSlotAtom(jp, JS_FALSE, GET_VARNO(pc));
atom = GetSlotAtom(jp, JS_FALSE, GET_SLOTNO(pc));
LOCAL_ASSERT(atom);
goto do_name;
@@ -3807,7 +3845,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
* before returning.
*/
mark = JS_ARENA_MARK(&cx->tempPool);
if (!InitSprintStack(cx, &ss2, jp, inner->depth))
if (!InitSprintStack(cx, &ss2, jp, StackDepth(inner)))
return NULL;
ss2.inGenExp = JS_TRUE;
@@ -4651,7 +4689,7 @@ DecompileCode(JSPrinter *jp, JSScript *script, jsbytecode *pc, uintN len,
jsbytecode *oldcode, *oldmain, *code;
char *last;
depth = script->depth;
depth = StackDepth(script);
JS_ASSERT(pcdepth <= depth);
/* Initialize a sprinter for use with the offset stack. */
@@ -4818,7 +4856,7 @@ js_DecompileFunction(JSPrinter *jp)
LOCAL_ASSERT(*pc == JSOP_DUP);
if (!ss.printer) {
ok = InitSprintStack(jp->sprinter.context, &ss, jp,
fun->u.i.script->depth);
StackDepth(fun->u.i.script));
if (!ok)
break;
}
@@ -4886,7 +4924,7 @@ js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v,
JSScript *script;
JSFrameRegs *regs;
intN pcdepth;
jsval *sp;
jsval *sp, *stackBase;
char *name;
JS_ASSERT(spindex < 0 ||
@@ -4914,7 +4952,7 @@ js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v,
* populated interpreter's stack with its current content.
*/
pcstack = (jsbytecode **)
JS_malloc(cx, script->depth * sizeof *pcstack);
JS_malloc(cx, StackDepth(script) * sizeof *pcstack);
if (!pcstack)
return NULL;
pcdepth = ReconstructPCStack(cx, script, regs->pc, pcstack);
@@ -4933,16 +4971,17 @@ js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v,
* calculated value matching v under assumption that it is
* it that caused exception, see bug 328664.
*/
JS_ASSERT((size_t) (regs->sp - fp->spbase) <= script->depth);
stackBase = StackBase(fp);
JS_ASSERT((size_t) (regs->sp - stackBase) <= StackDepth(script));
sp = regs->sp;
do {
if (sp == fp->spbase) {
if (sp == stackBase) {
pcdepth = -1;
goto release_pcstack;
}
} while (*--sp != v);
if (sp >= fp->spbase + pcdepth) {
if (sp >= stackBase + pcdepth) {
/*
* This happens when the value comes from a temporary slot
* that the interpreter uses for GC roots. Assume that it is
@@ -4950,7 +4989,7 @@ js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v,
*/
pc = regs->pc;
} else {
pc = pcstack[sp - fp->spbase];
pc = pcstack[sp - stackBase];
}
}
@@ -5064,7 +5103,8 @@ DecompileExpression(JSContext *cx, JSScript *script, JSFunction *fun,
goto out;
}
pcstack = (jsbytecode **) JS_malloc(cx, script->depth * sizeof *pcstack);
pcstack = (jsbytecode **)
JS_malloc(cx, StackDepth(script) * sizeof *pcstack);
if (!pcstack) {
name = NULL;
goto out;
@@ -5110,8 +5150,6 @@ ReconstructPCStack(JSContext *cx, JSScript *script, jsbytecode *pc,
const JSCodeSpec *cs;
ptrdiff_t oplen;
jssrcnote *sn;
uint32 type;
jsbytecode *pc2;
intN i;
#define LOCAL_ASSERT(expr) LOCAL_ASSERT_RV(expr, -1);
@@ -5132,6 +5170,8 @@ ReconstructPCStack(JSContext *cx, JSScript *script, jsbytecode *pc,
op = JS_GetTrapOpcode(cx, script, pc);
cs = &js_CodeSpec[op];
oplen = cs->length;
if (oplen < 0)
oplen = js_GetVariableBytecodeLength(pc);
if (op == JSOP_POPN) {
pcdepth -= GET_UINT16(pc);
@@ -5180,51 +5220,6 @@ ReconstructPCStack(JSContext *cx, JSScript *script, jsbytecode *pc,
}
}
type = JOF_TYPE(cs->format);
switch (type) {
case JOF_TABLESWITCH:
case JOF_TABLESWITCHX:
{
jsint jmplen, low, high;
jmplen = (type == JOF_TABLESWITCH) ? JUMP_OFFSET_LEN
: JUMPX_OFFSET_LEN;
pc2 = pc;
pc2 += jmplen;
low = GET_JUMP_OFFSET(pc2);
pc2 += JUMP_OFFSET_LEN;
high = GET_JUMP_OFFSET(pc2);
pc2 += JUMP_OFFSET_LEN;
for (i = low; i <= high; i++)
pc2 += jmplen;
oplen = 1 + pc2 - pc;
break;
}
case JOF_LOOKUPSWITCH:
case JOF_LOOKUPSWITCHX:
{
jsint jmplen;
jsatomid npairs;
jmplen = (type == JOF_LOOKUPSWITCH) ? JUMP_OFFSET_LEN
: JUMPX_OFFSET_LEN;
pc2 = pc;
pc2 += jmplen;
npairs = GET_UINT16(pc2);
pc2 += INDEX_LEN;
while (npairs) {
pc2 += INDEX_LEN;
pc2 += jmplen;
npairs--;
}
oplen = 1 + pc2 - pc;
break;
}
default:;
}
if (sn && SN_TYPE(sn) == SRC_HIDDEN)
continue;
@@ -5257,7 +5252,7 @@ ReconstructPCStack(JSContext *cx, JSScript *script, jsbytecode *pc,
ndefs = OBJ_BLOCK_COUNT(cx, obj);
}
LOCAL_ASSERT((uintN)(pcdepth + ndefs) <= script->depth);
LOCAL_ASSERT((uintN)(pcdepth + ndefs) <= StackDepth(script));
/*
* Fill the slots that the opcode defines withs its pc unless it just