Bug 684384 - Add JSOP_LABEL opcode for IonMonkey. r=dvander

This commit is contained in:
Jan de Mooij 2011-11-09 17:42:27 +01:00
Родитель 7555484c58
Коммит 073ee45aa6
10 изменённых файлов: 78 добавлений и 43 удалений

Просмотреть файл

@ -905,6 +905,7 @@ OptimizeSpanDeps(JSContext *cx, BytecodeEmitter *bce)
case JSOP_DEFAULT: op = JSOP_DEFAULTX; break;
case JSOP_TABLESWITCH: op = JSOP_TABLESWITCHX; break;
case JSOP_LOOKUPSWITCH: op = JSOP_LOOKUPSWITCHX; break;
case JSOP_LABEL: op = JSOP_LABELX; break;
default:
ReportStatementTooLarge(cx, bce);
return JS_FALSE;
@ -6359,7 +6360,11 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
break;
case PNK_COLON:
/* Emit an annotated nop so we know to decompile a label. */
/*
* Emit a JSOP_LABEL instruction. The argument is the offset to the statement
* following the labeled statement. This op has either a SRC_LABEL or
* SRC_LABELBRACE source note for the decompiler.
*/
atom = pn->pn_atom;
jsatomid index;
@ -6373,7 +6378,11 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
? SRC_LABELBRACE
: SRC_LABEL;
noteIndex = NewSrcNote2(cx, bce, noteType, ptrdiff_t(index));
if (noteIndex < 0 || Emit1(cx, bce, JSOP_NOP) < 0)
if (noteIndex < 0)
return JS_FALSE;
top = EmitJump(cx, bce, JSOP_LABEL, 0);
if (top < 0)
return JS_FALSE;
/* Emit code for the labeled statement. */
@ -6384,6 +6393,9 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
if (!PopStatementBCE(cx, bce))
return JS_FALSE;
/* Patch the JSOP_LABEL offset. */
CHECK_AND_SET_JUMP_OFFSET_AT(cx, bce, top);
/* If the statement was compound, emit a note for the end brace. */
if (noteType == SRC_LABELBRACE) {
if (NewSrcNote(cx, bce, SRC_ENDBRACE) < 0 ||

Просмотреть файл

@ -993,8 +993,8 @@ enum SrcNoteType {
SRC_PCBASE = 12, /* distance back from annotated getprop or
setprop op to left-most obj.prop.subprop
bytecode -- always a backward delta */
SRC_LABEL = 13, /* JSOP_NOP for label: with atomid immediate */
SRC_LABELBRACE = 14, /* JSOP_NOP for label: {...} begin brace */
SRC_LABEL = 13, /* JSOP_LABEL for label: with atomid immediate */
SRC_LABELBRACE = 14, /* JSOP_LABEL for label: {...} begin brace */
SRC_ENDBRACE = 15, /* JSOP_NOP for label: {...} end brace */
SRC_BREAK2LABEL = 16, /* JSOP_GOTO for 'break label' with atomid */
SRC_CONT2LABEL = 17, /* JSOP_GOTO for 'continue label' with atomid */

Просмотреть файл

@ -3389,6 +3389,8 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset,
case JSOP_LOOKUPSWITCH:
case JSOP_LOOKUPSWITCHX:
case JSOP_TRY:
case JSOP_LABEL:
case JSOP_LABELX:
break;
/* Bytecodes pushing values of known type. */

Просмотреть файл

@ -2089,6 +2089,12 @@ BEGIN_CASE(JSOP_NOTRACE)
/* No-op */
END_CASE(JSOP_TRACE)
BEGIN_CASE(JSOP_LABEL)
END_CASE(JSOP_LABEL)
BEGIN_CASE(JSOP_LABELX)
END_CASE(JSOP_LABELX)
check_backedge:
{
CHECK_BRANCH();
@ -4467,9 +4473,6 @@ BEGIN_CASE(JSOP_CALLFCSLOT)
}
END_CASE(JSOP_GETFCSLOT)
BEGIN_CASE(JSOP_UNUSED0)
BEGIN_CASE(JSOP_UNUSED1)
BEGIN_CASE(JSOP_DEFCONST)
BEGIN_CASE(JSOP_DEFVAR)
{

Просмотреть файл

@ -2389,27 +2389,6 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
len = tail + js_CodeSpec[pc[tail]].length;
break;
case SRC_LABEL:
GET_SOURCE_NOTE_ATOM(sn, atom);
jp->indent -= 4;
rval = QuoteString(&ss->sprinter, atom, 0);
if (!rval)
return NULL;
RETRACT(&ss->sprinter, rval);
js_printf(jp, "\t%s:\n", rval);
jp->indent += 4;
break;
case SRC_LABELBRACE:
GET_SOURCE_NOTE_ATOM(sn, atom);
rval = QuoteString(&ss->sprinter, atom, 0);
if (!rval)
return NULL;
RETRACT(&ss->sprinter, rval);
js_printf(jp, "\t%s: {\n", rval);
jp->indent += 4;
break;
case SRC_ENDBRACE:
jp->indent -= 4;
js_printf(jp, "\t}\n");
@ -2446,6 +2425,38 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
}
break;
case JSOP_LABEL:
case JSOP_LABELX:
sn = js_GetSrcNote(jp->script, pc);
todo = -2;
switch (sn ? SN_TYPE(sn) : SRC_NULL) {
case SRC_LABEL:
GET_SOURCE_NOTE_ATOM(sn, atom);
jp->indent -= 4;
rval = QuoteString(&ss->sprinter, atom, 0);
if (!rval)
return NULL;
RETRACT(&ss->sprinter, rval);
js_printf(jp, "\t%s:\n", rval);
jp->indent += 4;
break;
case SRC_LABELBRACE:
GET_SOURCE_NOTE_ATOM(sn, atom);
rval = QuoteString(&ss->sprinter, atom, 0);
if (!rval)
return NULL;
RETRACT(&ss->sprinter, rval);
js_printf(jp, "\t%s: {\n", rval);
jp->indent += 4;
break;
default:
JS_NOT_REACHED("JSOP_LABEL without source note");
break;
}
break;
case JSOP_PUSH:
#if JS_HAS_DESTRUCTURING
sn = js_GetSrcNote(jp->script, pc);

Просмотреть файл

@ -274,9 +274,9 @@ OPDEF(JSOP_LOCALDEC, 104,"localdec", NULL, 3, 0, 1, 15, JOF_LOCAL|
OPDEF(JSOP_IMACOP, 105,"imacop", NULL, 1, 0, 0, 0, JOF_BYTE)
/* Static binding for globals. */
OPDEF(JSOP_UNUSED0, 106,"unused0", NULL, 3, 0, 1, 19, JOF_BYTE)
OPDEF(JSOP_UNUSED1, 107,"unused1", NULL, 3, 0, 2, 19, JOF_BYTE)
/* The argument is the offset to the next statement and is used by IonMonkey. */
OPDEF(JSOP_LABEL, 106,"label", NULL, 3, 0, 0, 0, JOF_JUMP)
OPDEF(JSOP_LABELX, 107,"labelx", NULL, 5, 0, 0, 0, JOF_JUMPX)
/* Like JSOP_FUNAPPLY but for f.call instead of f.apply. */
OPDEF(JSOP_FUNCALL, 108,"funcall", NULL, 3, -1, 1, 18, JOF_UINT16|JOF_INVOKE|JOF_TYPESET)

Просмотреть файл

@ -15421,6 +15421,16 @@ TraceRecorder::record_JSOP_FINALLY()
return ARECORD_CONTINUE;
}
JS_REQUIRES_STACK AbortableRecordingStatus
TraceRecorder::record_JSOP_LABEL() {
return ARECORD_CONTINUE;
}
JS_REQUIRES_STACK AbortableRecordingStatus
TraceRecorder::record_JSOP_LABELX() {
return ARECORD_CONTINUE;
}
JS_REQUIRES_STACK AbortableRecordingStatus
TraceRecorder::record_JSOP_NOP()
{
@ -16157,16 +16167,6 @@ TraceRecorder::record_JSOP_SHARPINIT()
return ARECORD_STOP;
}
JS_REQUIRES_STACK AbortableRecordingStatus
TraceRecorder::record_JSOP_UNUSED0() {
return ARECORD_CONTINUE;
}
JS_REQUIRES_STACK AbortableRecordingStatus
TraceRecorder::record_JSOP_UNUSED1() {
return ARECORD_CONTINUE;
}
JS_REQUIRES_STACK AbortableRecordingStatus
TraceRecorder::record_JSOP_GETGNAME()
{

Просмотреть файл

@ -225,7 +225,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 - 96)
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 97)
/*
* Library-private functions.

Просмотреть файл

@ -2504,6 +2504,12 @@ mjit::Compiler::generateMethod()
/* No-op for the decompiler. */
END_CASE(JSOP_CONDSWITCH)
BEGIN_CASE(JSOP_LABEL)
END_CASE(JSOP_LABEL)
BEGIN_CASE(JSOP_LABELX)
END_CASE(JSOP_LABELX)
BEGIN_CASE(JSOP_DEFFUN)
{
uint32 index = fullAtomIndex(PC);

Просмотреть файл

@ -1866,7 +1866,8 @@ SrcNotes(JSContext *cx, JSScript *script, Sprinter *sp)
if (switchTableStart <= offset && offset < switchTableEnd) {
name = "case";
} else {
JS_ASSERT(js_GetOpcode(cx, script, script->code + offset) == JSOP_NOP);
JSOp op = js_GetOpcode(cx, script, script->code + offset);
JS_ASSERT(op == JSOP_LABEL || op == JSOP_LABELX);
}
}
Sprint(sp, "%3u: %4u %5u [%4u] %-8s", uintN(sn - notes), lineno, offset, delta, name);