| //@ 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(); |