# HG changeset patch # User Benjamin Bouvier # Date 1518454634 -3600 # Node ID cdb66b98f4bc7f6550dea2056e60715ea311425d # Parent d590eaeb2063c2285eead9cd431e7c66928b137d Bug 1437499: Commonize CalledFromJitExitFrameLayout and use it for wasm too; r=jandem MozReview-Commit-ID: LP2VUYNkQTJ diff --git a/js/src/jit-test/tests/wasm/regress/ion-error-gc-fakeexitframe.js b/js/src/jit-test/tests/wasm/regress/ion-error-gc-fakeexitframe.js new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/wasm/regress/ion-error-gc-fakeexitframe.js @@ -0,0 +1,81 @@ +var lfLogBuffer = ` +//corefuzz-dcd-endofdata +for (var i = 0; gczeal(4,10); g(buffer)) + assertEq(assignParameterGetElement(42), 17); +//corefuzz-dcd-endofdata +//corefuzz-dcd-endofdata +//corefuzz-dcd-endofdata +g = newGlobal(); +g.parent = this +g.eval("Debugger(parent).onExceptionUnwind=(function(){})") +`; +lfLogBuffer = lfLogBuffer.split('\n'); + +gcPreserveCode(); + +var letext =`(module + (type $type0 (func (param i32 i64))) + (type $type1 (func (param i32) (result i64))) + (type $type2 (func (result i32))) + (memory 1) + (export "store" $func0) + (export "load" $func1) + (export "assert_0" $func2) + (func $func0 (param $var0 i32) (param $var1 i64) + get_local $var0 + get_local $var1 + i64.store16 offset=16 + ) + (func $func1 (param $var0 i32) (result i64) + get_local $var0 + i64.load16_s offset=16 + ) + (func $func2 (result i32) + i32.const 65519 + i64.const -32768 + call $func0 + i32.const 1 + ) + (data (i32.const 0) + "\\00\\01\\02\\03\\04\\05\\06\\07\\08\t\n\\0b\\0c\\0d\\0e\\0f" + ) + (data (i32.const 16) + "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff" + ) +)`; + +var binary = wasmTextToBinary(letext); +var module = new WebAssembly.Module(binary); + +var lfCodeBuffer = ""; +while (true) { + var line = lfLogBuffer.shift(); + if (line == null) { + break; + } else if (line == "//corefuzz-dcd-endofdata") { + processCode(lfCodeBuffer); + } else { + lfCodeBuffer += line + "\n"; + } +} + +if (lfCodeBuffer) processCode(lfCodeBuffer); + +function processCode(code) { + evaluate(code); + while (true) { + imports = {} + try { + instance = new WebAssembly.Instance(module, imports); + break; + } catch (exc) {} + } + for (let descriptor of WebAssembly.Module.exports(module)) { + switch (descriptor.kind) { + case "function": + try { + print(instance.exports[descriptor.name]()) + } catch (exc1) {} + } + } +} diff --git a/js/src/jit/JitFrames.cpp b/js/src/jit/JitFrames.cpp --- a/js/src/jit/JitFrames.cpp +++ b/js/src/jit/JitFrames.cpp @@ -874,18 +874,17 @@ TraceThisAndArguments(JSTracer* trc, con if (!CalleeTokenIsFunction(layout->calleeToken())) return; size_t nargs = layout->numActualArgs(); size_t nformals = 0; JSFunction* fun = CalleeTokenToFunction(layout->calleeToken()); if (frame.type() != JitFrame_JSJitToWasm && - !frame.isExitFrameLayout() && - !frame.isExitFrameLayout() && + !frame.isExitFrameLayout() && !fun->nonLazyScript()->mayReadFrameArgsDirectly()) { nformals = fun->nargs(); } size_t newTargetOffset = Max(nargs, fun->nargs()); Value* argv = layout->argv(); @@ -1171,26 +1170,18 @@ TraceJitExitFrame(JSTracer* trc, const J Value* vp = method->vp(); TraceRootRange(trc, len, vp, "ion-dom-args"); } else { TraceRoot(trc, dom->vp(), "ion-dom-args"); } return; } - if (frame.isExitFrameLayout()) { - auto* layout = frame.exitFrame()->as(); - JitFrameLayout* jsLayout = layout->jsFrame(); - jsLayout->replaceCalleeToken(TraceCalleeToken(trc, jsLayout->calleeToken())); - TraceThisAndArguments(trc, frame, jsLayout); - return; - } - - if (frame.isExitFrameLayout()) { - auto* layout = frame.exitFrame()->as(); + if (frame.isExitFrameLayout()) { + auto* layout = frame.exitFrame()->as(); JitFrameLayout* jsLayout = layout->jsFrame(); jsLayout->replaceCalleeToken(TraceCalleeToken(trc, jsLayout->calleeToken())); TraceThisAndArguments(trc, frame, jsLayout); return; } if (frame.isBareExit()) { // Nothing to trace. Fake exit frame pushed for VM functions with diff --git a/js/src/jit/JitFrames.h b/js/src/jit/JitFrames.h --- a/js/src/jit/JitFrames.h +++ b/js/src/jit/JitFrames.h @@ -821,75 +821,69 @@ ExitFrameLayout::as -inline LazyLinkExitFrameLayout* -ExitFrameLayout::as() -{ - MOZ_ASSERT(is()); - uint8_t* sp = reinterpret_cast(this); - sp -= LazyLinkExitFrameLayout::offsetOfExitFrame(); - return reinterpret_cast(sp); -} - -class InterpreterStubExitFrameLayout -{ - protected: // silence clang warning about unused private fields - ExitFooterFrame footer_; - JitFrameLayout exit_; - - public: - static ExitFrameType Type() { return ExitFrameType::InterpreterStub; } - - static inline size_t Size() { - return sizeof(InterpreterStubExitFrameLayout); + return sizeof(CalledFromJitExitFrameLayout); } inline JitFrameLayout* jsFrame() { return &exit_; } static size_t offsetOfExitFrame() { - return offsetof(InterpreterStubExitFrameLayout, exit_); + return offsetof(CalledFromJitExitFrameLayout, exit_); } }; -template <> -inline InterpreterStubExitFrameLayout* -ExitFrameLayout::as() +class LazyLinkExitFrameLayout : public CalledFromJitExitFrameLayout +{ + public: + static ExitFrameType Type() { return ExitFrameType::LazyLink; } +}; + +class InterpreterStubExitFrameLayout : public CalledFromJitExitFrameLayout +{ + public: + static ExitFrameType Type() { return ExitFrameType::InterpreterStub; } +}; + +class WasmExitFrameLayout : CalledFromJitExitFrameLayout { - MOZ_ASSERT(is()); + public: + static ExitFrameType Type() { return ExitFrameType::WasmJitEntry; } +}; + +template<> +inline bool +ExitFrameLayout::is() +{ + return is() || + is() || + is(); +} + +template <> +inline CalledFromJitExitFrameLayout* +ExitFrameLayout::as() +{ + MOZ_ASSERT(is()); uint8_t* sp = reinterpret_cast(this); - sp -= InterpreterStubExitFrameLayout::offsetOfExitFrame(); - return reinterpret_cast(sp); + sp -= CalledFromJitExitFrameLayout::offsetOfExitFrame(); + return reinterpret_cast(sp); } class ICStub; class JitStubFrameLayout : public CommonFrameLayout { // Info on the stack //