bug-1445973-quick.js (2299B)
1 // |jit-test| --no-baseline 2 // 3 // For background, see the comments for LiveSavedFrameCache in js/src/vm/Stack.h. 4 // 5 // The cache would like to assert that, assuming the cache hasn't been 6 // completely flushed due to a compartment mismatch, if a stack frame's 7 // hasCachedSavedFrame bit is set, then that frame does indeed have an entry in 8 // the cache. 9 // 10 // When LiveSavedFrameCache::find finds an entry whose frame address matches, 11 // but whose pc does not match, it removes that entry from the cache. Usually, a 12 // fresh entry for that frame will be pushed into the cache in short order as we 13 // rebuild the SavedFrame chain, but if the creation of the SavedFrame fails due 14 // to OOM, then we are left with no cache entry for that frame. 15 // 16 // The fix for 1445973 is simply to clear the frame's bit when we remove the 17 // cache entry for a pc mismatch. Previously the code neglected to do this, but 18 // usually got away with it because the cache would be re-populated. OOM fuzzing 19 // interrupted the code at the proper place and revealed the crash, but did so 20 // with a test that took 90s to run. This test runs in a fraction of a second. 21 22 function f() { 23 // Ensure that we will try to allocate fresh SavedFrame objects. 24 clearSavedFrames(); 25 26 // Ensure that all frames have their hasCachedSavedFrame bits set. 27 saveStack(); 28 29 try { 30 // Capture the stack again. The entry for this frame will be removed due to 31 // a pc mismatch. The OOM must occur here, causing the cache not to be 32 // repopulated. 33 saveStack(); 34 } catch (e) { } 35 36 // Capture the stack a third time. This will see that f's frame has its bit 37 // set, even though it has no entry in the cache. 38 saveStack(); 39 } 40 41 // This ensures that there is a frame below f's in the same Activation, so that 42 // the assertion doesn't get skipped because the LiveSavedFrameCache is entirely 43 // empty, to handle caches flushed by compartment mismatches. 44 function g() { f(); } 45 46 // Call all the code once, to ensure that everything has been delazified. When 47 // different calls to g perform different amounts of allocation, oomTest's 48 // simple strategy for choosing which allocation should fail can neglect to hit 49 // the SavedFrame creation. This is also why we disable the baseline compiler in 50 // the test metaline. 51 g(); 52 53 oomTest(g);