From 879c0730389669a6472fc89f1e22dcc5dc84dc1f Mon Sep 17 00:00:00 2001 From: Shu-yu Guo Date: Thu, 13 Nov 2014 14:39:41 -0800 Subject: [PATCH] Bug 1032869 - Part 4: Add an auto-updated DebugModeOSRVolatileJitFrameIterator. (r=jandem) --- js/src/jit/BaselineDebugModeOSR.cpp | 13 +++++++++++++ js/src/jit/BaselineDebugModeOSR.h | 26 ++++++++++++++++++++++++++ js/src/jit/IonFrames.cpp | 8 +++++++- js/src/jscntxt.cpp | 1 + js/src/jscntxt.h | 6 ++++++ 5 files changed, 53 insertions(+), 1 deletion(-) diff --git a/js/src/jit/BaselineDebugModeOSR.cpp b/js/src/jit/BaselineDebugModeOSR.cpp index 670159c479ca..f9e184386930 100644 --- a/js/src/jit/BaselineDebugModeOSR.cpp +++ b/js/src/jit/BaselineDebugModeOSR.cpp @@ -380,6 +380,8 @@ PatchBaselineFramesForDebugMode(JSContext *cx, const Debugger::ExecutionObservab // directly to the IC resume address. uint8_t *retAddr = bl->returnAddressForIC(bl->icEntryFromPCOffset(pcOffset)); SpewPatchBaselineFrame(prev->returnAddress(), retAddr, script, kind, pc); + DebugModeOSRVolatileJitFrameIterator::forwardLiveIterators( + cx, prev->returnAddress(), retAddr); prev->setReturnAddress(retAddr); entryIndex++; break; @@ -995,3 +997,14 @@ JitRuntime::generateBaselineDebugModeOSRHandler(JSContext *cx, uint32_t *noFrame return code; } + +/* static */ void +DebugModeOSRVolatileJitFrameIterator::forwardLiveIterators(JSContext *cx, + uint8_t *oldAddr, uint8_t *newAddr) +{ + DebugModeOSRVolatileJitFrameIterator *iter; + for (iter = cx->liveVolatileJitFrameIterators_; iter; iter = iter->prev) { + if (iter->returnAddressToFp_ == oldAddr) + iter->returnAddressToFp_ = newAddr; + } +} diff --git a/js/src/jit/BaselineDebugModeOSR.h b/js/src/jit/BaselineDebugModeOSR.h index af7318267fe8..82a7301945ae 100644 --- a/js/src/jit/BaselineDebugModeOSR.h +++ b/js/src/jit/BaselineDebugModeOSR.h @@ -10,6 +10,7 @@ #include "jit/BaselineFrame.h" #include "jit/BaselineIC.h" #include "jit/BaselineJIT.h" +#include "jit/JitFrameIterator.h" #include "vm/Debugger.h" @@ -67,6 +68,31 @@ class DebugModeOSRVolatileStub bool operator==(const T &other) const { MOZ_ASSERT(!invalid()); return stub_ == other; } }; +// +// A JitFrameIterator that updates itself in case of recompilation of an +// on-stack baseline script. +// +class DebugModeOSRVolatileJitFrameIterator : public JitFrameIterator +{ + DebugModeOSRVolatileJitFrameIterator **stack, *prev; + + public: + explicit DebugModeOSRVolatileJitFrameIterator(JSContext *cx) + : JitFrameIterator(cx) + { + stack = &cx->liveVolatileJitFrameIterators_; + prev = *stack; + *stack = this; + } + + ~DebugModeOSRVolatileJitFrameIterator() { + MOZ_ASSERT(*stack == this); + *stack = prev; + } + + static void forwardLiveIterators(JSContext *cx, uint8_t *oldAddr, uint8_t *newAddr); +}; + // // Auxiliary info to help the DebugModeOSRHandler fix up state. // diff --git a/js/src/jit/IonFrames.cpp b/js/src/jit/IonFrames.cpp index 25736d246362..d28b082f25d7 100644 --- a/js/src/jit/IonFrames.cpp +++ b/js/src/jit/IonFrames.cpp @@ -708,7 +708,13 @@ HandleException(ResumeFromException *rfe) if (cx->runtime()->jitRuntime()->hasIonReturnOverride()) cx->runtime()->jitRuntime()->takeIonReturnOverride(); - JitFrameIterator iter(cx); + // The Debugger onExceptionUnwind hook (reachable via + // HandleExceptionBaseline below) may cause on-stack recompilation of + // baseline scripts, which may patch return addresses on the stack. Since + // JitFrameIterators cache the previous frame's return address when + // iterating, we need a variant here that is automatically updated should + // on-stack recompilation occur. + DebugModeOSRVolatileJitFrameIterator iter(cx); while (!iter.isEntry()) { bool overrecursed = false; if (iter.isIonJS()) { diff --git a/js/src/jscntxt.cpp b/js/src/jscntxt.cpp index 412ae616d270..17fc393628f4 100644 --- a/js/src/jscntxt.cpp +++ b/js/src/jscntxt.cpp @@ -1011,6 +1011,7 @@ JSContext::JSContext(JSRuntime *rt) unwrappedException_(UndefinedValue()), options_(), propagatingForcedReturn_(false), + liveVolatileJitFrameIterators_(nullptr), reportGranularity(JS_DEFAULT_JITREPORT_GRANULARITY), resolvingList(nullptr), generatingError(false), diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index 1776d50ec9c8..a55251e45686 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -35,6 +35,7 @@ namespace js { namespace jit { class IonContext; class CompileCompartment; +class DebugModeOSRVolatileJitFrameIterator; } struct CallsiteCloneKey { @@ -421,6 +422,7 @@ struct JSContext : public js::ExclusiveContext, friend class js::ExclusiveContext; friend class JS::AutoSaveExceptionState; + friend class js::jit::DebugModeOSRVolatileJitFrameIterator; private: /* Exception state -- the exception member is a GC root by definition. */ @@ -434,6 +436,10 @@ struct JSContext : public js::ExclusiveContext, // debug mode. bool propagatingForcedReturn_; + // A stack of live iterators that need to be updated in case of debug mode + // OSR. + js::jit::DebugModeOSRVolatileJitFrameIterator *liveVolatileJitFrameIterators_; + public: int32_t reportGranularity; /* see vm/Probes.h */