Title: [215854] trunk
Revision
215854
Author
[email protected]
Date
2017-04-26 20:38:12 -0700 (Wed, 26 Apr 2017)

Log Message

Print Wasm function index in stack trace
https://bugs.webkit.org/show_bug.cgi?id=171349

Reviewed by JF Bastien.

JSTests:

* wasm/function-tests/stack-trace.js: Added.
(import.Builder.from.string_appeared_here.assert):
(let.imp):
* wasm/function-tests/trap-after-cross-instance-call.js:
(wasmFrameCountFromError):
* wasm/function-tests/trap-load-2.js:
(wasmFrameCountFromError):
* wasm/function-tests/trap-load.js:
(wasmFrameCountFromError):

Source/_javascript_Core:

This patch prints a Callee's index in the function index
space in Error.stack.

This will lead to stack traces that have lines of text like:
wasm function index: 4@[wasm code]

We don't ascribe indices to everything in wasm. Specifically, the
Wasm->JS call stub callee does not get a name, and neither does
the JS -> Wasm entrypoint.

* interpreter/Interpreter.cpp:
(JSC::GetStackTraceFunctor::operator()):
* interpreter/StackVisitor.cpp:
(JSC::StackVisitor::readNonInlinedFrame):
(JSC::StackVisitor::Frame::functionName):
* interpreter/StackVisitor.h:
(JSC::StackVisitor::Frame::wasmFunctionIndex):
* runtime/StackFrame.cpp:
(JSC::StackFrame::functionName):
* runtime/StackFrame.h:
(JSC::StackFrame::StackFrame):
(JSC::StackFrame::wasm):
(JSC::StackFrame::hasBytecodeOffset):
(JSC::StackFrame::bytecodeOffset):
* wasm/WasmBBQPlanInlines.h:
(JSC::Wasm::BBQPlan::initializeCallees):
* wasm/WasmCallee.cpp:
(JSC::Wasm::Callee::Callee):
* wasm/WasmCallee.h:
(JSC::Wasm::Callee::create):
(JSC::Wasm::Callee::index):
* wasm/WasmOMGPlan.cpp:
(JSC::Wasm::OMGPlan::work):

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (215853 => 215854)


--- trunk/JSTests/ChangeLog	2017-04-27 02:57:09 UTC (rev 215853)
+++ trunk/JSTests/ChangeLog	2017-04-27 03:38:12 UTC (rev 215854)
@@ -1,5 +1,22 @@
 2017-04-26  Saam Barati  <[email protected]>
 
+        Print Wasm function index in stack trace
+        https://bugs.webkit.org/show_bug.cgi?id=171349
+
+        Reviewed by JF Bastien.
+
+        * wasm/function-tests/stack-trace.js: Added.
+        (import.Builder.from.string_appeared_here.assert):
+        (let.imp):
+        * wasm/function-tests/trap-after-cross-instance-call.js:
+        (wasmFrameCountFromError):
+        * wasm/function-tests/trap-load-2.js:
+        (wasmFrameCountFromError):
+        * wasm/function-tests/trap-load.js:
+        (wasmFrameCountFromError):
+
+2017-04-26  Saam Barati  <[email protected]>
+
         ASSERTION FAILED: inIndex != notFound in JSC::invalidParameterInSourceAppender()
         https://bugs.webkit.org/show_bug.cgi?id=170924
         <rdar://problem/31721052>

Added: trunk/JSTests/wasm/function-tests/stack-trace.js (0 => 215854)


