From db48c38fa9411a495bbd4b6970450e7b089348f2 Mon Sep 17 00:00:00 2001 From: Brendan Eich Date: Mon, 9 Mar 2009 18:34:35 -0700 Subject: [PATCH] Bug 476240 - Generate via imacro_asm.js the big condition in TraceRecorder::monitorRecording's OPDEF macro (r=gal). --- js/src/imacro_asm.js.in | 5 +++++ js/src/imacros.c.out | 28 ++++++++++++++++++++++++++++ js/src/jstracer.cpp | 39 +++++++++++++++++++-------------------- 3 files changed, 52 insertions(+), 20 deletions(-) diff --git a/js/src/imacro_asm.js.in b/js/src/imacro_asm.js.in index c1e0a8533a7..132e4d1c19a 100644 --- a/js/src/imacro_asm.js.in +++ b/js/src/imacro_asm.js.in @@ -324,6 +324,11 @@ function assemble(filename) { ", /* " + opinfo[i].jsop + " */"); } print("};"); + + print("#define JSOP_IS_IMACOP(x) (0 \\"); + for (let i in opcode2extra) + print(" || x == " + opinfo[i].jsop + " \\"); + print(")"); } for (let i = 0; i < arguments.length; i++) { diff --git a/js/src/imacros.c.out b/js/src/imacros.c.out index f0a06f1a239..59e0f5e2070 100644 --- a/js/src/imacros.c.out +++ b/js/src/imacros.c.out @@ -914,3 +914,31 @@ uint8 js_opcode2extra[JSOP_LIMIT] = { 0, /* JSOP_HOLE */ 0, /* JSOP_LOOP */ }; +#define JSOP_IS_IMACOP(x) (0 \ + || x == JSOP_BITOR \ + || x == JSOP_BITXOR \ + || x == JSOP_BITAND \ + || x == JSOP_EQ \ + || x == JSOP_NE \ + || x == JSOP_LT \ + || x == JSOP_LE \ + || x == JSOP_GT \ + || x == JSOP_GE \ + || x == JSOP_LSH \ + || x == JSOP_RSH \ + || x == JSOP_URSH \ + || x == JSOP_ADD \ + || x == JSOP_SUB \ + || x == JSOP_MUL \ + || x == JSOP_DIV \ + || x == JSOP_MOD \ + || x == JSOP_NEG \ + || x == JSOP_POS \ + || x == JSOP_GETELEM \ + || x == JSOP_SETELEM \ + || x == JSOP_CALL \ + || x == JSOP_ITER \ + || x == JSOP_NEXTITER \ + || x == JSOP_APPLY \ + || x == JSOP_INITELEM \ +) diff --git a/js/src/jstracer.cpp b/js/src/jstracer.cpp index c963152821a..7fe7184d7c6 100644 --- a/js/src/jstracer.cpp +++ b/js/src/jstracer.cpp @@ -4347,14 +4347,14 @@ TraceRecorder::monitorRecording(JSContext* cx, TraceRecorder* tr, JSOp op) if (!js_CloseLoop(cx)) return JSMRS_STOP; } else { - // Clear one-shot state used to communicate between record_JSOP_CALL and post- - // opcode-case-guts record hook (record_FastNativeCallComplete). + /* Clear one-shot state used to communicate between record_JSOP_CALL and post- + opcode-case-guts record hook (record_FastNativeCallComplete). */ tr->pendingTraceableNative = NULL; jsbytecode* pc = cx->fp->regs->pc; - /* If we hit a break, end the loop and generate an always taken loop exit guard. For other - downward gotos (like if/else) continue recording. */ + /* If we hit a break, end the loop and generate an always taken loop exit guard. + For other downward gotos (like if/else) continue recording. */ if (*pc == JSOP_GOTO || *pc == JSOP_GOTOX) { jssrcnote* sn = js_GetSrcNote(cx->fp->script, pc); if (sn && SN_TYPE(sn) == SRC_BREAK) { @@ -4372,8 +4372,9 @@ TraceRecorder::monitorRecording(JSContext* cx, TraceRecorder* tr, JSOp op) js_DeleteRecorder(cx); return JSMRS_STOP; /* done recording */ } + #ifdef NANOJIT_IA32 - /* Handle tableswitches specially--prepare a jump table if needed. */ + /* Handle tableswitches specially -- prepare a jump table if needed. */ if (*pc == JSOP_TABLESWITCH || *pc == JSOP_TABLESWITCHX) { LIns* guardIns = tr->tableswitch(); if (guardIns) { @@ -4386,10 +4387,10 @@ TraceRecorder::monitorRecording(JSContext* cx, TraceRecorder* tr, JSOp op) #endif } - /* If it's not a break or a return from a loop, continue recording and follow the trace. */ + /* If op is not a break or a return from a loop, continue recording and follow the + trace. We check for imacro-calling bytecodes inside each switch case to resolve + the if (JSOP_IS_IMACOP(x)) conditions at compile time. */ - /* We check for imacro-calling bytecodes inside the switch cases to resolve - the "if" condition at the compile time. */ bool flag; switch (op) { default: goto abort_recording; @@ -4402,12 +4403,8 @@ TraceRecorder::monitorRecording(JSContext* cx, TraceRecorder* tr, JSOp op) : cx->fp->regs->pc - cx->fp->script->code, \ !cx->fp->imacpc, stdout);) \ flag = tr->record_##x(); \ - if (x == JSOP_ITER || x == JSOP_NEXTITER || x == JSOP_APPLY || \ - x == JSOP_GETELEM || x == JSOP_SETELEM || x== JSOP_INITELEM || \ - x == JSOP_CALL || JSOP_IS_BINARY(x) || JSOP_IS_UNARY(x) || \ - JSOP_IS_EQUALITY(x)) { \ + if (JSOP_IS_IMACOP(x)) \ goto imacro; \ - } \ break; # include "jsopcode.tbl" # undef OPDEF @@ -5019,9 +5016,9 @@ TraceRecorder::ifop() } #ifdef NANOJIT_IA32 -/* Record LIR for a tableswitch or tableswitchx op. We record LIR only - * the "first" time we hit the op. Later, when we start traces after - * exiting that trace, we just patch. */ +/* Record LIR for a tableswitch or tableswitchx op. We record LIR only the + "first" time we hit the op. Later, when we start traces after exiting that + trace, we just patch. */ JS_REQUIRES_STACK LIns* TraceRecorder::tableswitch() { @@ -5036,9 +5033,11 @@ TraceRecorder::tableswitch() jsbytecode* pc = cx->fp->regs->pc; /* Starting a new trace after exiting a trace via switch. */ - if (anchor && (anchor->exitType == CASE_EXIT || - anchor->exitType == DEFAULT_EXIT) && fragment->ip == pc) + if (anchor && + (anchor->exitType == CASE_EXIT || anchor->exitType == DEFAULT_EXIT) && + fragment->ip == pc) { return NULL; + } /* Decode jsop. */ jsint low, high; @@ -5054,8 +5053,8 @@ TraceRecorder::tableswitch() high = GET_JUMPX_OFFSET(pc); } - /* Really large tables won't fit in a page. This is a conservative - * check. If it matters in practice we need to go off-page. */ + /* Really large tables won't fit in a page. This is a conservative check. + If it matters in practice we need to go off-page. */ if ((high + 1 - low) * sizeof(intptr_t*) + 128 > (unsigned) LARGEST_UNDERRUN_PROT) { // This throws away the return value of switchop but it seems // ok because switchop always returns true.