haikuwebkit/LayoutTests/js/dfg-osr-entry-hoisted-clobb...

11 lines
292 B
Plaintext
Raw Permalink Normal View History

DFG should hoist structure checks https://bugs.webkit.org/show_bug.cgi?id=92696 Source/JavaScriptCore: Reviewed by Gavin Barraclough. This hoists structure checks in the same way that we would hoist array checks, but with added complexity to cope with the fact that the structure of an object may change. This is handled by performing a side effects analysis over the region in which the respective variable is live. If a structure clobbering side effect may happen then we either hoist the structure checks and fall back on structure transition watchpoints (if the watchpoint set is still valid), or we avoid hoisting altogether. Doing this required teaching the CFA that we may have an expectation that an object has a particular structure even after structure clobbering happens, in the sense that structure proofs that were cobbered can be revived using watchpoints. CFA must know about this so that OSR entry may know about it, since we cannot allow entry to happen if the variable has a clobbered structure proof, will have a watchpoint to revive the proof, and the variable in the baseline JIT has a completely unrelated structure. This is mostly performance neutral. * CMakeLists.txt: * GNUmakefile.list.am: * JavaScriptCore.xcodeproj/project.pbxproj: * Target.pri: * bytecode/ValueRecovery.h: (JSC::ValueRecovery::isSet): (JSC::ValueRecovery::operator!): (ValueRecovery): * dfg/DFGAbstractState.cpp: (JSC::DFG::AbstractState::execute): (JSC::DFG::AbstractState::clobberWorld): (DFG): (JSC::DFG::AbstractState::clobberCapturedVars): * dfg/DFGAbstractState.h: (AbstractState): * dfg/DFGAbstractValue.h: (JSC::DFG::AbstractValue::clear): (JSC::DFG::AbstractValue::isClear): (JSC::DFG::AbstractValue::makeTop): (JSC::DFG::AbstractValue::isTop): (JSC::DFG::AbstractValue::set): (JSC::DFG::AbstractValue::operator==): (JSC::DFG::AbstractValue::merge): (JSC::DFG::AbstractValue::filter): (JSC::DFG::AbstractValue::validate): (JSC::DFG::AbstractValue::validateForEntry): (AbstractValue): (JSC::DFG::AbstractValue::checkConsistency): (JSC::DFG::AbstractValue::dump): * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::setLocal): (JSC::DFG::ByteCodeParser::getArgument): (JSC::DFG::ByteCodeParser::setArgument): (JSC::DFG::ByteCodeParser::parseBlock): (JSC::DFG::ByteCodeParser::fixVariableAccessSpeculations): * dfg/DFGCSEPhase.cpp: (JSC::DFG::CSEPhase::checkStructureLoadElimination): (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination): (JSC::DFG::CSEPhase::putStructureStoreElimination): (JSC::DFG::CSEPhase::getLocalLoadElimination): (JSC::DFG::CSEPhase::performNodeCSE): * dfg/DFGDriver.cpp: (JSC::DFG::compile): * dfg/DFGGraph.cpp: (JSC::DFG::Graph::dump): * dfg/DFGGraph.h: (JSC::DFG::Graph::vote): (Graph): * dfg/DFGNode.h: (JSC::DFG::Node::convertToStructureTransitionWatchpoint): (Node): (JSC::DFG::Node::hasStructureSet): * dfg/DFGNodeType.h: (DFG): * dfg/DFGOSREntry.cpp: (JSC::DFG::prepareOSREntry): * dfg/DFGPredictionPropagationPhase.cpp: (JSC::DFG::PredictionPropagationPhase::propagate): (PredictionPropagationPhase): (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting): * dfg/DFGSpeculativeJIT.h: (SpeculativeJIT): (JSC::DFG::SpeculativeJIT::forwardSpeculationCheck): (JSC::DFG::SpeculativeJIT::speculationCheckWithConditionalDirection): (JSC::DFG::SpeculativeJIT::terminateSpeculativeExecutionWithConditionalDirection): (JSC::DFG::SpeculateCellOperand::SpeculateCellOperand): (JSC::DFG::SpeculateCellOperand::gpr): (SpeculateCellOperand): * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::fillSpeculateCell): (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::fillSpeculateCell): (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGStructureCheckHoistingPhase.cpp: Added. (DFG): (StructureCheckHoistingPhase): (JSC::DFG::StructureCheckHoistingPhase::StructureCheckHoistingPhase): (JSC::DFG::StructureCheckHoistingPhase::run): (JSC::DFG::StructureCheckHoistingPhase::noticeStructureCheck): (JSC::DFG::StructureCheckHoistingPhase::noticeClobber): (JSC::DFG::StructureCheckHoistingPhase::clobber): (CheckData): (JSC::DFG::StructureCheckHoistingPhase::CheckData::CheckData): (JSC::DFG::performStructureCheckHoisting): * dfg/DFGStructureCheckHoistingPhase.h: Added. (DFG): * dfg/DFGVariableAccessData.h: (VariableAccessData): (JSC::DFG::VariableAccessData::VariableAccessData): (JSC::DFG::VariableAccessData::mergeStructureCheckHoistingFailed): (JSC::DFG::VariableAccessData::structureCheckHoistingFailed): (JSC::DFG::VariableAccessData::clearVotes): (JSC::DFG::VariableAccessData::vote): (JSC::DFG::VariableAccessData::voteRatio): (JSC::DFG::VariableAccessData::shouldUseDoubleFormatAccordingToVote): * runtime/Options.h: (JSC): LayoutTests: Rubber stamped by Gavin Barraclough. Added a new test that covers the following scenarios: - OSR entry if a variable with a hoisted check has an unexpected structure, structures get clobbered, and we're protecting ourselves with structure transition watchpoints. - OSR exit on hoisted structure checks, if the object doesn't have the expected structure, and where the source of the assignment is side-effecting. I combined these into a single test because there is no way to test the latter without testing the former. * fast/js/dfg-osr-entry-hoisted-clobbered-structure-check-expected.txt: Added. * fast/js/dfg-osr-entry-hoisted-clobbered-structure-check.html: Added. * fast/js/jsc-test-list: * fast/js/script-tests/dfg-osr-entry-hoisted-clobbered-structure-check.js: Added. (foo): (bar): (baz): Canonical link: https://commits.webkit.org/110775@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@124404 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2012-08-02 04:32:30 +00:00
Tests that performing an OSR entry into a loop with a hoisted structure check, where the loop may clobber the world, works.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS foo(object, 10000) is 926684
PASS successfullyParsed is true
TEST COMPLETE