forked from mirrors/gecko-dev
Bug 1902983 - Don't use bailout data after iterating Wasm frames. a=RyanVM
This is similar to bug 1900523, but the fix there was incomplete because the `JSJitToWasm` frame type is only used when we go through the Wasm JIT entry trampoline. Ion can also call Wasm functions directly and in that case the type will be `FrameType::Exit`. Original Revision: https://phabricator.services.mozilla.com/D214098 Differential Revision: https://phabricator.services.mozilla.com/D214375
This commit is contained in:
parent
aa15db38ef
commit
7638273d1f
3 changed files with 43 additions and 16 deletions
24
js/src/jit-test/tests/ion/bug1902983.js
Normal file
24
js/src/jit-test/tests/ion/bug1902983.js
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
// |jit-test| --fast-warmup; --gc-zeal=21,100; skip-if: !wasmIsSupported()
|
||||||
|
let counter = 0;
|
||||||
|
function g() {
|
||||||
|
counter++;
|
||||||
|
const y = BigInt.asIntN(counter, -883678545n);
|
||||||
|
const z = y >> y;
|
||||||
|
BigInt.asUintN(2 ** counter, 883678545n);
|
||||||
|
try { g(); } catch (e) { }
|
||||||
|
}
|
||||||
|
function f() {
|
||||||
|
for (let i = 0; i < 5; i++) {
|
||||||
|
for (let j = 0; j < 30; j++) { }
|
||||||
|
Promise.allSettled().catch(e => null);
|
||||||
|
counter = 0;
|
||||||
|
g();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const binary = wasmTextToBinary(`(module (import "m" "f" (func $f)) (func (export "test") (call $f)))`);
|
||||||
|
const mod = new WebAssembly.Module(binary);
|
||||||
|
const inst = new WebAssembly.Instance(mod, { m: { f: f } });
|
||||||
|
for (let i = 0; i < 100; i++) { }
|
||||||
|
for (let i = 0; i < 5; i++) {
|
||||||
|
inst.exports.test();
|
||||||
|
}
|
||||||
|
|
@ -26,26 +26,29 @@ using namespace js;
|
||||||
using namespace js::jit;
|
using namespace js::jit;
|
||||||
|
|
||||||
JSJitFrameIter::JSJitFrameIter(const JitActivation* activation)
|
JSJitFrameIter::JSJitFrameIter(const JitActivation* activation)
|
||||||
: JSJitFrameIter(activation, FrameType::Exit, activation->jsExitFP()) {}
|
: current_(activation->jsExitFP()),
|
||||||
|
type_(FrameType::Exit),
|
||||||
JSJitFrameIter::JSJitFrameIter(const JitActivation* activation,
|
|
||||||
FrameType frameType, uint8_t* fp)
|
|
||||||
: current_(fp),
|
|
||||||
type_(frameType),
|
|
||||||
resumePCinCurrentFrame_(nullptr),
|
|
||||||
cachedSafepointIndex_(nullptr),
|
|
||||||
activation_(activation) {
|
activation_(activation) {
|
||||||
// If we're currently performing a bailout, we have to use the activation's
|
// If we're currently performing a bailout, we have to use the activation's
|
||||||
// bailout data when we start iterating over the activation's frames.
|
// bailout data when we start iterating over the activation's frames.
|
||||||
// Note: JSJitToWasm indicates the activation contains both JS and Wasm frames
|
if (activation_->bailoutData()) {
|
||||||
// and we're resuming iteration of the JS frames.
|
|
||||||
MOZ_ASSERT(type_ == FrameType::JSJitToWasm || type_ == FrameType::Exit);
|
|
||||||
if (type_ == FrameType::Exit && activation_->bailoutData()) {
|
|
||||||
current_ = activation_->bailoutData()->fp();
|
current_ = activation_->bailoutData()->fp();
|
||||||
type_ = FrameType::Bailout;
|
type_ = FrameType::Bailout;
|
||||||
} else {
|
|
||||||
MOZ_ASSERT(!TlsContext.get()->inUnsafeCallWithABI);
|
|
||||||
}
|
}
|
||||||
|
MOZ_ASSERT(!TlsContext.get()->inUnsafeCallWithABI);
|
||||||
|
}
|
||||||
|
|
||||||
|
JSJitFrameIter::JSJitFrameIter(const JitActivation* activation,
|
||||||
|
FrameType frameType, uint8_t* fp)
|
||||||
|
: current_(fp), type_(frameType), activation_(activation) {
|
||||||
|
// This constructor is only used when resuming iteration after iterating Wasm
|
||||||
|
// frames in the same JitActivation so ignore activation_->bailoutData().
|
||||||
|
//
|
||||||
|
// Note: FrameType::JSJitToWasm is used for JIT => Wasm calls through the Wasm
|
||||||
|
// JIT entry trampoline. FrameType::Exit is used for direct Ion => Wasm calls.
|
||||||
|
MOZ_ASSERT(fp > activation->jsOrWasmExitFP());
|
||||||
|
MOZ_ASSERT(type_ == FrameType::JSJitToWasm || type_ == FrameType::Exit);
|
||||||
|
MOZ_ASSERT(!TlsContext.get()->inUnsafeCallWithABI);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JSJitFrameIter::checkInvalidation() const {
|
bool JSJitFrameIter::checkInvalidation() const {
|
||||||
|
|
|
||||||
|
|
@ -115,14 +115,14 @@ class JSJitFrameIter {
|
||||||
protected:
|
protected:
|
||||||
uint8_t* current_;
|
uint8_t* current_;
|
||||||
FrameType type_;
|
FrameType type_;
|
||||||
uint8_t* resumePCinCurrentFrame_;
|
uint8_t* resumePCinCurrentFrame_ = nullptr;
|
||||||
|
|
||||||
// Size of the current Baseline frame. Equivalent to
|
// Size of the current Baseline frame. Equivalent to
|
||||||
// BaselineFrame::debugFrameSize_ in debug builds.
|
// BaselineFrame::debugFrameSize_ in debug builds.
|
||||||
mozilla::Maybe<uint32_t> baselineFrameSize_;
|
mozilla::Maybe<uint32_t> baselineFrameSize_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable const SafepointIndex* cachedSafepointIndex_;
|
mutable const SafepointIndex* cachedSafepointIndex_ = nullptr;
|
||||||
const JitActivation* activation_;
|
const JitActivation* activation_;
|
||||||
|
|
||||||
void dumpBaseline() const;
|
void dumpBaseline() const;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue