summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/saved-stacks/bug-1445973-quick.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/saved-stacks/bug-1445973-quick.js')
-rw-r--r--js/src/jit-test/tests/saved-stacks/bug-1445973-quick.js53
1 files changed, 53 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/saved-stacks/bug-1445973-quick.js b/js/src/jit-test/tests/saved-stacks/bug-1445973-quick.js
new file mode 100644
index 0000000000..e95315f71f
--- /dev/null
+++ b/js/src/jit-test/tests/saved-stacks/bug-1445973-quick.js
@@ -0,0 +1,53 @@
+// |jit-test| --no-baseline; skip-if: !('oomTest' in this)
+//
+// For background, see the comments for LiveSavedFrameCache in js/src/vm/Stack.h.
+//
+// The cache would like to assert that, assuming the cache hasn't been
+// completely flushed due to a compartment mismatch, if a stack frame's
+// hasCachedSavedFrame bit is set, then that frame does indeed have an entry in
+// the cache.
+//
+// When LiveSavedFrameCache::find finds an entry whose frame address matches,
+// but whose pc does not match, it removes that entry from the cache. Usually, a
+// fresh entry for that frame will be pushed into the cache in short order as we
+// rebuild the SavedFrame chain, but if the creation of the SavedFrame fails due
+// to OOM, then we are left with no cache entry for that frame.
+//
+// The fix for 1445973 is simply to clear the frame's bit when we remove the
+// cache entry for a pc mismatch. Previously the code neglected to do this, but
+// usually got away with it because the cache would be re-populated. OOM fuzzing
+// interrupted the code at the proper place and revealed the crash, but did so
+// with a test that took 90s to run. This test runs in a fraction of a second.
+
+function f() {
+ // Ensure that we will try to allocate fresh SavedFrame objects.
+ clearSavedFrames();
+
+ // Ensure that all frames have their hasCachedSavedFrame bits set.
+ saveStack();
+
+ try {
+ // Capture the stack again. The entry for this frame will be removed due to
+ // a pc mismatch. The OOM must occur here, causing the cache not to be
+ // repopulated.
+ saveStack();
+ } catch (e) { }
+
+ // Capture the stack a third time. This will see that f's frame has its bit
+ // set, even though it has no entry in the cache.
+ saveStack();
+}
+
+// This ensures that there is a frame below f's in the same Activation, so that
+// the assertion doesn't get skipped because the LiveSavedFrameCache is entirely
+// empty, to handle caches flushed by compartment mismatches.
+function g() { f(); }
+
+// Call all the code once, to ensure that everything has been delazified. When
+// different calls to g perform different amounts of allocation, oomTest's
+// simple strategy for choosing which allocation should fail can neglect to hit
+// the SavedFrame creation. This is also why we disable the baseline compiler in
+// the test metaline.
+g();
+
+oomTest(g);