--- trunk/JSTests/wasm/function-tests/stack-trace.js	                        (rev 0)
+++ trunk/JSTests/wasm/function-tests/stack-trace.js	2017-04-27 03:38:12 UTC (rev 215854)
@@ -0,0 +1,57 @@
+import Builder from '../Builder.js'
+
+function assert(b) {
+    if (!b)
+        throw new Error("Bad");
+}
+
+const builder = (new Builder())
+    .Type().End()
+    .Import()
+        .Function("imp", "f", { params: [], ret: "void" })
+    .End()
+    .Function().End()
+    .Export().Function("entry").End()
+    .Code()
+         // idx 1
+        .Function("entry", {params: []})
+            .Call(3)
+        .End()
+        // idx 2
+        .Function({params: []})
+            .Call(4)
+        .End()
+        // idx 3
+        .Function({params: []})
+            .Call(2)
+        .End()
+        // idx 4
+        .Function({params: []})
+            .Call(0)
+        .End()
+    .End();
+
+let stacktrace;
+let imp = () => {
+    stacktrace = (new Error).stack;
+}
+
+
+const bin = builder.WebAssembly().get();
+const module = new WebAssembly.Module(bin);
+let instance = new WebAssembly.Instance(module, {imp: {f: imp}});
+assert(!stacktrace);
+for (let i = 0; i < 10000; ++i) {
+    instance.exports.entry();
+    assert(stacktrace);
+    stacktrace = stacktrace.split("\n");
+    assert(stacktrace[0].indexOf("imp") !== -1); // the arrow function import named "imp".
+    assert(stacktrace[1] === "wasm function@[wasm code]"); // the wasm->js stub
+    assert(stacktrace[2] === "wasm function index: 4@[wasm code]");
+    assert(stacktrace[3] === "wasm function index: 2@[wasm code]");
+    assert(stacktrace[4] === "wasm function index: 3@[wasm code]");
+    assert(stacktrace[5] === "wasm function index: 1@[wasm code]");
+    assert(stacktrace[6] === "wasm function@[wasm code]"); // wasm entry
+
+    stacktrace = null;
+}

Modified: trunk/JSTests/wasm/function-tests/trap-after-cross-instance-call.js (215853 => 215854)


--- trunk/JSTests/wasm/function-tests/trap-after-cross-instance-call.js	2017-04-27 02:57:09 UTC (rev 215853)
+++ trunk/JSTests/wasm/function-tests/trap-after-cross-instance-call.js	2017-04-27 03:38:12 UTC (rev 215854)
@@ -52,7 +52,7 @@
 
 
 function wasmFrameCountFromError(e) {
-    let stackFrames = e.stack.split("\n").filter((s) => s.indexOf("<wasm>@[wasm code]") !== -1);
+    let stackFrames = e.stack.split("\n").filter((s) => s.indexOf("wasm function") !== -1);
     return stackFrames.length;
 }
 

Modified: trunk/JSTests/wasm/function-tests/trap-load-2.js (215853 => 215854)


--- trunk/JSTests/wasm/function-tests/trap-load-2.js	2017-04-27 02:57:09 UTC (rev 215853)
+++ trunk/JSTests/wasm/function-tests/trap-load-2.js	2017-04-27 03:38:12 UTC (rev 215854)
@@ -20,7 +20,7 @@
     .End();
 
 function wasmFrameCountFromError(e) {
-    let stackFrames = e.stack.split("\n").filter((s) => s.indexOf("<wasm>@[wasm code]") !== -1);
+    let stackFrames = e.stack.split("\n").filter((s) => s.indexOf("wasm function") !== -1);
     return stackFrames.length;
 }
 

Modified: trunk/JSTests/wasm/function-tests/trap-load.js (215853 => 215854)


--- trunk/JSTests/wasm/function-tests/trap-load.js	2017-04-27 02:57:09 UTC (rev 215853)
+++ trunk/JSTests/wasm/function-tests/trap-load.js	2017-04-27 03:38:12 UTC (rev 215854)
@@ -24,7 +24,7 @@
 const foo = new WebAssembly.Instance(module, {a: {b: new WebAssembly.Memory({initial: numPages})}}).exports.foo;
 
 function wasmFrameCountFromError(e) {
-    let stackFrames = e.stack.split("\n").filter((s) => s.indexOf("<wasm>@[wasm code]") !== -1);
+    let stackFrames = e.stack.split("\n").filter((s) => s.indexOf("wasm function") !== -1);
     return stackFrames.length;
 }
 

Modified: trunk/Source/_javascript_Core/ChangeLog (215853 => 215854)


