diff --git a/js/src/jstracer.cpp b/js/src/jstracer.cpp index a6c6383b2f0..c5793d10452 100644 --- a/js/src/jstracer.cpp +++ b/js/src/jstracer.cpp @@ -895,10 +895,12 @@ TraceRecorder::TraceRecorder(JSContext* cx, GuardRecord* _anchor, Fragment* _fra this->applyingArguments = false; this->trashTree = false; this->whichTreeToTrash = _fragment->root; + this->global_dslots = this->globalObj->dslots; debug_only_v(printf("recording starting from %s:%u@%u\n", cx->fp->script->filename, js_PCToLineNumber(cx, cx->fp->script, cx->fp->regs->pc), cx->fp->regs->pc - cx->fp->script->code);); + debug_only_v(printf("globalObj=%p, shape=%d\n", this->globalObj, OBJ_SHAPE(this->globalObj));) lir = lir_buf_writer = new (&gc) LirBufWriter(lirbuf); #ifdef DEBUG @@ -2651,6 +2653,12 @@ js_MonitorRecording(TraceRecorder* tr) // Clear one-shot flag used to communicate between record_JSOP_CALL and record_EnterFrame. tr->applyingArguments = false; + // In the future, handle dslots realloc by computing an offset from dslots instead. + if (tr->global_dslots != tr->globalObj->dslots) { + js_AbortRecording(cx, NULL, "globalObj->dslots reallocated"); + return false; + } + // Process deepAbort() requests now. if (tr->wasDeepAborted()) { js_AbortRecording(cx, NULL, "deep abort requested"); diff --git a/js/src/jstracer.h b/js/src/jstracer.h index 9a00eead726..09980dfe0a9 100644 --- a/js/src/jstracer.h +++ b/js/src/jstracer.h @@ -248,6 +248,7 @@ class TraceRecorder { Queue inlinedLoopEdges; Queue cfgMerges; JSTraceableNative* pendingTraceableNative; + jsval* global_dslots; bool isGlobal(jsval* p) const; ptrdiff_t nativeGlobalOffset(jsval* p) const;