blob: 52675b87f46c5ae5dbf8ce5a03ccc50f1321d8fb [file] [log] [blame]
//@ runNoCJITNoAccessInlining
// Regression test for https://bugs.webkit.org/show_bug.cgi?id=148542
//
// In order to manifest, the bug being tested requires all these conditions to be true:
// 1. A put operation must not being optimized by the DFG into a PutByOffset.
// It needs to be a PutById node instead so that it will use the inline cache.
// This is satisfied by using the --useAccessInlining=false option above.
//
// 2. The PutById's execution must go through its transition stub.
//
// 3. In the transition stub, the object being put into must require a reallocation of its
// storage butterfly. This causes the stub to generate code to save some registers.
//
// 4. The transition stub needs to call the slow path for flushing the heap write barrier
// buffer.
//
// 5. The caller of the test must not be DFG compiled. This was not a strictly needed
// condition of the bug, but allowing the caller to compile seems to interfere with
// our method below of achieving condition 3.
//
// With the bug fixed, this test should not crash.
var val = { a: 5, b: 10 }
function test(obj, val, j, x, y, z) {
obj.a = val.a; // PutById after GetById
if (val.b) // GetById to access val in a register again.
val.b++;
}
noInline(test);
function runTest() {
for (var j = 0; j < 50; j++) {
var objs = [];
let numberOfObjects = 200;
for (var k = 0; k < numberOfObjects; k++) {
var obj = { };
// Condition 3.
// Fuzzing the amount of property storage used so that we can get the
// repatch stub generator to resize the object out of line storage, and
// create more register pressure to do that work. This in turn causes it to
// need to preserve registers on the stack.
var numInitialProps = j % 20;
for (var i = 0; i < numInitialProps; i++)
obj["i" + i] = i;
objs[k] = obj;
}
// Condition 4.
// Put all the objects in the GC's oldGen so that we can exercise the write
// barrier when we exercise the PutById.
gc();
for (var k = 0; k < numberOfObjects; k++) {
// Condition 2.
// Eventually, the IC will converge on the slow path. Need to gc()
// periodically to repatch anew.
if (k % 97 == 1 && j % 5 == 1)
gc();
test(objs[k], val, j);
}
}
}
noDFG(runTest); // Condition 5.
runTest();