--- trunk/Source/_javascript_Core/ChangeLog	2017-04-27 02:57:09 UTC (rev 215853)
+++ trunk/Source/_javascript_Core/ChangeLog	2017-04-27 03:38:12 UTC (rev 215854)
@@ -1,3 +1,44 @@
+2017-04-26  Saam Barati  <[email protected]>
+
+        Print Wasm function index in stack trace
+        https://bugs.webkit.org/show_bug.cgi?id=171349
+
+        Reviewed by JF Bastien.
+
+        This patch prints a Callee's index in the function index
+        space in Error.stack.
+
+        This will lead to stack traces that have lines of text like:
+        wasm function index: 4@[wasm code]
+
+        We don't ascribe indices to everything in wasm. Specifically, the
+        Wasm->JS call stub callee does not get a name, and neither does
+        the JS -> Wasm entrypoint.
+
+        * interpreter/Interpreter.cpp:
+        (JSC::GetStackTraceFunctor::operator()):
+        * interpreter/StackVisitor.cpp:
+        (JSC::StackVisitor::readNonInlinedFrame):
+        (JSC::StackVisitor::Frame::functionName):
+        * interpreter/StackVisitor.h:
+        (JSC::StackVisitor::Frame::wasmFunctionIndex):
+        * runtime/StackFrame.cpp:
+        (JSC::StackFrame::functionName):
+        * runtime/StackFrame.h:
+        (JSC::StackFrame::StackFrame):
+        (JSC::StackFrame::wasm):
+        (JSC::StackFrame::hasBytecodeOffset):
+        (JSC::StackFrame::bytecodeOffset):
+        * wasm/WasmBBQPlanInlines.h:
+        (JSC::Wasm::BBQPlan::initializeCallees):
+        * wasm/WasmCallee.cpp:
+        (JSC::Wasm::Callee::Callee):
+        * wasm/WasmCallee.h:
+        (JSC::Wasm::Callee::create):
+        (JSC::Wasm::Callee::index):
+        * wasm/WasmOMGPlan.cpp:
+        (JSC::Wasm::OMGPlan::work):
+
 2017-04-26  Keith Miller  <[email protected]>
 
         Follow up to r215843

Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (215853 => 215854)


