DFG JIT does not speculate aggressively enough on GetById
https://bugs.webkit.org/show_bug.cgi?id=68320
Reviewed by Oliver Hunt.
This adds the ability to access properties directly, by offset.
This optimization kicks in when at the time of DFG compilation,
it appears that the given get_by_id is self-cached by the old JIT.
Two new opcodes get introduced: CheckStructure and GetByOffset.
CheckStructure performs a speculation check on the object's
structure, and returns the storage pointer. GetByOffset performs
a direct read of the field from the storage pointer. Both
CheckStructure and GetByOffset can be CSE'd, so that we can
eliminate redundant structure checks, and redundant reads of the
same field.
This is a 4% speed-up on V8, a 2% slow-down on Kraken, and
neutral on SunSpider.
- bytecode/PredictedType.cpp:
(JSC::predictionFromClassInfo):
(JSC::predictionFromStructure):
(JSC::predictionFromCell):
- bytecode/PredictedType.h:
- dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
(JSC::DFG::dataFormatToString):
(JSC::DFG::needDataFormatConversion):
(JSC::DFG::GenerationInfo::initStorage):
(JSC::DFG::GenerationInfo::spill):
(JSC::DFG::GenerationInfo::fillStorage):
(JSC::DFG::Graph::predict):
(JSC::DFG::Graph::getPrediction):
- dfg/DFGJITCodeGenerator.cpp:
(JSC::DFG::JITCodeGenerator::fillInteger):
(JSC::DFG::JITCodeGenerator::fillDouble):
(JSC::DFG::JITCodeGenerator::fillJSValue):
(JSC::DFG::JITCodeGenerator::fillStorage):
(JSC::DFG::GPRTemporary::GPRTemporary):
- dfg/DFGJITCodeGenerator.h:
(JSC::DFG::JITCodeGenerator::silentSpillGPR):
(JSC::DFG::JITCodeGenerator::silentFillGPR):
(JSC::DFG::JITCodeGenerator::spill):
(JSC::DFG::JITCodeGenerator::storageResult):
(JSC::DFG::StorageOperand::StorageOperand):
(JSC::DFG::StorageOperand::~StorageOperand):
(JSC::DFG::StorageOperand::index):
(JSC::DFG::StorageOperand::gpr):
(JSC::DFG::StorageOperand::use):
(JSC::DFG::OpInfo::OpInfo):
(JSC::DFG::Node::Node):
(JSC::DFG::Node::hasPrediction):
(JSC::DFG::Node::hasStructure):
(JSC::DFG::Node::structure):
(JSC::DFG::Node::hasStorageAccessData):
(JSC::DFG::Node::storageAccessDataIndex):
(JSC::DFG::Propagator::propagateNode):
(JSC::DFG::Propagator::globalVarLoadElimination):
(JSC::DFG::Propagator::getMethodLoadElimination):
(JSC::DFG::Propagator::checkStructureLoadElimination):
(JSC::DFG::Propagator::getByOffsetLoadElimination):
(JSC::DFG::Propagator::performNodeCSE):
- dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
(JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
(JSC::DFG::SpeculativeJIT::fillSpeculateCell):
(JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
(JSC::DFG::SpeculativeJIT::compile):
(WTF::safeCast):