Bug 1428453 - Baldr: remove WasmFrameIter::debugTrapCallsite() (r=yury)
authorLuke Wagner <luke@mozilla.com>
Mon, 08 Jan 2018 17:53:21 -0600
changeset 450088 cf36ca9dd01399d2f6af52052897263bca1c4c6e
parent 450087 e5e24467641e6d918b069d09771a3e4d96a970ea
child 450089 e7e9f7e84f6ba1a4c35295415b8f2bfe30982a8f
push id8527
push userCallek@gmail.com
push dateThu, 11 Jan 2018 21:05:50 +0000
treeherdermozilla-beta@95342d212a7a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersyury
bugs1428453
milestone59.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1428453 - Baldr: remove WasmFrameIter::debugTrapCallsite() (r=yury) MozReview-Commit-ID: AHjWPINanvF
js/src/wasm/WasmBuiltins.cpp
js/src/wasm/WasmFrameIter.cpp
js/src/wasm/WasmFrameIter.h
js/src/wasm/WasmTypes.cpp
js/src/wasm/WasmTypes.h
--- a/js/src/wasm/WasmBuiltins.cpp
+++ b/js/src/wasm/WasmBuiltins.cpp
@@ -91,50 +91,55 @@ WasmHandleExecutionInterrupt()
     activation->finishWasmInterrupt();
     return resumePC;
 }
 
 static bool
 WasmHandleDebugTrap()
 {
     JitActivation* activation = CallingActivation();
-    MOZ_ASSERT(activation);
     JSContext* cx = activation->cx();
+    Frame* fp = activation->wasmExitFP();
+    Instance* instance = fp->tls->instance;
+    const Code& code = instance->code();
+    MOZ_ASSERT(code.metadata().debugEnabled);
 
-    WasmFrameIter frame(activation);
-    MOZ_ASSERT(frame.debugEnabled());
-    const CallSite* site = frame.debugTrapCallsite();
+    // The debug trap stub is the innermost frame. It's return address is the
+    // actual trap site.
+    const CallSite* site = code.lookupCallSite(fp->returnAddress);
     MOZ_ASSERT(site);
+
+    // Advance to the actual trapping frame.
+    fp = fp->callerFP;
+    DebugFrame* debugFrame = DebugFrame::from(fp);
+
     if (site->kind() == CallSite::EnterFrame) {
-        if (!frame.instance()->enterFrameTrapsEnabled())
+        if (!instance->enterFrameTrapsEnabled())
             return true;
-        DebugFrame* debugFrame = frame.debugFrame();
         debugFrame->setIsDebuggee();
         debugFrame->observe(cx);
         // TODO call onEnterFrame
         JSTrapStatus status = Debugger::onEnterFrame(cx, debugFrame);
         if (status == JSTRAP_RETURN) {
             // Ignoring forced return (JSTRAP_RETURN) -- changing code execution
             // order is not yet implemented in the wasm baseline.
             // TODO properly handle JSTRAP_RETURN and resume wasm execution.
             JS_ReportErrorASCII(cx, "Unexpected resumption value from onEnterFrame");
             return false;
         }
         return status == JSTRAP_CONTINUE;
     }
     if (site->kind() == CallSite::LeaveFrame) {
-        DebugFrame* debugFrame = frame.debugFrame();
         debugFrame->updateReturnJSValue();
         bool ok = Debugger::onLeaveFrame(cx, debugFrame, nullptr, true);
         debugFrame->leave(cx);
         return ok;
     }
 
-    DebugFrame* debugFrame = frame.debugFrame();
-    DebugState& debug = frame.instance()->debug();
+    DebugState& debug = instance->debug();
     MOZ_ASSERT(debug.hasBreakpointTrapAtOffset(site->lineOrBytecode()));
     if (debug.stepModeEnabled(debugFrame->funcIndex())) {
         RootedValue result(cx, UndefinedValue());
         JSTrapStatus status = Debugger::onSingleStep(cx, &result);
         if (status == JSTRAP_RETURN) {
             // TODO properly handle JSTRAP_RETURN.
             JS_ReportErrorASCII(cx, "Unexpected resumption value from onSingleStep");
             return false;
--- a/js/src/wasm/WasmFrameIter.cpp
+++ b/js/src/wasm/WasmFrameIter.cpp
@@ -211,30 +211,17 @@ WasmFrameIter::debugEnabled() const
     return code_->metadata().debugEnabled &&
            codeRange_->funcIndex() >= code_->metadata(Tier::Debug).funcImports.length();
 }
 
 DebugFrame*
 WasmFrameIter::debugFrame() const
 {
     MOZ_ASSERT(!done());
-    MOZ_ASSERT(debugEnabled());
-    return reinterpret_cast<DebugFrame*>((uint8_t*)fp_ - DebugFrame::offsetOfFrame());
-}
-
-const CallSite*
-WasmFrameIter::debugTrapCallsite() const
-{
-    MOZ_ASSERT(!done());
-    MOZ_ASSERT(callsite_);
-    MOZ_ASSERT(debugEnabled());
-    MOZ_ASSERT(callsite_->kind() == CallSite::EnterFrame ||
-               callsite_->kind() == CallSite::LeaveFrame ||
-               callsite_->kind() == CallSite::Breakpoint);
-    return callsite_;
+    return DebugFrame::from(fp_);
 }
 
 /*****************************************************************************/
 // Prologue/epilogue code generation
 
 // These constants reflect statically-determined offsets in the
 // prologue/epilogue. The offsets are dynamically asserted during code
 // generation.
--- a/js/src/wasm/WasmFrameIter.h
+++ b/js/src/wasm/WasmFrameIter.h
@@ -86,17 +86,16 @@ class WasmFrameIter
     bool mutedErrors() const;
     JSAtom* functionDisplayAtom() const;
     unsigned lineOrBytecode() const;
     const CodeRange* codeRange() const { return codeRange_; }
     Instance* instance() const;
     void** unwoundAddressOfReturnAddress() const;
     bool debugEnabled() const;
     DebugFrame* debugFrame() const;
-    const CallSite* debugTrapCallsite() const;
 };
 
 enum class SymbolicAddress;
 
 // An ExitReason describes the possible reasons for leaving compiled wasm
 // code or the state of not having left compiled wasm code
 // (ExitReason::None). It is either a known reason, or a enumeration to a native
 // function that is used for better display in the profiler.
--- a/js/src/wasm/WasmTypes.cpp
+++ b/js/src/wasm/WasmTypes.cpp
@@ -557,16 +557,25 @@ wasm::ComputeMappedSize(uint32_t maxSize
 
     MOZ_ASSERT(boundsCheckLimit % gc::SystemPageSize() == 0);
     MOZ_ASSERT(GuardSize % gc::SystemPageSize() == 0);
     return boundsCheckLimit + GuardSize;
 }
 
 #endif  // WASM_HUGE_MEMORY
 
+/* static */ DebugFrame*
+DebugFrame::from(Frame* fp)
+{
+    MOZ_ASSERT(fp->tls->instance->code().metadata().debugEnabled);
+    auto* df = reinterpret_cast<DebugFrame*>((uint8_t*)fp - DebugFrame::offsetOfFrame());
+    MOZ_ASSERT(fp->instance() == df->instance());
+    return df;
+}
+
 void
 DebugFrame::alignmentStaticAsserts()
 {
     // VS2017 doesn't consider offsetOfFrame() to be a constexpr, so we have
     // to use offsetof directly. These asserts can't be at class-level
     // because the type is incomplete.
 
     static_assert(WasmStackAlignment >= Alignment,
--- a/js/src/wasm/WasmTypes.h
+++ b/js/src/wasm/WasmTypes.h
@@ -1874,16 +1874,17 @@ class DebugFrame
     uint32_t padding_;  // See alignmentStaticAsserts().
 #endif
 
   private:
     // The Frame goes at the end since the stack grows down.
     Frame frame_;
 
   public:
+    static DebugFrame* from(Frame* fp);
     Frame& frame() { return frame_; }
     uint32_t funcIndex() const { return funcIndex_; }
     Instance* instance() const { return frame_.instance(); }
     GlobalObject* global() const;
     JSObject* environmentChain() const;
     bool getLocal(uint32_t localIndex, MutableHandleValue vp);
 
     // The return value must be written from the unboxed representation in the