--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp	2017-04-27 02:57:09 UTC (rev 215853)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp	2017-04-27 03:38:12 UTC (rev 215854)
@@ -479,9 +479,10 @@
         }
 
         if (m_remainingCapacityForFrameCapture) {
-            if (visitor->isWasmFrame())
-                m_results.append(StackFrame::wasm());
-            else if (!!visitor->codeBlock() && !visitor->codeBlock()->unlinkedCodeBlock()->isBuiltinFunction()) {
+            if (visitor->isWasmFrame()) {
+                std::optional<unsigned> wasmFunctionIndex = visitor->wasmFunctionIndex();
+                m_results.append(StackFrame::wasm(wasmFunctionIndex ? *wasmFunctionIndex : StackFrame::invalidWasmIndex));
+            } else if (!!visitor->codeBlock() && !visitor->codeBlock()->unlinkedCodeBlock()->isBuiltinFunction()) {
                 m_results.append(
                     StackFrame(m_vm, visitor->callee().asCell(), visitor->codeBlock(), visitor->bytecodeOffset()));
             } else {

Modified: trunk/Source/_javascript_Core/interpreter/StackVisitor.cpp (215853 => 215854)


--- trunk/Source/_javascript_Core/interpreter/StackVisitor.cpp	2017-04-27 02:57:09 UTC (rev 215853)
+++ trunk/Source/_javascript_Core/interpreter/StackVisitor.cpp	2017-04-27 03:38:12 UTC (rev 215854)
@@ -163,6 +163,11 @@
         m_frame.m_isWasmFrame = true;
         m_frame.m_codeBlock = nullptr;
         m_frame.m_bytecodeOffset = 0;
+#if ENABLE(WEBASSEMBLY)
+        CalleeBits bits = callFrame->callee();
+        if (bits.isWasm())
+            m_frame.m_wasmFunctionIndex = bits.asWasmCallee()->index();
+#endif
     } else {
         m_frame.m_codeBlock = callFrame->codeBlock();
         m_frame.m_bytecodeOffset = !m_frame.codeBlock() ? 0
@@ -278,7 +283,10 @@
 
     switch (codeType()) {
     case CodeType::Wasm:
-        traceLine = ASCIILiteral("wasm code");
+        if (m_wasmFunctionIndex)
+            traceLine = makeString("wasm function index: ", String::number(*m_wasmFunctionIndex));
+        else
+            traceLine = ASCIILiteral("wasm function");
         break;
     case CodeType::Eval:
         traceLine = ASCIILiteral("eval code");

Modified: trunk/Source/_javascript_Core/interpreter/StackVisitor.h (215853 => 215854)


--- trunk/Source/_javascript_Core/interpreter/StackVisitor.h	2017-04-27 02:57:09 UTC (rev 215853)
+++ trunk/Source/_javascript_Core/interpreter/StackVisitor.h	2017-04-27 03:38:12 UTC (rev 215854)
@@ -77,6 +77,11 @@
         bool isNativeFrame() const { return !codeBlock() && !isWasmFrame(); }
         bool isInlinedFrame() const { return !!inlineCallFrame(); }
         bool isWasmFrame() const;
+        std::optional<unsigned> const wasmFunctionIndex()
+        {
+            ASSERT(isWasmFrame());
+            return m_wasmFunctionIndex;
+        }
 
         JS_EXPORT_PRIVATE String functionName() const;
         JS_EXPORT_PRIVATE String sourceURL() const;
@@ -116,6 +121,7 @@
         size_t m_index;
         size_t m_argumentCountIncludingThis;
         unsigned m_bytecodeOffset;
+        std::optional<unsigned> m_wasmFunctionIndex;
         bool m_callerIsVMEntryFrame : 1;
         bool m_isWasmFrame : 1;
 

Modified: trunk/Source/_javascript_Core/runtime/StackFrame.cpp (215853 => 215854)


--- trunk/Source/_javascript_Core/runtime/StackFrame.cpp	2017-04-27 02:57:09 UTC (rev 215853)
+++ trunk/Source/_javascript_Core/runtime/StackFrame.cpp	2017-04-27 03:38:12 UTC (rev 215854)
@@ -57,8 +57,11 @@
 
 String StackFrame::functionName(VM& vm) const
 {
-    if (m_isWasmFrame)
-        return ASCIILiteral("<wasm>");
+    if (m_isWasmFrame) {
+        if (m_wasmFunctionIndex == invalidWasmIndex)
+            return ASCIILiteral("wasm function");
+        return makeString("wasm function index: ", String::number(m_wasmFunctionIndex));
+    }
 
     if (m_codeBlock) {
         switch (m_codeBlock->codeType()) {

Modified: trunk/Source/_javascript_Core/runtime/StackFrame.h (215853 => 215854)


--- trunk/Source/_javascript_Core/runtime/StackFrame.h	2017-04-27 02:57:09 UTC (rev 215853)
+++ trunk/Source/_javascript_Core/runtime/StackFrame.h	2017-04-27 03:38:12 UTC (rev 215854)
@@ -39,6 +39,7 @@
 
     StackFrame(VM& vm, JSCell* callee)
         : m_callee(vm, callee)
+        , m_bytecodeOffset(UINT_MAX)
     { }
 
     StackFrame(VM& vm, JSCell* callee, CodeBlock* codeBlock, unsigned bytecodeOffset)
@@ -47,10 +48,12 @@
         , m_bytecodeOffset(bytecodeOffset)
     { }
 
-    static StackFrame wasm()
+    static constexpr unsigned invalidWasmIndex = UINT_MAX;
+    static StackFrame wasm(unsigned index)
     {
         StackFrame result;
         result.m_isWasmFrame = true;
+        result.m_wasmFunctionIndex = index;
         return result;
     }
 
@@ -62,10 +65,10 @@
     String sourceURL() const;
     String toString(VM&) const;
 
-    bool hasBytecodeOffset() const { return m_bytecodeOffset != UINT_MAX; }
+    bool hasBytecodeOffset() const { return m_bytecodeOffset != UINT_MAX && !m_isWasmFrame; }
     unsigned bytecodeOffset()
     {
-        ASSERT(m_bytecodeOffset != UINT_MAX);
+        ASSERT(hasBytecodeOffset());
         return m_bytecodeOffset;
     }
 
@@ -73,7 +76,10 @@
 private:
     Strong<JSCell> m_callee { };
     Strong<CodeBlock> m_codeBlock { };
-    unsigned m_bytecodeOffset { UINT_MAX };
+    union {
+        unsigned m_bytecodeOffset;
+        unsigned m_wasmFunctionIndex;
+    };
     bool m_isWasmFrame { false };
 };
 

Modified: trunk/Source/_javascript_Core/wasm/WasmBBQPlanInlines.h (215853 => 215854)


--- trunk/Source/_javascript_Core/wasm/WasmBBQPlanInlines.h	2017-04-27 02:57:09 UTC (rev 215853)
+++ trunk/Source/_javascript_Core/wasm/WasmBBQPlanInlines.h	2017-04-27 03:38:12 UTC (rev 215854)
@@ -43,7 +43,7 @@
         Ref<Wasm::Callee> jsEntrypointCallee = Wasm::Callee::create(WTFMove(function->jsToWasmEntrypoint));
         MacroAssembler::repatchPointer(function->jsToWasmCalleeMoveLocation, CalleeBits::boxWasm(jsEntrypointCallee.ptr()));
 
-        Ref<Wasm::Callee> wasmEntrypointCallee = Wasm::Callee::create(WTFMove(function->wasmEntrypoint));
+        Ref<Wasm::Callee> wasmEntrypointCallee = Wasm::Callee::create(WTFMove(function->wasmEntrypoint), internalFunctionIndex + m_moduleInformation->importFunctionCount());
         MacroAssembler::repatchPointer(function->wasmCalleeMoveLocation, CalleeBits::boxWasm(wasmEntrypointCallee.ptr()));
 
         callback(internalFunctionIndex, WTFMove(jsEntrypointCallee), WTFMove(wasmEntrypointCallee));

Modified: trunk/Source/_javascript_Core/wasm/WasmCallee.cpp (215853 => 215854)


--- trunk/Source/_javascript_Core/wasm/WasmCallee.cpp	2017-04-27 02:57:09 UTC (rev 215853)
+++ trunk/Source/_javascript_Core/wasm/WasmCallee.cpp	2017-04-27 03:38:12 UTC (rev 215854)
@@ -32,8 +32,9 @@
 
 namespace JSC { namespace Wasm {
 
-Callee::Callee(Entrypoint&& entrypoint)
+Callee::Callee(Entrypoint&& entrypoint, unsigned index)
     : m_entrypoint(WTFMove(entrypoint))
+    , m_index(index)
 {
     registerCode(m_entrypoint.compilation->codeRef().executableMemory()->start(), m_entrypoint.compilation->codeRef().executableMemory()->end());
 }

Modified: trunk/Source/_javascript_Core/wasm/WasmCallee.h (215853 => 215854)


--- trunk/Source/_javascript_Core/wasm/WasmCallee.h	2017-04-27 02:57:09 UTC (rev 215853)
+++ trunk/Source/_javascript_Core/wasm/WasmCallee.h	2017-04-27 03:38:12 UTC (rev 215854)
@@ -38,9 +38,12 @@
     WTF_MAKE_FAST_ALLOCATED;
 public:
 
-    static Ref<Callee> create(Wasm::Entrypoint&& entrypoint)
+    // We use this when we're the JS entrypoint, we don't ascribe an index to those.
+    static constexpr unsigned invalidCalleeIndex = UINT_MAX;
+
+    static Ref<Callee> create(Wasm::Entrypoint&& entrypoint, unsigned index = invalidCalleeIndex)
     {
-        Callee* callee = new Callee(WTFMove(entrypoint));
+        Callee* callee = new Callee(WTFMove(entrypoint), index);
         return adoptRef(*callee);
     }
 
@@ -47,11 +50,18 @@
     void* entrypoint() const { return m_entrypoint.compilation->code().executableAddress(); }
 
     RegisterAtOffsetList* calleeSaveRegisters() { return &m_entrypoint.calleeSaveRegisters; }
+    std::optional<unsigned> index() const
+    {
+        if (m_index == invalidCalleeIndex)
+            return std::nullopt;
+        return m_index;
+    }
 
 private:
-    JS_EXPORT_PRIVATE Callee(Wasm::Entrypoint&&);
+    JS_EXPORT_PRIVATE Callee(Wasm::Entrypoint&&, unsigned index);
 
     Wasm::Entrypoint m_entrypoint;
+    unsigned m_index;
 };
 
 } } // namespace JSC::Wasm

Modified: trunk/Source/_javascript_Core/wasm/WasmOMGPlan.cpp (215853 => 215854)


--- trunk/Source/_javascript_Core/wasm/WasmOMGPlan.cpp	2017-04-27 02:57:09 UTC (rev 215853)
+++ trunk/Source/_javascript_Core/wasm/WasmOMGPlan.cpp	2017-04-27 03:38:12 UTC (rev 215854)
@@ -98,7 +98,7 @@
     void* entrypoint;
     {
         ASSERT(m_codeBlock.ptr() == m_module->codeBlockFor(mode()));
-        Ref<Callee> callee = Callee::create(WTFMove(omgEntrypoint));
+        Ref<Callee> callee = Callee::create(WTFMove(omgEntrypoint), functionIndexSpace);
         MacroAssembler::repatchPointer(parseAndCompileResult.value()->wasmCalleeMoveLocation, CalleeBits::boxWasm(callee.ptr()));
         ASSERT(!m_codeBlock->m_optimizedCallees[m_functionIndex]);
         entrypoint = callee->entrypoint();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to