diff --git a/js/src/jsanalyze.cpp b/js/src/jsanalyze.cpp index ac703fd9ebd..41a8509f260 100644 --- a/js/src/jsanalyze.cpp +++ b/js/src/jsanalyze.cpp @@ -1894,6 +1894,12 @@ SSAValue::print() const } } +void +ScriptAnalysis::assertMatchingDebugMode() +{ + JS_ASSERT(!!script->compartment()->debugMode() == !!originalDebugMode_); +} + #endif /* DEBUG */ } /* namespace analyze */ diff --git a/js/src/jsanalyze.h b/js/src/jsanalyze.h index e4e5d2921a2..38ca6a8cf8b 100644 --- a/js/src/jsanalyze.h +++ b/js/src/jsanalyze.h @@ -822,6 +822,11 @@ class ScriptAnalysis bool ranLifetimes_; bool ranInference_; +#ifdef DEBUG + /* Whether the compartment was in debug mode when we performed the analysis. */ + bool originalDebugMode_: 1; +#endif + /* --------- Bytecode analysis --------- */ bool usesReturnValue_:1; @@ -843,7 +848,13 @@ class ScriptAnalysis public: - ScriptAnalysis(JSScript *script) { PodZero(this); this->script = script; } + ScriptAnalysis(JSScript *script) { + PodZero(this); + this->script = script; +#ifdef DEBUG + this->originalDebugMode_ = script->compartment()->debugMode(); +#endif + } bool ranBytecode() { return ranBytecode_; } bool ranSSA() { return ranSSA_; } @@ -1164,6 +1175,13 @@ class ScriptAnalysis bool analyzeTypesBytecode(JSContext *cx, unsigned offset, TypeInferenceState &state); bool followEscapingArguments(JSContext *cx, const SSAValue &v, Vector *seen); bool followEscapingArguments(JSContext *cx, SSAUseChain *use, Vector *seen); + + public: +#ifdef DEBUG + void assertMatchingDebugMode(); +#else + void assertMatchingDebugMode() { } +#endif }; /* Protect analysis structures from GC while they are being used. */ diff --git a/js/src/jscompartment.cpp b/js/src/jscompartment.cpp index ad862a7ccc2..5e611e54cb7 100644 --- a/js/src/jscompartment.cpp +++ b/js/src/jscompartment.cpp @@ -639,13 +639,14 @@ JSCompartment::updateForDebugMode(JSContext *cx) } /* - * Discard JIT code for any scripts that change debugMode. This assumes - * that 'comp' is in the same thread as 'cx'. + * Discard JIT code and bytecode analyses for any scripts that change + * debugMode. This assumes that 'comp' is in the same thread as 'cx'. */ for (gc::CellIter i(cx, this, gc::FINALIZE_SCRIPT); !i.done(); i.next()) { JSScript *script = i.get(); if (script->debugMode != enabled) { mjit::ReleaseScriptCode(cx, script); + script->clearAnalysis(); script->debugMode = enabled; } } diff --git a/js/src/methodjit/Compiler.cpp b/js/src/methodjit/Compiler.cpp index d788afdc87a..2c3d452fafc 100644 --- a/js/src/methodjit/Compiler.cpp +++ b/js/src/methodjit/Compiler.cpp @@ -189,6 +189,7 @@ mjit::Compiler::checkAnalysis(JSScript *script) return Compile_Error; ScriptAnalysis *analysis = script->analysis(); + analysis->assertMatchingDebugMode(); if (analysis->failed()) { JaegerSpew(JSpew_Abort, "couldn't analyze bytecode; probably switchX or OOM\n"); return Compile_Abort;