haikuwebkit/JSTests/stress/escape-object-in-diamond-th...

41 lines
1.1 KiB
JavaScript
Raw Permalink Normal View History

The liveness pruning done by ObjectAllocationSinkingPhase ignores the possibility of an object's bytecode liveness being longer than its DFG liveness https://bugs.webkit.org/show_bug.cgi?id=144945 Reviewed by Michael Saboff. We were making the mistake of using DFG liveness for object allocation sinking decisions. This is wrong. In fact we almost never want to use DFG liveness directly. The only place where that makes sense is pruning in DFG AI. So, I created a CombinedLiveness class that combines the DFG liveness with bytecode liveness. In the process of doing this, I realized that the DFGForAllKills definition of combined liveness at block tail was not strictly right; it was using the bytecode liveness at the block terminal instead of the union of the bytecode live-at-heads of successor blocks. So, I changed DFGForAllKills to work in terms of CombinedLiveness. This allows me to unskip the test I added in r184260. I also added a new test that tries to trigger this bug more directly. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.xcodeproj/project.pbxproj: * dfg/DFGArgumentsEliminationPhase.cpp: * dfg/DFGCombinedLiveness.cpp: Added. (JSC::DFG::liveNodesAtHead): (JSC::DFG::CombinedLiveness::CombinedLiveness): * dfg/DFGCombinedLiveness.h: Added. (JSC::DFG::CombinedLiveness::CombinedLiveness): * dfg/DFGForAllKills.h: (JSC::DFG::forAllKillsInBlock): (JSC::DFG::forAllLiveNodesAtTail): Deleted. * dfg/DFGObjectAllocationSinkingPhase.cpp: (JSC::DFG::ObjectAllocationSinkingPhase::performSinking): (JSC::DFG::ObjectAllocationSinkingPhase::determineMaterializationPoints): (JSC::DFG::ObjectAllocationSinkingPhase::placeMaterializationPoints): (JSC::DFG::ObjectAllocationSinkingPhase::promoteSunkenFields): * tests/stress/escape-object-in-diamond-then-exit.js: Added. * tests/stress/sink-object-past-invalid-check-sneaky.js: Canonical link: https://commits.webkit.org/163019@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@184311 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-05-13 22:14:25 +00:00
var global = null;
function foo(p, q) {
var o = {f:42};
if (p)
global = o;
var tmp = q + 1;
return o.f + tmp;
}
noInline(foo);
var lastObject = null;
function validateEscape(when) {
if (global === lastObject)
throw "Error: bad value in global " + when + ", identical to lastObject.";
if (global === null || !(typeof global == "object"))
throw "Error: bad value in global " + when + ": it's not an object.";
if (global.f != 42)
throw "Error: bad value in global " + when + ": f isn't 42, it's: " + global.f;
lastObject = global;
global = null;
}
for (var i = 0; i < 10000; ++i) {
var escape = !!(i & 1);
var result = foo(escape, 42);
if (result != 42 + 42 + 1)
throw "Error: bad result: " + result;
if (escape)
validateEscape("in loop");
else if (global !== null)
throw "Error: bad value in global: " + global;
}
var result = foo(true, 2147483647);
if (result != 42 + 2147483647 + 1)
throw "Error: bad result at end: " + result;
validateEscape("at end");