-
fpizlo@apple.com authored
https://bugs.webkit.org/show_bug.cgi?id=67826 Reviewed by Oliver Hunt. This adds the ability to bail out of DFG speculative JIT execution by performing an on-stack replacement (OSR) that results in the control flow going to the equivalent code generated by the old JIT. This required a number of new features, as well as taking advantage of some features that happened to already be present: We already had a policy of storing the bytecode index for which a DFG node was generated inside the DFG::Node class. This was previously called exceptionInfo. It's now renamed to codeOrigin to reflect that it's used for more than just excpetions. OSR uses this to figure out which bytecode index to use to look up the machine code location in the code generated by the old JIT that we should be jumping to. CodeBlock now stores a mapping between bytecode indices and machine code offsets for code generated by the old JIT. This is implemented by CompactJITCodeMap, which tries to compress this data a bit. The OSR compiler decodes this and uses it to find the machine code locations it should be jumping to. We already had a mechanism that emitted SetLocal nodes in the DFG graph that told us the time at which the old JIT would have stored something into its register file, and the DFG::Node that corresponds to the value that it would have stored. These SetLocal's were mostly dead-code- eliminated, but our DCE leaves the nodes intact except for making them have 0 as the ref count. This allows the OSR compiler to construct a mapping between the state as it would have been seen by the old JIT and the state as the DFG JIT sees it. The OSR compiler uses this to generate code that reshapes the call frame so that it is like what the old JIT would expect. Finally, when DFG_OSR is enabled (the default for TIERED_COMPILATION) we no longer emit the non-speculative path. * JavaScriptCore.xcodeproj/project.pbxproj: * bytecode/CodeBlock.h: * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::currentCodeOrigin): (JSC::DFG::ByteCodeParser::addToGraph): * dfg/DFGGPRInfo.h: * dfg/DFGGenerationInfo.h: (JSC::DFG::GenerationInfo::alive): * dfg/DFGGraph.cpp: (JSC::DFG::Graph::dump): * dfg/DFGJITCodeGenerator.cpp: (JSC::DFG::JITCodeGenerator::emitCall): * dfg/DFGJITCodeGenerator.h: (JSC::DFG::JITCodeGenerator::appendCallWithExceptionCheck): * dfg/DFGJITCompiler.cpp: (JSC::DFG::JITCompiler::exitSpeculativeWithOSR): (JSC::DFG::JITCompiler::linkOSRExits): (JSC::DFG::JITCompiler::compileBody): (JSC::DFG::JITCompiler::link): * dfg/DFGJITCompiler.h: (JSC::DFG::CallRecord::CallRecord): (JSC::DFG::JITCompiler::notifyCall): (JSC::DFG::JITCompiler::appendCallWithExceptionCheck): (JSC::DFG::JITCompiler::appendCallWithFastExceptionCheck): (JSC::DFG::JITCompiler::addJSCall): (JSC::DFG::JITCompiler::JSCallRecord::JSCallRecord): * dfg/DFGNode.h: (JSC::DFG::CodeOrigin::CodeOrigin): (JSC::DFG::CodeOrigin::isSet): (JSC::DFG::CodeOrigin::bytecodeIndex): (JSC::DFG::Node::Node): (JSC::DFG::Node::child1Unchecked): * dfg/DFGNonSpeculativeJIT.cpp: (JSC::DFG::NonSpeculativeJIT::compile): * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::ValueSource::dump): (JSC::DFG::ValueRecovery::dump): (JSC::DFG::OSRExit::OSRExit): (JSC::DFG::SpeculativeJIT::compile): (JSC::DFG::SpeculativeJIT::compileMovHint): (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor): * dfg/DFGSpeculativeJIT.h: (JSC::DFG::ValueSource::ValueSource): (JSC::DFG::ValueSource::isSet): (JSC::DFG::ValueSource::nodeIndex): (JSC::DFG::ValueRecovery::ValueRecovery): (JSC::DFG::ValueRecovery::alreadyInRegisterFile): (JSC::DFG::ValueRecovery::inGPR): (JSC::DFG::ValueRecovery::inFPR): (JSC::DFG::ValueRecovery::displacedInRegisterFile): (JSC::DFG::ValueRecovery::constant): (JSC::DFG::ValueRecovery::technique): (JSC::DFG::ValueRecovery::gpr): (JSC::DFG::ValueRecovery::fpr): (JSC::DFG::ValueRecovery::virtualRegister): (JSC::DFG::OSRExit::numberOfRecoveries): (JSC::DFG::OSRExit::valueRecovery): (JSC::DFG::OSRExit::isArgument): (JSC::DFG::OSRExit::argumentForIndex): (JSC::DFG::OSRExit::variableForIndex): (JSC::DFG::OSRExit::operandForIndex): (JSC::DFG::SpeculativeJIT::osrExits): (JSC::DFG::SpeculativeJIT::speculationCheck): (JSC::DFG::SpeculativeJIT::valueSourceForOperand): (JSC::DFG::SpeculativeJIT::setNodeIndexForOperand): (JSC::DFG::SpeculativeJIT::valueSourceReferenceForOperand): (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor): (JSC::DFG::SpeculationCheckIndexIterator::SpeculationCheckIndexIterator): (JSC::DFG::SpeculativeJIT::SpeculativeJIT): * jit/CompactJITCodeMap.h: Added. (JSC::BytecodeAndMachineOffset::BytecodeAndMachineOffset): (JSC::BytecodeAndMachineOffset::getBytecodeIndex): (JSC::BytecodeAndMachineOffset::getMachineCodeOffset): (JSC::CompactJITCodeMap::~CompactJITCodeMap): (JSC::CompactJITCodeMap::decode): (JSC::CompactJITCodeMap::CompactJITCodeMap): (JSC::CompactJITCodeMap::at): (JSC::CompactJITCodeMap::decodeNumber): (JSC::CompactJITCodeMap::Encoder::Encoder): (JSC::CompactJITCodeMap::Encoder::~Encoder): (JSC::CompactJITCodeMap::Encoder::append): (JSC::CompactJITCodeMap::Encoder::finish): (JSC::CompactJITCodeMap::Encoder::appendByte): (JSC::CompactJITCodeMap::Encoder::encodeNumber): (JSC::CompactJITCodeMap::Encoder::ensureCapacityFor): * jit/JIT.cpp: (JSC::JIT::privateCompileMainPass): (JSC::JIT::privateCompile): * jit/JIT.h: * runtime/JSGlobalData.cpp: (JSC::JSGlobalData::JSGlobalData): (JSC::JSGlobalData::~JSGlobalData): * runtime/JSGlobalData.h: (JSC::JSGlobalData::osrScratchBufferForSize): * runtime/JSValue.cpp: (JSC::JSValue::description): git-svn-id: http://svn.webkit.org/repository/webkit/trunk@94996 268f45cc-cd09-0410-ab3c-d52691b4dbfc
7f6c6809