DFG should inline InstanceOf ICs
https://bugs.webkit.org/show_bug.cgi?id=185695
Reviewed by Yusuke Suzuki.
Source/JavaScriptCore:
This teaches the DFG how to inline InstanceOf ICs into a MatchStructure node. This can then
be folded to a CheckStructure + JSConstant.
In the process of testing this, I found a bug where LICM was not hoisting things that
depended on ExtraOSREntryLocal because that might return SpecEmpty. I fixed that by teaching
LICM how to materialize CheckNotEmpty on demand whenever HoistingFailed.
This is a ~5% speed-up on boyer.
~2x speed-up on the instanceof-always-hit-one, instanceof-always-hit-two, and
instanceof-sometimes-hit microbenchmarks.
- JavaScriptCore.xcodeproj/project.pbxproj:
- Sources.txt:
- bytecode/GetByIdStatus.cpp:
(JSC::GetByIdStatus::appendVariant):
(JSC::GetByIdStatus::filter):
- bytecode/GetByIdStatus.h:
(JSC::GetByIdStatus::operator bool const):
(JSC::GetByIdStatus::operator! const): Deleted.
- bytecode/GetByIdVariant.h:
(JSC::GetByIdVariant::operator bool const):
(JSC::GetByIdVariant::operator! const): Deleted.
- bytecode/ICStatusUtils.h: Added.
(JSC::appendICStatusVariant):
(JSC::filterICStatusVariants):
- bytecode/InstanceOfStatus.cpp: Added.
(JSC::InstanceOfStatus::appendVariant):
(JSC::InstanceOfStatus::computeFor):
(JSC::InstanceOfStatus::computeForStubInfo):
(JSC::InstanceOfStatus::commonPrototype const):
(JSC::InstanceOfStatus::filter):
- bytecode/InstanceOfStatus.h: Added.
(JSC::InstanceOfStatus::InstanceOfStatus):
(JSC::InstanceOfStatus::state const):
(JSC::InstanceOfStatus::isSet const):
(JSC::InstanceOfStatus::operator bool const):
(JSC::InstanceOfStatus::isSimple const):
(JSC::InstanceOfStatus::takesSlowPath const):
(JSC::InstanceOfStatus::numVariants const):
(JSC::InstanceOfStatus::variants const):
(JSC::InstanceOfStatus::at const):
(JSC::InstanceOfStatus::operator[] const):
- bytecode/InstanceOfVariant.cpp: Added.
(JSC::InstanceOfVariant::InstanceOfVariant):
(JSC::InstanceOfVariant::attemptToMerge):
(JSC::InstanceOfVariant::dump const):
(JSC::InstanceOfVariant::dumpInContext const):
- bytecode/InstanceOfVariant.h: Added.
(JSC::InstanceOfVariant::InstanceOfVariant):
(JSC::InstanceOfVariant::operator bool const):
(JSC::InstanceOfVariant::structureSet const):
(JSC::InstanceOfVariant::structureSet):
(JSC::InstanceOfVariant::conditionSet const):
(JSC::InstanceOfVariant::prototype const):
(JSC::InstanceOfVariant::isHit const):
- bytecode/StructureStubInfo.cpp:
(JSC::StructureStubInfo::StructureStubInfo):
- bytecode/StructureStubInfo.h:
(JSC::StructureStubInfo::considerCaching):
- dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
- dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
(JSC::DFG::clobberize):
- dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::foldConstants):
(JSC::DFG::doesGC):
(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::Graph::dump):
- dfg/DFGGraph.h:
- dfg/DFGLICMPhase.cpp:
(JSC::DFG::LICMPhase::attemptHoist):
(JSC::DFG::Node::remove):
(JSC::DFG::Node::hasMatchStructureData):
(JSC::DFG::Node::matchStructureData):
- dfg/DFGNodeType.h:
- dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
- dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileMatchStructure):
- dfg/DFGSpeculativeJIT.h:
- dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
- dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
(JSC::FTL::canCompile):
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileMatchStructure):
Source/WTF:
I found myself needing a way to represent bottom/false/true/top, so I created it.
- WTF.xcodeproj/project.pbxproj:
- wtf/BooleanLattice.h: Added.
(WTF::lubBooleanLattice):
(WTF::printInternal):