diff --git a/js/src/jsinterp.cpp b/js/src/jsinterp.cpp index f2753ec5309..01449ee1097 100644 --- a/js/src/jsinterp.cpp +++ b/js/src/jsinterp.cpp @@ -2771,9 +2771,16 @@ JS_INTERPRET(JSContext *cx, JSInterpreterState *state) #endif #ifdef jstracer_cpp___ -# define ABORT_TRACE goto abort_trace +# define ABORT_TRACE \ + goto abort_trace; +# define ABORT_TRACE_IF_ERROR \ + JS_BEGIN_MACRO \ + if (js_GetRecorderError(cx)) \ + goto abort_trace; \ + JS_END_MACRO #else -# define ABORT_TRACE +# define ABORT_TRACE ((void*)0) +# define ABORT_TRACE_IF_ERROR ((void*)0) #endif #if JS_THREADED_INTERP @@ -2791,7 +2798,10 @@ JS_INTERPRET(JSContext *cx, JSInterpreterState *state) # undef OPDEF }; -# define DO_OP() JS_EXTENSION_(goto *jumpTable[op]) +# define DO_OP() JS_BEGIN_MACRO \ + ABORT_TRACE_IF_ERROR; \ + JS_EXTENSION_(goto *jumpTable[op]); \ + JS_END_MACRO # define DO_NEXT_OP(n) JS_BEGIN_MACRO \ METER_OP_PAIR(op, regs.pc[n]); \ op = (JSOp) *(regs.pc += (n)); \ @@ -2812,7 +2822,10 @@ JS_INTERPRET(JSContext *cx, JSInterpreterState *state) #else /* !JS_THREADED_INTERP */ -# define DO_OP() goto do_op +# define DO_OP() JS_BEGIN_MACRO \ + ABORT_TRACE_IF_ERROR; \ + goto do_op; \ + JS_END_MACRO # define DO_NEXT_OP(n) JS_BEGIN_MACRO \ JS_ASSERT((n) == len); \ goto advance_pc; \ @@ -2865,6 +2878,9 @@ JS_INTERPRET(JSContext *cx, JSInterpreterState *state) fp = cx->fp; script = fp->script; JS_ASSERT(script->length != 0); + + /* Make sure ok is initialized. */ + ok = false; if (state) RESTORE_STATE(state); @@ -6972,13 +6988,11 @@ JS_INTERPRET(JSContext *cx, JSInterpreterState *state) error: #ifdef jstracer_cpp___ - ok = JS_FALSE; SAVE_STATE(state, JS_NEXT_ERROR); return JS_FALSE; abort_trace: js_CallRecorder(cx, "stop", native_pointer_to_jsval(regs.pc)); - ok = JS_FALSE; SAVE_STATE(state, JS_NEXT_CONTINUE); return ok; #else @@ -7201,7 +7215,7 @@ JS_INTERPRET(JSContext *cx, JSInterpreterState *state) attempt_tracing: { js_CallRecorder(cx, "start", native_pointer_to_jsval(regs.pc)); - if (JS_TRACE_MONITOR(cx).error) { + if (js_GetRecorderError(cx)) { op = (JSOp) *regs.pc; DO_OP(); } diff --git a/js/src/jstracer.cpp b/js/src/jstracer.cpp index 217c8987e57..3123c80fba9 100644 --- a/js/src/jstracer.cpp +++ b/js/src/jstracer.cpp @@ -66,8 +66,6 @@ js_CallRecorder(JSContext* cx, const char* fn, uintN argc, jsval* argv) JSBool ok = #endif JS_CallFunctionName(cx, js_GetRecorder(cx), fn, argc, argv, &rval); - if (rval != JSVAL_TRUE) - JS_TRACE_MONITOR(cx).error = true; JS_ASSERT(ok); } @@ -84,3 +82,12 @@ js_CallRecorder(JSContext* cx, const char* name, jsval a, jsval b) jsval args[] = { a, b }; js_CallRecorder(cx, name, 2, args); } + +bool +js_GetRecorderError(JSContext* cx) +{ + jsval error; + return (JS_GetProperty(cx, JS_TRACE_MONITOR(cx).recorder, + "error", &error) != true) + || (error != JSVAL_FALSE); +} diff --git a/js/src/jstracer.h b/js/src/jstracer.h index 374c2af4dd7..78ac629bc1c 100644 --- a/js/src/jstracer.h +++ b/js/src/jstracer.h @@ -55,7 +55,6 @@ struct JSTraceMonitor { int freq; JSObject* recorder; - bool error; }; #define TRACE_TRIGGER_MASK 0x3f @@ -64,6 +63,8 @@ void js_CallRecorder(JSContext* cx, const char* fn, uintN argc, jsval* argv); void js_CallRecorder(JSContext* cx, const char* fn, jsval a); void js_CallRecorder(JSContext* cx, const char* fn, jsval a, jsval b); +bool js_GetRecorderError(JSContext* cx); + /* * The recorder needs to keep track of native machine addresses. This mapping * only works for aligned pointers. diff --git a/js/src/recorder.js b/js/src/recorder.js index 6f2614bfb9b..bf6363d1d5c 100644 --- a/js/src/recorder.js +++ b/js/src/recorder.js @@ -39,35 +39,30 @@ ({ start: function(pc, sp) { - this.anchorPC = pc; - this.anchorSP = this.SP = sp; - this.code = []; - this.map = {}; - print("Recording at @" + pc); - return true; + this.error = false; + this.anchorPC = pc; + this.anchorSP = this.SP = sp; + this.code = []; + this.map = {}; + print("Recording at @" + pc); }, stop: function(pc) { print("Recording ended at @" + pc); }, /* track the data flow through locals */ track: function(from, to) { - this.map[to] = this.map[from]; - return true; + this.map[to] = this.map[from]; }, /* emit an IR instruction */ emit: function(x, to) { - this.map[to] = this.code.push(x); - return true; + this.map[to] = this.code.push(x); }, /* register a change in the stack pointer */ setSP: function(sp) { - this.SP = sp; - return true; + this.SP = sp; }, /* create a constant and assign it to v */ constant: function(v, c) { - this.emit({ op: "constant", value: c }); - return true; + this.emit({ op: "constant", value: c }); } }); -