fourthTier: DFG CFA should know when it hits a contradiction
https://bugs.webkit.org/show_bug.cgi?id=117272
Reviewed by Oliver Hunt.
This makes the DFG CFA immediately detect when it hit a contradiction. Previously
we might not know this: for example if we did an int32 type check on a known string;
the code would definitely always exit but the CFA would think that we wouldn't have
even though it would have computed a BOTTOM (i.e. contradictory) value for that
variable.
This requires two other changes:
- CFA must report contradictions as if they are frequent exit sites, since
contradictory speculations will subsequently get replaced with ForceOSRExit.
ForceOSRExit cannot itself report profiling data back to the DFG::ExitProfile. So,
we do this on behalf of the speculation, eagerly, within the CFA. This also has
the effect of speeding convergence somewhat. We may want to revisit this later;
for example we might want to instead have the notion of a ForceOSRExit that knows
the set of speculations that got folded into it.
- This revealed a bug where the CFA was modeling CheckStructure on a node that had
a known singleton m_futurePossibleStructure set somewhat differently than the
constant folder. If the CheckStructure was checking a structure set with two or
more structures in it, it would not filter the abstract value. But the constant
folder would turn this into a watchpoint on the singleton structure, thereby
filtering the value. This discrepancy meant that we wouldn't realize the
contradiction until the backend, and the AbstractState::bail() method asserts that
we always realize contradictions in the constant folder.
(JSC::CodeBlock::addFrequentExitSite):
(JSC::CodeBlock::hasExitSite):
(CodeBlock):
- bytecode/DFGExitProfile.cpp:
(JSC::DFG::ExitProfile::add):
(JSC::DFG::ExitProfile::hasExitSite):
(JSC::DFG::QueryableExitProfile::QueryableExitProfile):
(JSC::DFG::QueryableExitProfile::~QueryableExitProfile):
(DFG):
(JSC::DFG::QueryableExitProfile::initialize):
- bytecode/DFGExitProfile.h:
(JSC::DFG::FrequentExitSite::FrequentExitSite):
(ExitProfile):
(JSC::DFG::ExitProfile::hasExitSite):
(QueryableExitProfile):
(JSC::exitKindToString):
- dfg/DFGAbstractState.cpp:
(JSC::DFG::AbstractState::AbstractState):
(JSC::DFG::AbstractState::beginBasicBlock):
(JSC::DFG::AbstractState::reset):
(JSC::DFG::AbstractState::startExecuting):
(JSC::DFG::AbstractState::executeEffects):
(JSC::DFG::AbstractState::execute):
(JSC::DFG::AbstractState::filter):
(DFG):
(JSC::DFG::AbstractState::filterArrayModes):
(JSC::DFG::AbstractState::filterByValue):
(JSC::DFG::AbstractState::bail):
(AbstractState):
(JSC::DFG::AbstractState::filter):
(JSC::DFG::AbstractState::filterArrayModes):
(JSC::DFG::AbstractState::filterByValue):
(JSC::DFG::AbstractState::filterByType):
- dfg/DFGAbstractValue.cpp:
(JSC::DFG::AbstractValue::filter):
(JSC::DFG::AbstractValue::filterArrayModes):
(DFG):
(JSC::DFG::AbstractValue::filterByValue):
(JSC::DFG::AbstractValue::normalizeClarity):
(AbstractValue):
- dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
(JSC::DFG::CFAPhase::performBlockCFA):
(JSC::DFG::debugFail):
(JSC::DFG::capabilityLevel):
- dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::foldConstants):
(ConstantFoldingPhase):
(JSC::DFG::ConstantFoldingPhase::paintUnreachableCode):
- dfg/DFGFiltrationResult.h: Added.
(DFG):
(JSC::DFG::FixupPhase::fixupNode):
(DFG):
(JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSiteSlow):
(JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSite):
- dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
- dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::backwardTypeCheck):
(JSC::DFG::SpeculativeJIT::bail):
(DFG):
(JSC::DFG::SpeculativeJIT::compile):
(JSC::DFG::SpeculativeJIT::compileToStringOnCell):
(JSC::DFG::SpeculativeJIT::speculateStringObject):
(JSC::DFG::SpeculativeJIT::speculateStringOrStringObject):
(SpeculativeJIT):
- dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
(JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
(JSC::DFG::SpeculativeJIT::fillSpeculateCell):
(JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
(JSC::DFG::SpeculativeJIT::compile):
- dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
(JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
(JSC::DFG::SpeculativeJIT::fillSpeculateCell):
(JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
(JSC::DFG::SpeculativeJIT::compile):
(JSC::FTL::canCompile):
- ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::appendTypeCheck):