WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
lol it compiles
blah.patch (text/plain), 183.94 KB, created by
Filip Pizlo
on 2013-04-11 18:18:49 PDT
(
hide
)
Description:
lol it compiles
Filename:
MIME Type:
Creator:
Filip Pizlo
Created:
2013-04-11 18:18:49 PDT
Size:
183.94 KB
patch
obsolete
>Index: Source/JavaScriptCore/ChangeLog >=================================================================== >--- Source/JavaScriptCore/ChangeLog (revision 148170) >+++ Source/JavaScriptCore/ChangeLog (working copy) >@@ -1,3 +1,238 @@ >+2013-04-10 Filip Pizlo <fpizlo@apple.com> >+ >+ fourthTier: FTL should have OSR exit >+ https://bugs.webkit.org/show_bug.cgi?id=113623 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Work in progress. >+ >+ * assembler/AbstractMacroAssembler.h: >+ (Address): >+ (JSC::AbstractMacroAssembler::Address::withOffset): >+ * assembler/LinkBuffer.h: >+ (JSC::LinkBuffer::offsetOf): >+ (LinkBuffer): >+ * dfg/DFGAbstractState.cpp: >+ (JSC::DFG::AbstractState::initialize): >+ * dfg/DFGGPRInfo.h: >+ (GPRInfo): >+ * dfg/DFGMinifiedNode.h: >+ (JSC::DFG::belongsInMinifiedGraph): >+ * dfg/DFGNodeType.h: >+ (JSC::DFG::needsOSRBackwardRewiring): >+ (DFG): >+ (JSC::DFG::needsOSRForwardRewiring): >+ * dfg/DFGOSRExit.cpp: >+ (JSC::DFG::OSRExit::OSRExit): >+ (DFG): >+ (JSC::DFG::OSRExit::convertToForward): >+ * dfg/DFGOSRExit.h: >+ (OSRExit): >+ * dfg/DFGOSRExitBase.cpp: Added. >+ (DFG): >+ (JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSiteSlow): >+ (JSC::DFG::OSRExitBase::doSearchForForwardConversion): >+ * dfg/DFGOSRExitBase.h: Added. >+ (DFG): >+ (JSC::DFG::OSRExitBase::OSRExitBase): >+ (OSRExitBase): >+ (JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSite): >+ * dfg/DFGOSRExitCompiler.cpp: >+ * dfg/DFGOSRExitCompilerCommon.cpp: >+ (JSC::DFG::handleExitCounts): >+ (JSC::DFG::reifyInlinedCallFrames): >+ (JSC::DFG::adjustAndJumpToTarget): >+ * dfg/DFGOSRExitCompilerCommon.h: >+ (DFG): >+ * dfg/DFGOSRExitPreparation.cpp: Added. >+ (DFG): >+ (JSC::DFG::prepareCodeOriginForOSRExit): >+ * dfg/DFGOSRExitPreparation.h: Added. >+ (DFG): >+ * dfg/DFGSpeculativeJIT.cpp: >+ (JSC::DFG::SpeculativeJIT::checkArgumentTypes): >+ * dfg/DFGValueSource.h: >+ (JSC::DFG::ValueSource::forSpeculation): >+ * dfg/DFGVariableEventStream.cpp: >+ (JSC::DFG::VariableEventStream::reconstruct): >+ * ftl/FTLAbbreviations.h: >+ (FTL): >+ (JSC::FTL::functionType): >+ (JSC::FTL::typeOf): >+ (JSC::FTL::buildCall): >+ (JSC::FTL::setTailCall): >+ * ftl/FTLCArgumentGetter.cpp: Added. >+ (FTL): >+ (JSC::FTL::CArgumentGetter::loadNextAndBox): >+ * ftl/FTLCArgumentGetter.h: Added. >+ (FTL): >+ (JSC::FTL::isArgumentRegister): >+ (CArgumentGetter): >+ (JSC::FTL::CArgumentGetter::CArgumentGetter): >+ (JSC::FTL::CArgumentGetter::loadNext8): >+ (JSC::FTL::CArgumentGetter::loadNext32): >+ (JSC::FTL::CArgumentGetter::loadNext64): >+ (JSC::FTL::CArgumentGetter::loadNextPtr): >+ (JSC::FTL::CArgumentGetter::loadNextDouble): >+ (JSC::FTL::CArgumentGetter::nextAddress): >+ * ftl/FTLExitArgument.cpp: Added. >+ (FTL): >+ (JSC::FTL::ExitArgument::dump): >+ * ftl/FTLExitArgument.h: Added. >+ (FTL): >+ (ExitArgumentRepresentation): >+ (ExitArgument): >+ (JSC::FTL::ExitArgument::ExitArgument): >+ (JSC::FTL::ExitArgument::operator!): >+ (JSC::FTL::ExitArgument::format): >+ (JSC::FTL::ExitArgument::argument): >+ (JSC::FTL::ExitArgument::withFormat): >+ (JSC::FTL::ExitArgument::representation): >+ * ftl/FTLExitArgumentForOperand.cpp: Added. >+ (FTL): >+ (JSC::FTL::ExitArgumentForOperand::dump): >+ * ftl/FTLExitArgumentForOperand.h: Added. >+ (FTL): >+ (ExitArgumentForOperand): >+ (JSC::FTL::ExitArgumentForOperand::ExitArgumentForOperand): >+ (JSC::FTL::ExitArgumentForOperand::operator!): >+ (JSC::FTL::ExitArgumentForOperand::exitArgument): >+ (JSC::FTL::ExitArgumentForOperand::operand): >+ (JSC::FTL::lesserArgumentIndex): >+ * ftl/FTLExitArgumentList.h: Added. >+ (FTL): >+ * ftl/FTLExitThunkGenerator.cpp: Added. >+ (FTL): >+ (JSC::FTL::ExitThunkGenerator::ExitThunkGenerator): >+ (JSC::FTL::ExitThunkGenerator::~ExitThunkGenerator): >+ (JSC::FTL::ExitThunkGenerator::emitThunk): >+ * ftl/FTLExitThunkGenerator.h: Added. >+ (FTL): >+ (ExitThunkGenerator): >+ * ftl/FTLExitValue.cpp: Added. >+ (FTL): >+ (JSC::FTL::ExitValue::dump): >+ * ftl/FTLExitValue.h: Added. >+ (FTL): >+ (ExitValue): >+ (JSC::FTL::ExitValue::ExitValue): >+ (JSC::FTL::ExitValue::operator!): >+ (JSC::FTL::ExitValue::dead): >+ (JSC::FTL::ExitValue::inJSStack): >+ (JSC::FTL::ExitValue::inJSStackAsInt32): >+ (JSC::FTL::ExitValue::inJSStackAsDouble): >+ (JSC::FTL::ExitValue::constant): >+ (JSC::FTL::ExitValue::exitArgument): >+ (JSC::FTL::ExitValue::kind): >+ (JSC::FTL::ExitValue::isDead): >+ (JSC::FTL::ExitValue::isInJSStackSomehow): >+ (JSC::FTL::ExitValue::isConstant): >+ (JSC::FTL::ExitValue::isArgument): >+ * ftl/FTLFormattedValue.h: >+ (FTL): >+ (JSC::FTL::noValue): >+ (JSC::FTL::int32Value): >+ (JSC::FTL::uInt32Value): >+ (JSC::FTL::booleanValue): >+ (JSC::FTL::jsValueValue): >+ (JSC::FTL::doubleValue): >+ * ftl/FTLJITCode.cpp: >+ (JSC::FTL::JITCode::initializeExitThunks): >+ (FTL): >+ (JSC::FTL::JITCode::exitThunks): >+ * ftl/FTLJITCode.h: >+ (JITCode): >+ * ftl/FTLLowerDFGToLLVM.cpp: >+ (FTL): >+ (JSC::FTL::LowerDFGToLLVM::LowerDFGToLLVM): >+ (JSC::FTL::LowerDFGToLLVM::lower): >+ (JSC::FTL::LowerDFGToLLVM::transferAndCheckArguments): >+ (JSC::FTL::LowerDFGToLLVM::compileBlock): >+ (JSC::FTL::LowerDFGToLLVM::compileNode): >+ (JSC::FTL::LowerDFGToLLVM::compileGetLocal): >+ (JSC::FTL::LowerDFGToLLVM::compileSetLocal): >+ (LowerDFGToLLVM): >+ (JSC::FTL::LowerDFGToLLVM::compileMovHint): >+ (JSC::FTL::LowerDFGToLLVM::compileZombieHint): >+ (JSC::FTL::LowerDFGToLLVM::compileMovHintAndCheck): >+ (JSC::FTL::LowerDFGToLLVM::compileAdd): >+ (JSC::FTL::LowerDFGToLLVM::compileArithSub): >+ (JSC::FTL::LowerDFGToLLVM::compileArithMul): >+ (JSC::FTL::LowerDFGToLLVM::compileArithNegate): >+ (JSC::FTL::LowerDFGToLLVM::compileUInt32ToNumber): >+ (JSC::FTL::LowerDFGToLLVM::compileCheckStructure): >+ (JSC::FTL::LowerDFGToLLVM::compileGetByVal): >+ (JSC::FTL::LowerDFGToLLVM::speculateBackward): >+ (JSC::FTL::LowerDFGToLLVM::speculateForward): >+ (JSC::FTL::LowerDFGToLLVM::speculate): >+ (JSC::FTL::LowerDFGToLLVM::backwardTypeCheck): >+ (JSC::FTL::LowerDFGToLLVM::forwardTypeCheck): >+ (JSC::FTL::LowerDFGToLLVM::typeCheck): >+ (JSC::FTL::LowerDFGToLLVM::appendTypeCheck): >+ (JSC::FTL::LowerDFGToLLVM::lowInt32): >+ (JSC::FTL::LowerDFGToLLVM::lowCell): >+ (JSC::FTL::LowerDFGToLLVM::lowBoolean): >+ (JSC::FTL::LowerDFGToLLVM::speculateObject): >+ (JSC::FTL::LowerDFGToLLVM::isLive): >+ (JSC::FTL::LowerDFGToLLVM::use): >+ (JSC::FTL::LowerDFGToLLVM::initializeOSRExitStateForBlock): >+ (JSC::FTL::LowerDFGToLLVM::appendOSRExit): >+ (JSC::FTL::LowerDFGToLLVM::addExitArgumentForNode): >+ (JSC::FTL::LowerDFGToLLVM::tryToSetConstantExitArgument): >+ (JSC::FTL::LowerDFGToLLVM::addExitArgument): >+ (JSC::FTL::LowerDFGToLLVM::linkOSRExitsAndCompleteInitializationBlock): >+ (JSC::FTL::LowerDFGToLLVM::observeMovHint): >+ * ftl/FTLOSRExit.cpp: Added. >+ (FTL): >+ (JSC::FTL::OSRExit::OSRExit): >+ (JSC::FTL::OSRExit::codeLocationForRepatch): >+ (JSC::FTL::OSRExit::convertToForward): >+ * ftl/FTLOSRExit.h: Added. >+ (FTL): >+ (OSRExit): >+ * ftl/FTLOSRExitCompilationInfo.h: Added. >+ (FTL): >+ (JSC::FTL::OSRExitCompilationInfo::OSRExitCompilationInfo): >+ (OSRExitCompilationInfo): >+ * ftl/FTLOSRExitCompiler.cpp: Added. >+ (FTL): >+ (JSC::FTL::compileStub): >+ (JSC::FTL::compileFTLOSRExit): >+ * ftl/FTLOSRExitCompiler.h: Added. >+ (FTL): >+ * ftl/FTLOutput.h: >+ (JSC::FTL::Output::intToPtr): >+ (JSC::FTL::Output::load): >+ (JSC::FTL::Output::store): >+ (Output): >+ (JSC::FTL::Output::call): >+ (JSC::FTL::Output::convertToTailCall): >+ * ftl/FTLState.h: >+ (State): >+ * ftl/FTLThunks.cpp: Added. >+ (FTL): >+ (JSC::FTL::osrExitGenerationThunkGenerator): >+ * ftl/FTLThunks.h: Added. >+ (JSC): >+ (FTL): >+ * ftl/FTLValueFormat.cpp: Added. >+ (WTF): >+ (WTF::printInternal): >+ * ftl/FTLValueFormat.h: Added. >+ (FTL): >+ (WTF): >+ * ftl/FTLValueSource.cpp: Added. >+ (FTL): >+ (JSC::FTL::ValueSource::dump): >+ * ftl/FTLValueSource.h: Added. >+ (FTL): >+ (ValueSource): >+ (JSC::FTL::ValueSource::ValueSource): >+ (JSC::FTL::ValueSource::kind): >+ (JSC::FTL::ValueSource::operator!): >+ (JSC::FTL::ValueSource::node): >+ > 2013-04-09 Filip Pizlo <fpizlo@apple.com> > > fourthTier: DFG should provide utilities for common OSR exit tasks >Index: Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >=================================================================== >--- Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (revision 148047) >+++ Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (working copy) >@@ -89,6 +89,32 @@ > 0F21C27C14BE727600ADC64B /* ExecutionHarness.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C27A14BE727300ADC64B /* ExecutionHarness.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0F21C27D14BE727A00ADC64B /* CodeSpecializationKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0F21C27F14BEAA8200ADC64B /* BytecodeConventions.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 0F235BD117178E1C00690C7F /* FTLCArgumentGetter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F235BBB17178E1C00690C7F /* FTLCArgumentGetter.cpp */; }; >+ 0F235BD217178E1C00690C7F /* FTLCArgumentGetter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F235BBC17178E1C00690C7F /* FTLCArgumentGetter.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 0F235BD317178E1C00690C7F /* FTLExitArgument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F235BBD17178E1C00690C7F /* FTLExitArgument.cpp */; }; >+ 0F235BD417178E1C00690C7F /* FTLExitArgument.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F235BBE17178E1C00690C7F /* FTLExitArgument.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 0F235BD517178E1C00690C7F /* FTLExitArgumentForOperand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F235BBF17178E1C00690C7F /* FTLExitArgumentForOperand.cpp */; }; >+ 0F235BD617178E1C00690C7F /* FTLExitArgumentForOperand.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F235BC017178E1C00690C7F /* FTLExitArgumentForOperand.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 0F235BD717178E1C00690C7F /* FTLExitArgumentList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F235BC117178E1C00690C7F /* FTLExitArgumentList.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 0F235BD817178E1C00690C7F /* FTLExitThunkGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F235BC217178E1C00690C7F /* FTLExitThunkGenerator.cpp */; }; >+ 0F235BD917178E1C00690C7F /* FTLExitThunkGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F235BC317178E1C00690C7F /* FTLExitThunkGenerator.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 0F235BDA17178E1C00690C7F /* FTLExitValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F235BC417178E1C00690C7F /* FTLExitValue.cpp */; }; >+ 0F235BDB17178E1C00690C7F /* FTLExitValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F235BC517178E1C00690C7F /* FTLExitValue.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 0F235BDC17178E1C00690C7F /* FTLOSRExit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F235BC617178E1C00690C7F /* FTLOSRExit.cpp */; }; >+ 0F235BDD17178E1C00690C7F /* FTLOSRExit.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F235BC717178E1C00690C7F /* FTLOSRExit.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 0F235BDE17178E1C00690C7F /* FTLOSRExitCompilationInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F235BC817178E1C00690C7F /* FTLOSRExitCompilationInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 0F235BDF17178E1C00690C7F /* FTLOSRExitCompiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F235BC917178E1C00690C7F /* FTLOSRExitCompiler.cpp */; }; >+ 0F235BE017178E1C00690C7F /* FTLOSRExitCompiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F235BCA17178E1C00690C7F /* FTLOSRExitCompiler.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 0F235BE117178E1C00690C7F /* FTLThunks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F235BCB17178E1C00690C7F /* FTLThunks.cpp */; }; >+ 0F235BE217178E1C00690C7F /* FTLThunks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F235BCC17178E1C00690C7F /* FTLThunks.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 0F235BE317178E1C00690C7F /* FTLValueFormat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F235BCD17178E1C00690C7F /* FTLValueFormat.cpp */; }; >+ 0F235BE417178E1C00690C7F /* FTLValueFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F235BCE17178E1C00690C7F /* FTLValueFormat.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 0F235BE517178E1C00690C7F /* FTLValueSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F235BCF17178E1C00690C7F /* FTLValueSource.cpp */; }; >+ 0F235BE617178E1C00690C7F /* FTLValueSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F235BD017178E1C00690C7F /* FTLValueSource.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 0F235BEB17178E7300690C7F /* DFGOSRExitBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F235BE717178E7300690C7F /* DFGOSRExitBase.cpp */; }; >+ 0F235BEC17178E7300690C7F /* DFGOSRExitBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F235BE817178E7300690C7F /* DFGOSRExitBase.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 0F235BED17178E7300690C7F /* DFGOSRExitPreparation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F235BE917178E7300690C7F /* DFGOSRExitPreparation.cpp */; }; >+ 0F235BEE17178E7300690C7F /* DFGOSRExitPreparation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F235BEA17178E7300690C7F /* DFGOSRExitPreparation.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0F242DA713F3B1E8007ADD4C /* WeakReferenceHarvester.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F242DA513F3B1BB007ADD4C /* WeakReferenceHarvester.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0F256C361627B0AD007F2783 /* DFGCallArrayAllocatorSlowPathGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F256C341627B0AA007F2783 /* DFGCallArrayAllocatorSlowPathGenerator.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0F2BDC15151C5D4D00CD8910 /* DFGFixupPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2BDC12151C5D4A00CD8910 /* DFGFixupPhase.cpp */; }; >@@ -1022,6 +1048,32 @@ > 0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeSpecializationKind.h; sourceTree = "<group>"; }; > 0F21C27A14BE727300ADC64B /* ExecutionHarness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecutionHarness.h; sourceTree = "<group>"; }; > 0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeConventions.h; sourceTree = "<group>"; }; >+ 0F235BBB17178E1C00690C7F /* FTLCArgumentGetter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLCArgumentGetter.cpp; path = ftl/FTLCArgumentGetter.cpp; sourceTree = "<group>"; }; >+ 0F235BBC17178E1C00690C7F /* FTLCArgumentGetter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLCArgumentGetter.h; path = ftl/FTLCArgumentGetter.h; sourceTree = "<group>"; }; >+ 0F235BBD17178E1C00690C7F /* FTLExitArgument.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLExitArgument.cpp; path = ftl/FTLExitArgument.cpp; sourceTree = "<group>"; }; >+ 0F235BBE17178E1C00690C7F /* FTLExitArgument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLExitArgument.h; path = ftl/FTLExitArgument.h; sourceTree = "<group>"; }; >+ 0F235BBF17178E1C00690C7F /* FTLExitArgumentForOperand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLExitArgumentForOperand.cpp; path = ftl/FTLExitArgumentForOperand.cpp; sourceTree = "<group>"; }; >+ 0F235BC017178E1C00690C7F /* FTLExitArgumentForOperand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLExitArgumentForOperand.h; path = ftl/FTLExitArgumentForOperand.h; sourceTree = "<group>"; }; >+ 0F235BC117178E1C00690C7F /* FTLExitArgumentList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLExitArgumentList.h; path = ftl/FTLExitArgumentList.h; sourceTree = "<group>"; }; >+ 0F235BC217178E1C00690C7F /* FTLExitThunkGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLExitThunkGenerator.cpp; path = ftl/FTLExitThunkGenerator.cpp; sourceTree = "<group>"; }; >+ 0F235BC317178E1C00690C7F /* FTLExitThunkGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLExitThunkGenerator.h; path = ftl/FTLExitThunkGenerator.h; sourceTree = "<group>"; }; >+ 0F235BC417178E1C00690C7F /* FTLExitValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLExitValue.cpp; path = ftl/FTLExitValue.cpp; sourceTree = "<group>"; }; >+ 0F235BC517178E1C00690C7F /* FTLExitValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLExitValue.h; path = ftl/FTLExitValue.h; sourceTree = "<group>"; }; >+ 0F235BC617178E1C00690C7F /* FTLOSRExit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLOSRExit.cpp; path = ftl/FTLOSRExit.cpp; sourceTree = "<group>"; }; >+ 0F235BC717178E1C00690C7F /* FTLOSRExit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLOSRExit.h; path = ftl/FTLOSRExit.h; sourceTree = "<group>"; }; >+ 0F235BC817178E1C00690C7F /* FTLOSRExitCompilationInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLOSRExitCompilationInfo.h; path = ftl/FTLOSRExitCompilationInfo.h; sourceTree = "<group>"; }; >+ 0F235BC917178E1C00690C7F /* FTLOSRExitCompiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLOSRExitCompiler.cpp; path = ftl/FTLOSRExitCompiler.cpp; sourceTree = "<group>"; }; >+ 0F235BCA17178E1C00690C7F /* FTLOSRExitCompiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLOSRExitCompiler.h; path = ftl/FTLOSRExitCompiler.h; sourceTree = "<group>"; }; >+ 0F235BCB17178E1C00690C7F /* FTLThunks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLThunks.cpp; path = ftl/FTLThunks.cpp; sourceTree = "<group>"; }; >+ 0F235BCC17178E1C00690C7F /* FTLThunks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLThunks.h; path = ftl/FTLThunks.h; sourceTree = "<group>"; }; >+ 0F235BCD17178E1C00690C7F /* FTLValueFormat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLValueFormat.cpp; path = ftl/FTLValueFormat.cpp; sourceTree = "<group>"; }; >+ 0F235BCE17178E1C00690C7F /* FTLValueFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLValueFormat.h; path = ftl/FTLValueFormat.h; sourceTree = "<group>"; }; >+ 0F235BCF17178E1C00690C7F /* FTLValueSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLValueSource.cpp; path = ftl/FTLValueSource.cpp; sourceTree = "<group>"; }; >+ 0F235BD017178E1C00690C7F /* FTLValueSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLValueSource.h; path = ftl/FTLValueSource.h; sourceTree = "<group>"; }; >+ 0F235BE717178E7300690C7F /* DFGOSRExitBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOSRExitBase.cpp; path = dfg/DFGOSRExitBase.cpp; sourceTree = "<group>"; }; >+ 0F235BE817178E7300690C7F /* DFGOSRExitBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExitBase.h; path = dfg/DFGOSRExitBase.h; sourceTree = "<group>"; }; >+ 0F235BE917178E7300690C7F /* DFGOSRExitPreparation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOSRExitPreparation.cpp; path = dfg/DFGOSRExitPreparation.cpp; sourceTree = "<group>"; }; >+ 0F235BEA17178E7300690C7F /* DFGOSRExitPreparation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExitPreparation.h; path = dfg/DFGOSRExitPreparation.h; sourceTree = "<group>"; }; > 0F242DA513F3B1BB007ADD4C /* WeakReferenceHarvester.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakReferenceHarvester.h; sourceTree = "<group>"; }; > 0F256C341627B0AA007F2783 /* DFGCallArrayAllocatorSlowPathGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCallArrayAllocatorSlowPathGenerator.h; path = dfg/DFGCallArrayAllocatorSlowPathGenerator.h; sourceTree = "<group>"; }; > 0F2BDC12151C5D4A00CD8910 /* DFGFixupPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGFixupPhase.cpp; path = dfg/DFGFixupPhase.cpp; sourceTree = "<group>"; }; >@@ -2025,17 +2077,28 @@ > 0FEA09FC1705137F00BB722C /* ftl */ = { > isa = PBXGroup; > children = ( >+ 0FEA09FD170513DB00BB722C /* FTLAbbreviations.h */, > 0FEA0A171708B00700BB722C /* FTLAbstractHeap.cpp */, > 0FEA0A181708B00700BB722C /* FTLAbstractHeap.h */, > 0FEA0A191708B00700BB722C /* FTLAbstractHeapRepository.cpp */, > 0FEA0A1A1708B00700BB722C /* FTLAbstractHeapRepository.h */, >- 0FEA09FD170513DB00BB722C /* FTLAbbreviations.h */, > 0FEA09FE170513DB00BB722C /* FTLCapabilities.cpp */, > 0FEA09FF170513DB00BB722C /* FTLCapabilities.h */, >+ 0F235BBB17178E1C00690C7F /* FTLCArgumentGetter.cpp */, >+ 0F235BBC17178E1C00690C7F /* FTLCArgumentGetter.h */, > 0FEA0A251709623B00BB722C /* FTLCommonValues.cpp */, > 0FEA0A211709606900BB722C /* FTLCommonValues.h */, > 0FEA0A00170513DB00BB722C /* FTLCompile.cpp */, > 0FEA0A01170513DB00BB722C /* FTLCompile.h */, >+ 0F235BBD17178E1C00690C7F /* FTLExitArgument.cpp */, >+ 0F235BBE17178E1C00690C7F /* FTLExitArgument.h */, >+ 0F235BBF17178E1C00690C7F /* FTLExitArgumentForOperand.cpp */, >+ 0F235BC017178E1C00690C7F /* FTLExitArgumentForOperand.h */, >+ 0F235BC117178E1C00690C7F /* FTLExitArgumentList.h */, >+ 0F235BC217178E1C00690C7F /* FTLExitThunkGenerator.cpp */, >+ 0F235BC317178E1C00690C7F /* FTLExitThunkGenerator.h */, >+ 0F235BC417178E1C00690C7F /* FTLExitValue.cpp */, >+ 0F235BC517178E1C00690C7F /* FTLExitValue.h */, > 0FEA0A2B170B661900BB722C /* FTLFormattedValue.h */, > 0FEA0A261709623B00BB722C /* FTLIntrinsicRepository.cpp */, > 0FEA0A221709606900BB722C /* FTLIntrinsicRepository.h */, >@@ -2044,11 +2107,22 @@ > 0FEA0A131706363600BB722C /* FTLLLVMHeaders.h */, > 0FEA0A04170513DB00BB722C /* FTLLowerDFGToLLVM.cpp */, > 0FEA0A05170513DB00BB722C /* FTLLowerDFGToLLVM.h */, >+ 0F235BC617178E1C00690C7F /* FTLOSRExit.cpp */, >+ 0F235BC717178E1C00690C7F /* FTLOSRExit.h */, >+ 0F235BC817178E1C00690C7F /* FTLOSRExitCompilationInfo.h */, >+ 0F235BC917178E1C00690C7F /* FTLOSRExitCompiler.cpp */, >+ 0F235BCA17178E1C00690C7F /* FTLOSRExitCompiler.h */, > 0FEA0A291709629600BB722C /* FTLOutput.cpp */, > 0FEA0A06170513DB00BB722C /* FTLOutput.h */, > 0FEA0A151706BB9000BB722C /* FTLState.cpp */, > 0FEA0A07170513DB00BB722C /* FTLState.h */, >+ 0F235BCB17178E1C00690C7F /* FTLThunks.cpp */, >+ 0F235BCC17178E1C00690C7F /* FTLThunks.h */, > 0FEA0A1B1708B00700BB722C /* FTLTypedPointer.h */, >+ 0F235BCD17178E1C00690C7F /* FTLValueFormat.cpp */, >+ 0F235BCE17178E1C00690C7F /* FTLValueFormat.h */, >+ 0F235BCF17178E1C00690C7F /* FTLValueSource.cpp */, >+ 0F235BD017178E1C00690C7F /* FTLValueSource.h */, > ); > name = ftl; > sourceTree = "<group>"; >@@ -2798,6 +2872,8 @@ > 0FD82E53141DAEDE00179C94 /* DFGOSREntry.h */, > 0FC0978E146A6F6300CF2442 /* DFGOSRExit.cpp */, > 0FC097681468A6EF00CF2442 /* DFGOSRExit.h */, >+ 0F235BE717178E7300690C7F /* DFGOSRExitBase.cpp */, >+ 0F235BE817178E7300690C7F /* DFGOSRExitBase.h */, > 65987F2C167FE84B003C2F8D /* DFGOSRExitCompilationInfo.h */, > 0FC0978F146A6F6300CF2442 /* DFGOSRExitCompiler.cpp */, > 0FC0976F14693AEF00CF2442 /* DFGOSRExitCompiler.h */, >@@ -2807,6 +2883,8 @@ > 0F7025A81714B0F800382C0E /* DFGOSRExitCompilerCommon.h */, > 0FEFC9A71681A3B000567F53 /* DFGOSRExitJumpPlaceholder.cpp */, > 0FEFC9A81681A3B000567F53 /* DFGOSRExitJumpPlaceholder.h */, >+ 0F235BE917178E7300690C7F /* DFGOSRExitPreparation.cpp */, >+ 0F235BEA17178E7300690C7F /* DFGOSRExitPreparation.h */, > 0FFFC94F14EF909500C72532 /* DFGPhase.cpp */, > 0FFFC95014EF909500C72532 /* DFGPhase.h */, > 0FBE0F6D16C1DB010082C5E8 /* DFGPredictionInjectionPhase.cpp */, >@@ -3183,6 +3261,7 @@ > 0F620174143FCD330068B77C /* DFGVariableAccessData.h in Headers */, > 0FDDBFB61666EEDA00C55FEF /* DFGVariableAccessDataDump.h in Headers */, > 0F2BDC491522809600CD8910 /* DFGVariableEvent.h in Headers */, >+ 0F235BD217178E1C00690C7F /* FTLCArgumentGetter.h in Headers */, > 0F2BDC4B1522809D00CD8910 /* DFGVariableEventStream.h in Headers */, > 0FEA0A241709606900BB722C /* FTLIntrinsicRepository.h in Headers */, > 0FEA0A32170D40BF00BB722C /* DFGCommonData.h in Headers */, >@@ -3207,6 +3286,7 @@ > BCBE2CAE14E985AA000593AD /* GCAssertions.h in Headers */, > 0F766D3015A8DCE2008F363E /* GCAwareJITStubRoutine.h in Headers */, > C2239D1B16262BDD005AC5FD /* GCThread.h in Headers */, >+ 0F235BE217178E1C00690C7F /* FTLThunks.h in Headers */, > C21122E215DD9AB300790E3A /* GCThreadSharedData.h in Headers */, > 0F9332A014CA7DCD0085F3C6 /* GetByIdStatus.h in Headers */, > 142E3134134FF0A600AFADB5 /* Handle.h in Headers */, >@@ -3237,6 +3317,7 @@ > BC18C4140E16F5CD00B34460 /* JavaScriptCore.h in Headers */, > BC18C4150E16F5CD00B34460 /* JavaScriptCorePrefix.h in Headers */, > 1429D9300ED22D7000B89619 /* JIT.h in Headers */, >+ 0F235BD417178E1C00690C7F /* FTLExitArgument.h in Headers */, > 86CCEFDE0F413F8900FD7F9E /* JITCode.h in Headers */, > 0F0776BF14FF002B00102332 /* JITCompilationEffort.h in Headers */, > 0FAF7EFE165BA91F000C8455 /* JITDisassembler.h in Headers */, >@@ -3251,6 +3332,7 @@ > A76F54A313B28AAB00EF2BCE /* JITWriteBarrier.h in Headers */, > BC18C4160E16F5CD00B34460 /* JSActivation.h in Headers */, > 840480131021A1D9008E7F01 /* JSAPIValueWrapper.h in Headers */, >+ 0F235BE417178E1C00690C7F /* FTLValueFormat.h in Headers */, > BC18C4170E16F5CD00B34460 /* JSArray.h in Headers */, > BC18C4180E16F5CD00B34460 /* JSBase.h in Headers */, > 140D17D70E8AD4A9000CD17D /* JSBasePrivate.h in Headers */, >@@ -3308,9 +3390,11 @@ > C2CF39C216E15A8100DD69BE /* JSAPIWrapperObject.h in Headers */, > A7482B9311671147003B0712 /* JSWeakObjectMapRefPrivate.h in Headers */, > 1442566215EDE98D0066A49B /* JSWithScope.h in Headers */, >+ 0F235BD617178E1C00690C7F /* FTLExitArgumentForOperand.h in Headers */, > 86E3C619167BABEE006D760A /* JSWrapperMap.h in Headers */, > BC18C42E0E16F5CD00B34460 /* JSWrapperObject.h in Headers */, > 0F766D3515AE253B008F363E /* JumpReplacementWatchpoint.h in Headers */, >+ 0F235BEC17178E7300690C7F /* DFGOSRExitBase.h in Headers */, > BCFD8C930EEB2EE700283848 /* JumpTable.h in Headers */, > A72FFD64139985A800E5365A /* KeywordLookup.h in Headers */, > 969A072A0ED1CE6900F1F681 /* Label.h in Headers */, >@@ -3341,6 +3425,7 @@ > 86C36EEA0EE1289D00B3DF59 /* MacroAssembler.h in Headers */, > 86D3B2C610156BDE002865E7 /* MacroAssemblerARM.h in Headers */, > 86ADD1460FDDEA980006EEC2 /* MacroAssemblerARMv7.h in Headers */, >+ 0F235BDE17178E1C00690C7F /* FTLOSRExitCompilationInfo.h in Headers */, > 0F34B14C16D43E0D001CDA5A /* PolymorphicAccessStructureList.h in Headers */, > 863B23E00FC6118900703AA4 /* MacroAssemblerCodeRef.h in Headers */, > 86C568E111A213EE0007F7F0 /* MacroAssemblerMIPS.h in Headers */, >@@ -3381,8 +3466,10 @@ > BC18C4450E16F5CD00B34460 /* ObjectConstructor.h in Headers */, > BC18C4460E16F5CD00B34460 /* ObjectPrototype.h in Headers */, > E124A8F70E555775003091F1 /* OpaqueJSString.h in Headers */, >+ 0F235BD917178E1C00690C7F /* FTLExitThunkGenerator.h in Headers */, > 969A079B0ED1D3AE00F1F681 /* Opcode.h in Headers */, > 0F2BDC2C151FDE9100CD8910 /* Operands.h in Headers */, >+ 0F235BD717178E1C00690C7F /* FTLExitArgumentList.h in Headers */, > BC18C4480E16F5CD00B34460 /* Operations.h in Headers */, > 0FE228ED1436AB2700196C48 /* Options.h in Headers */, > BC18C44B0E16F5CD00B34460 /* Parser.h in Headers */, >@@ -3408,6 +3495,7 @@ > 0FF729C0166AD360000F5BA3 /* ProfilerOriginStack.h in Headers */, > 0FB1058C1675483300F8AB6E /* ProfilerOSRExit.h in Headers */, > 0FB1058E1675483A00F8AB6E /* ProfilerOSRExitSite.h in Headers */, >+ 0F235BE617178E1C00690C7F /* FTLValueSource.h in Headers */, > 0F13912C16771C3D009CCB07 /* ProfilerProfiledBytecodes.h in Headers */, > A7FB61001040C38B0017A286 /* PropertyDescriptor.h in Headers */, > BC95437D0EBA70FD0072B6D3 /* PropertyMapHashTable.h in Headers */, >@@ -3420,6 +3508,7 @@ > 1474C33B16AA2D950062F01D /* PrototypeMap.h in Headers */, > 0F9332A414CA7DD90085F3C6 /* PutByIdStatus.h in Headers */, > 0F0CD4C215F1A6070032F1C0 /* PutDirectIndexMode.h in Headers */, >+ 0F235BDB17178E1C00690C7F /* FTLExitValue.h in Headers */, > 0F9FC8C514E1B60400D52AE0 /* PutKind.h in Headers */, > 147B84630E6DE6B1004775A4 /* PutPropertySlot.h in Headers */, > 0FF60AC216740F8300029779 /* ReduceWhitespace.h in Headers */, >@@ -3445,6 +3534,7 @@ > C2160FE715F7E95E00942DFC /* SlotVisitorInlines.h in Headers */, > 933040040E6A749400786E6A /* SmallStrings.h in Headers */, > BC18C4640E16F5CD00B34460 /* SourceCode.h in Headers */, >+ 0F235BE017178E1C00690C7F /* FTLOSRExitCompiler.h in Headers */, > BC18C4630E16F5CD00B34460 /* SourceProvider.h in Headers */, > E49DC16C12EF294E00184A1F /* SourceProviderCache.h in Headers */, > E49DC16D12EF295300184A1F /* SourceProviderCacheItem.h in Headers */, >@@ -3519,11 +3609,13 @@ > 0FBE0F7716C1DB120082C5E8 /* DFGUnificationPhase.h in Headers */, > 0FD2C92416D01EE900C7803F /* StructureInlines.h in Headers */, > 0F2E892C16D028AD009E4FD2 /* UnusedPointer.h in Headers */, >+ 0F235BDD17178E1C00690C7F /* FTLOSRExit.h in Headers */, > 0F2E892D16D02BAF009E4FD2 /* DFGMinifiedID.h in Headers */, > 0FFB921816D02EB20055A5DB /* DFGAllocator.h in Headers */, > 0FFB921A16D02EC50055A5DB /* DFGBasicBlockInlines.h in Headers */, > 0FFB921B16D02F010055A5DB /* DFGNodeAllocator.h in Headers */, > 0FFB921C16D02F110055A5DB /* DFGOSRExitCompilationInfo.h in Headers */, >+ 0F235BEE17178E7300690C7F /* DFGOSRExitPreparation.h in Headers */, > 0FFB921D16D02F300055A5DB /* DFGSlowPathGenerator.h in Headers */, > 0FFB921E16D02F470055A5DB /* DFGVariadicFunction.h in Headers */, > 0FFB921F16D033050055A5DB /* (null) in Headers */, >@@ -3917,11 +4009,14 @@ > 0F620179143FCD480068B77C /* DFGAbstractState.cpp in Sources */, > 0F16015D156198C900C2587C /* DFGArgumentsSimplificationPhase.cpp in Sources */, > 0F63948415E48118006A597C /* DFGArrayMode.cpp in Sources */, >+ 0F235BD517178E1C00690C7F /* FTLExitArgumentForOperand.cpp in Sources */, > 0FC0976E1468AB5100CF2442 /* DFGAssemblyHelpers.cpp in Sources */, > 86EC9DC41328DF82002B2AD7 /* DFGByteCodeParser.cpp in Sources */, >+ 0F235BD817178E1C00690C7F /* FTLExitThunkGenerator.cpp in Sources */, > 0FD82E2114172CE300179C94 /* DFGCapabilities.cpp in Sources */, > 0FFFC95714EF90A000C72532 /* DFGCFAPhase.cpp in Sources */, > 0F3B3A271544C995003ED0FF /* DFGCFGSimplificationPhase.cpp in Sources */, >+ 0F235BD117178E1C00690C7F /* FTLCArgumentGetter.cpp in Sources */, > 0F2C557014738F3500121E4F /* DFGCodeBlocks.cpp in Sources */, > 0FF0F19D16B72A08005DF95B /* DFGCommon.cpp in Sources */, > 0F3B3A1A153E68F2003ED0FF /* DFGConstantFoldingPhase.cpp in Sources */, >@@ -3933,12 +4028,14 @@ > 0FBC0AE71496C7C400D4FBDD /* DFGExitProfile.cpp in Sources */, > C2CF39C116E15A8100DD69BE /* JSAPIWrapperObject.cpp in Sources */, > 0F2BDC15151C5D4D00CD8910 /* DFGFixupPhase.cpp in Sources */, >+ 0F235BDA17178E1C00690C7F /* FTLExitValue.cpp in Sources */, > 86EC9DC71328DF82002B2AD7 /* DFGGraph.cpp in Sources */, > 0FEA0A271709623B00BB722C /* FTLCommonValues.cpp in Sources */, > 86EC9DCB1328DF82002B2AD7 /* DFGJITCompiler.cpp in Sources */, > 0FF0F19916B729F6005DF95B /* DFGLongLivedState.cpp in Sources */, > 0F2BDC4D1522818600CD8910 /* DFGMinifiedNode.cpp in Sources */, > 0FF0F19C16B72A03005DF95B /* DFGNode.cpp in Sources */, >+ 0F235BED17178E7300690C7F /* DFGOSRExitPreparation.cpp in Sources */, > 0FA581BA150E952C00B9A2D9 /* DFGNodeFlags.cpp in Sources */, > 86EC9DCF1328DF82002B2AD7 /* DFGOperations.cpp in Sources */, > 0FD82E56141DAF0800179C94 /* DFGOSREntry.cpp in Sources */, >@@ -3998,6 +4095,7 @@ > 1429D92F0ED22D7000B89619 /* JIT.cpp in Sources */, > 86A90ED00EE7D51F00AB350D /* JITArithmetic.cpp in Sources */, > A75706DE118A2BCF0057F88F /* JITArithmetic32_64.cpp in Sources */, >+ 0F235BEB17178E7300690C7F /* DFGOSRExitBase.cpp in Sources */, > 86CC85A30EE79B7400288682 /* JITCall.cpp in Sources */, > 146FE51211A710430087AE66 /* JITCall32_64.cpp in Sources */, > 0F8F94441667635400D61971 /* JITCode.cpp in Sources */, >@@ -4016,6 +4114,7 @@ > 140566C4107EC255005DBC8D /* JSAPIValueWrapper.cpp in Sources */, > 147F39D0107EC37600427A48 /* JSArray.cpp in Sources */, > 1421359B0A677F4F00A8195E /* JSBase.cpp in Sources */, >+ 0F235BE517178E1C00690C7F /* FTLValueSource.cpp in Sources */, > 86FA9E91142BBB2E001773B7 /* JSBoundFunction.cpp in Sources */, > 1440F8AF0A508D200005F061 /* JSCallbackConstructor.cpp in Sources */, > 1440F8920A508B100005F061 /* JSCallbackFunction.cpp in Sources */, >@@ -4037,6 +4136,7 @@ > 147F39D4107EC37600427A48 /* JSObject.cpp in Sources */, > 1482B7E40A43076000517CFC /* JSObjectRef.cpp in Sources */, > A7F993600FD7325100A0B2D0 /* JSONObject.cpp in Sources */, >+ 0F235BDF17178E1C00690C7F /* FTLOSRExitCompiler.cpp in Sources */, > 95F6E6950E5B5F970091E860 /* JSProfilerPrivate.cpp in Sources */, > A727FF6B0DA3092200E548D7 /* JSPropertyNameIterator.cpp in Sources */, > 862553D116136DA9009F17D0 /* JSProxy.cpp in Sources */, >@@ -4105,11 +4205,14 @@ > 0F9FC8C314E1B5FE00D52AE0 /* PolymorphicPutByIdList.cpp in Sources */, > 95742F650DD11F5A000917FB /* Profile.cpp in Sources */, > 95CD45760E1C4FDD0085358E /* ProfileGenerator.cpp in Sources */, >+ 0F235BE317178E1C00690C7F /* FTLValueFormat.cpp in Sources */, > 95AB83560DA43C3000BC83F3 /* ProfileNode.cpp in Sources */, > 0FF729AD166AD35C000F5BA3 /* ProfilerBytecode.cpp in Sources */, > 0FF729AE166AD35C000F5BA3 /* ProfilerBytecodes.cpp in Sources */, >+ 0F235BDC17178E1C00690C7F /* FTLOSRExit.cpp in Sources */, > 0F13912916771C33009CCB07 /* ProfilerBytecodeSequence.cpp in Sources */, > 0FF729AF166AD35C000F5BA3 /* ProfilerCompilation.cpp in Sources */, >+ 0F235BE117178E1C00690C7F /* FTLThunks.cpp in Sources */, > 0FF729B0166AD35C000F5BA3 /* ProfilerCompilationKind.cpp in Sources */, > 0FEA0A33170D40BF00BB722C /* DFGJITCode.cpp in Sources */, > 0FF729B1166AD35C000F5BA3 /* ProfilerCompiledBytecode.cpp in Sources */, >@@ -4131,6 +4234,7 @@ > A1712B3B11C7B212007A5315 /* RegExpCache.cpp in Sources */, > 8642C510151C06A90046D4EF /* RegExpCachedResult.cpp in Sources */, > 14280842107EC0930013E7B2 /* RegExpConstructor.cpp in Sources */, >+ 0F235BD317178E1C00690C7F /* FTLExitArgument.cpp in Sources */, > 8642C512151C083D0046D4EF /* RegExpMatchesArray.cpp in Sources */, > 14280843107EC0930013E7B2 /* RegExpObject.cpp in Sources */, > 14280844107EC0930013E7B2 /* RegExpPrototype.cpp in Sources */, >Index: Source/JavaScriptCore/assembler/AbstractMacroAssembler.h >=================================================================== >--- Source/JavaScriptCore/assembler/AbstractMacroAssembler.h (revision 148047) >+++ Source/JavaScriptCore/assembler/AbstractMacroAssembler.h (working copy) >@@ -88,6 +88,11 @@ public: > , offset(offset) > { > } >+ >+ Address withOffset(int32_t additionalOffset) >+ { >+ return Address(base, offset + additionalOffset); >+ } > > RegisterID base; > int32_t offset; >Index: Source/JavaScriptCore/assembler/LinkBuffer.h >=================================================================== >--- Source/JavaScriptCore/assembler/LinkBuffer.h (revision 148047) >+++ Source/JavaScriptCore/assembler/LinkBuffer.h (working copy) >@@ -199,6 +199,11 @@ public: > return applyOffset(label.m_label).m_offset; > } > >+ unsigned offsetOf(PatchableJump jump) >+ { >+ return applyOffset(jump.m_jump.m_label).m_offset; >+ } >+ > // Upon completion of all patching 'FINALIZE_CODE()' should be called once to > // complete generation of the code. Alternatively, call > // finalizeCodeWithoutDisassembly() directly if you have your own way of >Index: Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h >=================================================================== >--- Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h (revision 148047) >+++ Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h (working copy) >@@ -93,6 +93,7 @@ public: > DoubleConditionBits_should_not_interfere_with_X86Assembler_Condition_codes); > > static const RegisterID stackPointerRegister = X86Registers::esp; >+ static const RegisterID framePointerRegister = X86Registers::ebp; > > #if ENABLE(JIT_CONSTANT_BLINDING) > static bool shouldBlindForSpecificArch(uint32_t value) { return value >= 0x00ffffff; } >Index: Source/JavaScriptCore/dfg/DFGAbstractState.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGAbstractState.cpp (revision 148047) >+++ Source/JavaScriptCore/dfg/DFGAbstractState.cpp (working copy) >@@ -95,7 +95,8 @@ void AbstractState::initialize(Graph& gr > continue; > } > >- SpeculatedType prediction = node->variableAccessData()->prediction(); >+ SpeculatedType prediction = >+ node->variableAccessData()->argumentAwarePrediction(); > if (isInt32Speculation(prediction)) > root->valuesAtHead.argument(i).set(SpecInt32); > else if (isBooleanSpeculation(prediction)) >Index: Source/JavaScriptCore/dfg/DFGGPRInfo.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGGPRInfo.h (revision 148047) >+++ Source/JavaScriptCore/dfg/DFGGPRInfo.h (working copy) >@@ -36,7 +36,7 @@ > namespace JSC { namespace DFG { > > typedef MacroAssembler::RegisterID GPRReg; >-#define InvalidGPRReg ((GPRReg)-1) >+#define InvalidGPRReg ((::JSC::DFG::GPRReg)-1) > > #if USE(JSVALUE64) > class JSValueRegs { >@@ -367,7 +367,7 @@ public: > static const GPRReg registerForIndex[numberOfArgumentRegisters] = { argumentGPR0, argumentGPR1, argumentGPR2, argumentGPR3, argumentGPR4, argumentGPR5 }; > return registerForIndex[index]; > } >- >+ > static unsigned toIndex(GPRReg reg) > { > ASSERT(reg != InvalidGPRReg); >Index: Source/JavaScriptCore/dfg/DFGMinifiedNode.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGMinifiedNode.h (revision 148047) >+++ Source/JavaScriptCore/dfg/DFGMinifiedNode.h (working copy) >@@ -51,6 +51,7 @@ inline bool belongsInMinifiedGraph(NodeT > case PhantomArguments: > return true; > default: >+ ASSERT(!needsOSRBackwardRewiring(type) && !needsOSRForwardRewiring(type)); > return false; > } > } >Index: Source/JavaScriptCore/dfg/DFGNodeType.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGNodeType.h (revision 148047) >+++ Source/JavaScriptCore/dfg/DFGNodeType.h (working copy) >@@ -287,6 +287,25 @@ inline NodeFlags defaultFlags(NodeType o > } > } > >+inline bool needsOSRBackwardRewiring(NodeType op) >+{ >+ return op == UInt32ToNumber; >+} >+ >+inline bool needsOSRForwardRewiring(NodeType op) >+{ >+ switch (op) { >+ case Int32ToDouble: >+ case ForwardInt32ToDouble: >+ case ValueToInt32: >+ case UInt32ToNumber: >+ case DoubleAsInt32: >+ return true; >+ default: >+ return false; >+ } >+} >+ > } } // namespace JSC::DFG > > #endif // ENABLE(DFG_JIT) >Index: Source/JavaScriptCore/dfg/DFGOSRExit.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGOSRExit.cpp (revision 148047) >+++ Source/JavaScriptCore/dfg/DFGOSRExit.cpp (working copy) >@@ -36,15 +36,12 @@ > namespace JSC { namespace DFG { > > OSRExit::OSRExit(ExitKind kind, JSValueSource jsValueSource, MethodOfGettingAValueProfile valueProfile, SpeculativeJIT* jit, unsigned streamIndex, unsigned recoveryIndex) >- : m_jsValueSource(jsValueSource) >+ : OSRExitBase(kind, jit->m_codeOriginForOSR) >+ , m_jsValueSource(jsValueSource) > , m_valueProfile(valueProfile) > , m_patchableCodeOffset(0) >- , m_codeOrigin(jit->m_codeOriginForOSR) >- , m_codeOriginForExitProfile(m_codeOrigin) > , m_recoveryIndex(recoveryIndex) > , m_watchpointIndex(std::numeric_limits<unsigned>::max()) >- , m_kind(kind) >- , m_count(0) > , m_streamIndex(streamIndex) > , m_lastSetOperand(jit->m_lastSetOperand) > { >@@ -73,57 +70,15 @@ void OSRExit::correctJump(LinkBuffer& li > m_patchableCodeOffset = linkBuffer.offsetOf(label); > } > >-bool OSRExit::considerAddingAsFrequentExitSiteSlow(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock) >-{ >- if (static_cast<double>(m_count) / dfgCodeBlock->osrExitCounter() <= Options::osrExitProminenceForFrequentExitSite()) >- return false; >- >- FrequentExitSite exitSite; >- >- if (m_kind == ArgumentsEscaped) { >- // Count this one globally. It doesn't matter where in the code block the arguments excaped; >- // the fact that they did is not associated with any particular instruction. >- exitSite = FrequentExitSite(m_kind); >- } else >- exitSite = FrequentExitSite(m_codeOriginForExitProfile.bytecodeIndex, m_kind); >- >- return baselineCodeBlockForOriginAndBaselineCodeBlock(m_codeOriginForExitProfile, profiledCodeBlock)->addFrequentExitSite(exitSite); >-} >- > void OSRExit::convertToForward(BasicBlock* block, Node* currentNode, unsigned nodeIndex, const ValueRecovery& valueRecovery) > { >- // Check that either the current node is a SetLocal, or the preceding node was a >- // SetLocal with the same code origin, or that we've provided a valueRecovery. >- if (!ASSERT_DISABLED >- && !valueRecovery >- && !currentNode->containsMovHint()) { >- Node* setLocal = block->at(nodeIndex - 1); >- ASSERT_UNUSED(setLocal, setLocal->containsMovHint()); >- ASSERT_UNUSED(setLocal, setLocal->codeOrigin == currentNode->codeOrigin); >- } >- >- // Find the first node for the next bytecode instruction. Also track the last mov hint >- // on this node. >- unsigned indexInBlock = nodeIndex + 1; >- Node* node = 0; >- Node* lastMovHint = 0; >- for (;;) { >- if (indexInBlock == block->size()) { >- // This is an inline return. Give up and do a backwards speculation. This is safe >- // because an inline return has its own bytecode index and it's always safe to >- // reexecute that bytecode. >- ASSERT(node->op() == Jump); >- return; >- } >- node = block->at(indexInBlock); >- if (node->containsMovHint() && node->child1() == currentNode) >- lastMovHint = node; >- if (node->codeOrigin != currentNode->codeOrigin) >- break; >- indexInBlock++; >- } >- >+ Node* node; >+ Node* lastMovHint; >+ if (!doSearchForForwardConversion(block, currentNode, nodeIndex, !!valueRecovery, node, lastMovHint)) >+ return; >+ > ASSERT(node->codeOrigin != currentNode->codeOrigin); >+ > m_codeOrigin = node->codeOrigin; > > if (!valueRecovery) >Index: Source/JavaScriptCore/dfg/DFGOSRExit.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGOSRExit.h (revision 148047) >+++ Source/JavaScriptCore/dfg/DFGOSRExit.h (working copy) >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2011 Apple Inc. All rights reserved. >+ * Copyright (C) 2011, 2013 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -34,6 +34,7 @@ > #include "DFGCommon.h" > #include "DFGExitProfile.h" > #include "DFGGPRInfo.h" >+#include "DFGOSRExitBase.h" > #include "DFGValueRecoveryOverride.h" > #include "MacroAssembler.h" > #include "MethodOfGettingAValueProfile.h" >@@ -84,7 +85,7 @@ private: > // > // This structure describes how to exit the speculative path by > // going into baseline code. >-struct OSRExit { >+struct OSRExit : public OSRExitBase { > OSRExit(ExitKind, JSValueSource, MethodOfGettingAValueProfile, SpeculativeJIT*, unsigned streamIndex, unsigned recoveryIndex = UINT_MAX); > > MacroAssemblerCodeRef m_code; >@@ -93,22 +94,10 @@ struct OSRExit { > MethodOfGettingAValueProfile m_valueProfile; > > unsigned m_patchableCodeOffset; >- CodeOrigin m_codeOrigin; >- CodeOrigin m_codeOriginForExitProfile; > > unsigned m_recoveryIndex; > unsigned m_watchpointIndex; > >- ExitKind m_kind; >- uint32_t m_count; >- >- bool considerAddingAsFrequentExitSite(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock) >- { >- if (!m_count || !exitKindIsCountable(m_kind)) >- return false; >- return considerAddingAsFrequentExitSiteSlow(dfgCodeBlock, profiledCodeBlock); >- } >- > void setPatchableCodeOffset(MacroAssembler::PatchableJump); > MacroAssembler::Jump getPatchableCodeOffsetAsJump() const; > CodeLocationJump codeLocationForRepatch(CodeBlock*) const; >@@ -120,9 +109,6 @@ struct OSRExit { > int m_lastSetOperand; > > RefPtr<ValueRecoveryOverride> m_valueRecoveryOverride; >- >-private: >- bool considerAddingAsFrequentExitSiteSlow(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock); > }; > > struct SpeculationFailureDebugInfo { >Index: Source/JavaScriptCore/dfg/DFGOSRExitBase.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGOSRExitBase.cpp (revision 0) >+++ Source/JavaScriptCore/dfg/DFGOSRExitBase.cpp (working copy) >@@ -0,0 +1,97 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "DFGOSRExitBase.h" >+ >+#if ENABLE(DFG_JIT) >+ >+#include "CodeBlock.h" >+#include "DFGBasicBlock.h" >+#include "DFGNode.h" >+#include "Operations.h" >+ >+namespace JSC { namespace DFG { >+ >+bool OSRExitBase::considerAddingAsFrequentExitSiteSlow(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock) >+{ >+ if (static_cast<double>(m_count) / dfgCodeBlock->osrExitCounter() <= Options::osrExitProminenceForFrequentExitSite()) >+ return false; >+ >+ FrequentExitSite exitSite; >+ >+ if (m_kind == ArgumentsEscaped) { >+ // Count this one globally. It doesn't matter where in the code block the arguments excaped; >+ // the fact that they did is not associated with any particular instruction. >+ exitSite = FrequentExitSite(m_kind); >+ } else >+ exitSite = FrequentExitSite(m_codeOriginForExitProfile.bytecodeIndex, m_kind); >+ >+ return baselineCodeBlockForOriginAndBaselineCodeBlock(m_codeOriginForExitProfile, profiledCodeBlock)->addFrequentExitSite(exitSite); >+} >+ >+bool OSRExitBase::doSearchForForwardConversion( >+ BasicBlock* block, Node* currentNode, unsigned nodeIndex, bool hasValueRecovery, >+ Node*& node, Node*& lastMovHint) >+{ >+ // Check that either the current node is a SetLocal, or the preceding node was a >+ // SetLocal with the same code origin, or that we've provided a valueRecovery. >+ if (!ASSERT_DISABLED >+ && !hasValueRecovery >+ && !currentNode->containsMovHint()) { >+ Node* setLocal = block->at(nodeIndex - 1); >+ ASSERT_UNUSED(setLocal, setLocal->containsMovHint()); >+ ASSERT_UNUSED(setLocal, setLocal->codeOrigin == currentNode->codeOrigin); >+ } >+ >+ // Find the first node for the next bytecode instruction. Also track the last mov hint >+ // on this node. >+ unsigned indexInBlock = nodeIndex + 1; >+ node = 0; >+ lastMovHint = 0; >+ for (;;) { >+ if (indexInBlock == block->size()) { >+ // This is an inline return. Give up and do a backwards speculation. This is safe >+ // because an inline return has its own bytecode index and it's always safe to >+ // reexecute that bytecode. >+ ASSERT(node->op() == Jump); >+ return false; >+ } >+ node = block->at(indexInBlock); >+ if (node->containsMovHint() && node->child1() == currentNode) >+ lastMovHint = node; >+ if (node->codeOrigin != currentNode->codeOrigin) >+ break; >+ indexInBlock++; >+ } >+ >+ ASSERT(node->codeOrigin != currentNode->codeOrigin); >+ return true; >+} >+ >+} } // namespace JSC::DFG >+ >+#endif // ENABLE(DFG_JIT) >+ >Index: Source/JavaScriptCore/dfg/DFGOSRExitBase.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGOSRExitBase.h (revision 0) >+++ Source/JavaScriptCore/dfg/DFGOSRExitBase.h (working copy) >@@ -0,0 +1,80 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#ifndef DFGOSRExitBase_h >+#define DFGOSRExitBase_h >+ >+#include <wtf/Platform.h> >+ >+#if ENABLE(DFG_JIT) >+ >+#include "CodeOrigin.h" >+#include "DFGExitProfile.h" >+ >+namespace JSC { namespace DFG { >+ >+struct BasicBlock; >+struct Node; >+ >+// Provides for the OSR exit profiling functionality that is common between the DFG >+// and the FTL. >+ >+struct OSRExitBase { >+ OSRExitBase(ExitKind kind, CodeOrigin origin) >+ : m_kind(kind) >+ , m_count(0) >+ , m_codeOrigin(origin) >+ , m_codeOriginForExitProfile(origin) >+ { >+ } >+ >+ ExitKind m_kind; >+ uint32_t m_count; >+ >+ CodeOrigin m_codeOrigin; >+ CodeOrigin m_codeOriginForExitProfile; >+ >+ bool considerAddingAsFrequentExitSite(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock) >+ { >+ if (!m_count || !exitKindIsCountable(m_kind)) >+ return false; >+ return considerAddingAsFrequentExitSiteSlow(dfgCodeBlock, profiledCodeBlock); >+ } >+ >+ // Returns true if the forward conversion is really needed. >+ bool doSearchForForwardConversion( >+ BasicBlock*, Node* currentNode, unsigned nodeIndex, bool hasValueRecovery, >+ Node*& nextBCNode, Node*& lastMovHint); >+ >+private: >+ bool considerAddingAsFrequentExitSiteSlow(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock); >+}; >+ >+} } // namespace JSC::DFG >+ >+#endif // ENABLE(DFG_JIT) >+ >+#endif // DFGOSRExitBase_h >+ >Index: Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp (revision 148047) >+++ Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp (working copy) >@@ -653,7 +653,7 @@ void OSRExitCompiler::compileExit(const > // 16) Load the result of the last bytecode operation into regT0. > > if (exit.m_lastSetOperand != std::numeric_limits<int>::max()) >- m_jit.load64(AssemblyHelpers::addressFor((VirtualRegister)exit.m_lastSetOperand), GPRInfo::cachedResultRegister); >+ m_jit.load64(AssemblyHelpers::addressFor(exit.m_lastSetOperand), GPRInfo::cachedResultRegister); > > // 17) And finish. > >Index: Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp (revision 148047) >+++ Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp (working copy) >@@ -31,6 +31,7 @@ > #include "CallFrame.h" > #include "DFGCommon.h" > #include "DFGJITCode.h" >+#include "DFGOSRExitPreparation.h" > #include "LinkBuffer.h" > #include "Operations.h" > #include "RepatchBuffer.h" >@@ -54,20 +55,7 @@ void compileOSRExit(ExecState* exec) > uint32_t exitIndex = globalData->osrExitIndex; > OSRExit& exit = codeBlock->getJITCode()->dfg()->osrExit[exitIndex]; > >- // Make sure all code on our inline stack is JIT compiled. This is necessary since >- // we may opt to inline a code block even before it had ever been compiled by the >- // JIT, but our OSR exit infrastructure currently only works if the target of the >- // OSR exit is JIT code. This could be changed since there is nothing particularly >- // hard about doing an OSR exit into the interpreter, but for now this seems to make >- // sense in that if we're OSR exiting from inlined code of a DFG code block, then >- // probably it's a good sign that the thing we're exiting into is hot. Even more >- // interestingly, since the code was inlined, it may never otherwise get JIT >- // compiled since the act of inlining it may ensure that it otherwise never runs. >- for (CodeOrigin codeOrigin = exit.m_codeOrigin; codeOrigin.inlineCallFrame; codeOrigin = codeOrigin.inlineCallFrame->caller) { >- static_cast<FunctionExecutable*>(codeOrigin.inlineCallFrame->executable.get()) >- ->baselineCodeBlockFor(codeOrigin.inlineCallFrame->isCall ? CodeForCall : CodeForConstruct) >- ->jitCompile(exec); >- } >+ prepareCodeOriginForOSRExit(exec, exit.m_codeOrigin); > > // Compute the value recoveries. > Operands<ValueRecovery> operands; >Index: Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp (revision 148047) >+++ Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp (working copy) >@@ -32,7 +32,7 @@ > > namespace JSC { namespace DFG { > >-void handleExitCounts(CCallHelpers& jit, const OSRExit& exit) >+void handleExitCounts(CCallHelpers& jit, const OSRExitBase& exit) > { > jit.add32(AssemblyHelpers::TrustedImm32(1), AssemblyHelpers::AbsoluteAddress(&exit.m_count)); > >@@ -73,7 +73,7 @@ void handleExitCounts(CCallHelpers& jit, > doneAdjusting.link(&jit); > } > >-void reifyInlinedCallFrames(CCallHelpers& jit, const OSRExit& exit) >+void reifyInlinedCallFrames(CCallHelpers& jit, const OSRExitBase& exit) > { > #if USE(JSVALUE64) > ASSERT(jit.baselineCodeBlock()->getJITType() == JITCode::BaselineJIT); >@@ -147,7 +147,7 @@ void reifyInlinedCallFrames(CCallHelpers > #endif // USE(JSVALUE64) // ending the #else part, so directly above is the 32-bit part > } > >-void adjustAndJumpToTarget(CCallHelpers& jit, const OSRExit& exit) >+void adjustAndJumpToTarget(CCallHelpers& jit, const OSRExitBase& exit) > { > if (exit.m_codeOrigin.inlineCallFrame) > jit.addPtr(AssemblyHelpers::TrustedImm32(exit.m_codeOrigin.inlineCallFrame->stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister); >Index: Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h (revision 148047) >+++ Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h (working copy) >@@ -35,9 +35,9 @@ > > namespace JSC { namespace DFG { > >-void handleExitCounts(CCallHelpers&, const OSRExit&); >-void reifyInlinedCallFrames(CCallHelpers&, const OSRExit&); >-void adjustAndJumpToTarget(CCallHelpers&, const OSRExit&); >+void handleExitCounts(CCallHelpers&, const OSRExitBase&); >+void reifyInlinedCallFrames(CCallHelpers&, const OSRExitBase&); >+void adjustAndJumpToTarget(CCallHelpers&, const OSRExitBase&); > > } } // namespace JSC::DFG > >Index: Source/JavaScriptCore/dfg/DFGOSRExitPreparation.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGOSRExitPreparation.cpp (revision 0) >+++ Source/JavaScriptCore/dfg/DFGOSRExitPreparation.cpp (working copy) >@@ -0,0 +1,49 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "DFGOSRExitPreparation.h" >+ >+#if ENABLE(DFG_JIT) >+ >+#include "CodeBlock.h" >+#include "Executable.h" >+#include "Operations.h" >+ >+namespace JSC { namespace DFG { >+ >+void prepareCodeOriginForOSRExit(ExecState* exec, CodeOrigin codeOrigin) >+{ >+ for (; codeOrigin.inlineCallFrame; codeOrigin = codeOrigin.inlineCallFrame->caller) { >+ static_cast<FunctionExecutable*>(codeOrigin.inlineCallFrame->executable.get()) >+ ->baselineCodeBlockFor(codeOrigin.inlineCallFrame->isCall ? CodeForCall : CodeForConstruct) >+ ->jitCompile(exec); >+ } >+} >+ >+} } // namespace JSC::DFG >+ >+#endif // ENABLE(DFG_JIT) >+ >Index: Source/JavaScriptCore/dfg/DFGOSRExitPreparation.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGOSRExitPreparation.h (revision 0) >+++ Source/JavaScriptCore/dfg/DFGOSRExitPreparation.h (working copy) >@@ -0,0 +1,53 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#ifndef DFGOSRExitPreparation_h >+#define DFGOSRExitPreparation_h >+ >+#if ENABLE(DFG_JIT) >+ >+#include "CallFrame.h" >+#include "CodeOrigin.h" >+ >+namespace JSC { namespace DFG { >+ >+// Make sure all code on our inline stack is JIT compiled. This is necessary since >+// we may opt to inline a code block even before it had ever been compiled by the >+// JIT, but our OSR exit infrastructure currently only works if the target of the >+// OSR exit is JIT code. This could be changed since there is nothing particularly >+// hard about doing an OSR exit into the interpreter, but for now this seems to make >+// sense in that if we're OSR exiting from inlined code of a DFG code block, then >+// probably it's a good sign that the thing we're exiting into is hot. Even more >+// interestingly, since the code was inlined, it may never otherwise get JIT >+// compiled since the act of inlining it may ensure that it otherwise never runs. >+void prepareCodeOriginForOSRExit(ExecState*, CodeOrigin); >+ >+} } // namespace JSC::DFG >+ >+#endif // ENABLE(DFG_JIT) >+ >+#endif // DFGOSRExitPreparation_h >+ >+ >Index: Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (revision 148047) >+++ Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (working copy) >@@ -1777,7 +1777,7 @@ void SpeculativeJIT::checkArgumentTypes( > continue; > > VirtualRegister virtualRegister = variableAccessData->local(); >- SpeculatedType predictedType = variableAccessData->prediction(); >+ SpeculatedType predictedType = variableAccessData->argumentAwarePrediction(); > > JSValueSource valueSource = JSValueSource(JITCompiler::addressFor(virtualRegister)); > >Index: Source/JavaScriptCore/dfg/DFGValueSource.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGValueSource.h (revision 148047) >+++ Source/JavaScriptCore/dfg/DFGValueSource.h (working copy) >@@ -131,7 +131,7 @@ public: > { > if (isInt32Speculation(prediction)) > return ValueSource(Int32InJSStack); >- if (isArraySpeculation(prediction) || isCellSpeculation(prediction)) >+ if (isCellSpeculation(prediction)) > return ValueSource(CellInJSStack); > if (isBooleanSpeculation(prediction)) > return ValueSource(BooleanInJSStack); >Index: Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp (revision 148047) >+++ Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp (working copy) >@@ -214,7 +214,7 @@ void VariableEventStream::reconstruct( > > bool found = false; > >- if (node && node->op() == UInt32ToNumber) { >+ if (node && needsOSRBackwardRewiring(node->op())) { > MinifiedID id = node->child1(); > if (tryToSetConstantRecovery(valueRecoveries[i], codeBlock, graph.at(id))) > continue; >@@ -257,6 +257,7 @@ void VariableEventStream::reconstruct( > doubleAsInt32ID = id; > break; > default: >+ ASSERT(!needsOSRForwardRewiring(node->op())); > break; > } > } >Index: Source/JavaScriptCore/ftl/FTLAbbreviations.h >=================================================================== >--- Source/JavaScriptCore/ftl/FTLAbbreviations.h (revision 148047) >+++ Source/JavaScriptCore/ftl/FTLAbbreviations.h (working copy) >@@ -80,9 +80,14 @@ static inline LType structType(LType ele > } > > enum Variadicity { NotVariadic, Variadic }; >-static inline LType functionType(LType returnType, LType* paramTypes, unsigned paramCount, Variadicity variadicity) >+static inline LType functionType(LType returnType, const LType* paramTypes, unsigned paramCount, Variadicity variadicity) > { >- return LLVMFunctionType(returnType, paramTypes, paramCount, variadicity == Variadic); >+ return LLVMFunctionType(returnType, const_cast<LType*>(paramTypes), paramCount, variadicity == Variadic); >+} >+template<typename VectorType> >+inline LType functionType(LType returnType, const VectorType& vector, Variadicity variadicity = NotVariadic) >+{ >+ return functionType(returnType, vector.begin(), vector.size(), variadicity); > } > static inline LType functionType(LType returnType, Variadicity variadicity = NotVariadic) > { >@@ -98,6 +103,8 @@ static inline LType functionType(LType r > return functionType(returnType, paramTypes, 2, variadicity); > } > >+static inline LType typeOf(LValue value) { return LLVMTypeOf(value); } >+ > static inline unsigned mdKindID(const char* string) { return LLVMGetMDKindID(string, strlen(string)); } > static inline LValue mdString(const char* string, unsigned length) { return LLVMMDString(string, length); } > static inline LValue mdString(const char* string) { return mdString(string, strlen(string)); } >@@ -151,9 +158,14 @@ static inline LValue buildIntCast(LBuild > static inline LValue buildIntToPtr(LBuilder builder, LValue value, LType type) { return LLVMBuildIntToPtr(builder, value, type, ""); } > static inline LValue buildPtrToInt(LBuilder builder, LValue value, LType type) { return LLVMBuildPtrToInt(builder, value, type, ""); } > static inline LValue buildICmp(LBuilder builder, LIntPredicate cond, LValue left, LValue right) { return LLVMBuildICmp(builder, cond, left, right, ""); } >-static inline LValue buildCall(LBuilder builder, LValue function, LValue* args, unsigned numArgs) >+static inline LValue buildCall(LBuilder builder, LValue function, const LValue* args, unsigned numArgs) >+{ >+ return LLVMBuildCall(builder, function, const_cast<LValue*>(args), numArgs, ""); >+} >+template<typename VectorType> >+inline LValue buildCall(LBuilder builder, LValue function, const VectorType& vector) > { >- return LLVMBuildCall(builder, function, args, numArgs, ""); >+ return buildCall(builder, function, vector.begin(), vector.size()); > } > static inline LValue buildCall(LBuilder builder, LValue function) > { >@@ -168,6 +180,8 @@ static inline LValue buildCall(LBuilder > LValue args[] = { arg1, arg2 }; > return buildCall(builder, function, args, 2); > } >+enum TailCallMode { IsNotTailCall, IsTailCall }; >+static inline void setTailCall(LValue call, TailCallMode mode) { LLVMSetTailCall(call, mode == IsTailCall); } > static inline LValue buildExtractValue(LBuilder builder, LValue aggVal, unsigned index) { return LLVMBuildExtractValue(builder, aggVal, index, ""); } > static inline LValue buildSelect(LBuilder builder, LValue condition, LValue taken, LValue notTaken) { return LLVMBuildSelect(builder, condition, taken, notTaken, ""); } > static inline LValue buildBr(LBuilder builder, LBasicBlock destination) { return LLVMBuildBr(builder, destination); } >Index: Source/JavaScriptCore/ftl/FTLCArgumentGetter.cpp >=================================================================== >--- Source/JavaScriptCore/ftl/FTLCArgumentGetter.cpp (revision 0) >+++ Source/JavaScriptCore/ftl/FTLCArgumentGetter.cpp (working copy) >@@ -0,0 +1,99 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "FTLCArgumentGetter.h" >+ >+#if ENABLE(FTL_JIT) >+ >+namespace JSC { namespace FTL { >+ >+using namespace DFG; >+ >+void CArgumentGetter::loadNextAndBox(ValueFormat format, GPRReg destination, GPRReg scratch) >+{ >+ if (scratch == InvalidGPRReg) { >+ if (destination == GPRInfo::nonArgGPR0) >+ scratch = GPRInfo::nonArgGPR1; >+ else >+ scratch = GPRInfo::nonArgGPR0; >+ } >+ >+ switch (format) { >+ case ValueFormatInt32: { >+ loadNext32(destination); >+ m_jit.or64(GPRInfo::tagTypeNumberRegister, destination); >+ break; >+ } >+ >+ case ValueFormatUInt32: { >+ loadNext32(destination); >+ MacroAssembler::Jump isInt = m_jit.branch32( >+ MacroAssembler::GreaterThanOrEqual, >+ destination, MacroAssembler::TrustedImm32(0)); >+ >+ m_jit.moveDoubleTo64(FPRInfo::fpRegT0, scratch); >+ m_jit.convertInt32ToDouble(destination, FPRInfo::fpRegT0); >+ m_jit.boxDouble(FPRInfo::fpRegT0, destination); >+ m_jit.move64ToDouble(scratch, FPRInfo::fpRegT0); >+ >+ MacroAssembler::Jump done = m_jit.jump(); >+ >+ isInt.link(&m_jit); >+ m_jit.or64(GPRInfo::tagTypeNumberRegister, destination); >+ >+ done.link(&m_jit); >+ break; >+ } >+ >+ case ValueFormatBoolean: { >+ loadNext8(destination); >+ m_jit.or32(MacroAssembler::TrustedImm32(ValueFalse), destination); >+ break; >+ } >+ >+ case ValueFormatJSValue: { >+ loadNext64(destination); >+ break; >+ } >+ >+ case ValueFormatDouble: { >+ m_jit.moveDoubleTo64(FPRInfo::fpRegT0, scratch); >+ loadNextDouble(FPRInfo::fpRegT0); >+ m_jit.boxDouble(FPRInfo::fpRegT0, destination); >+ m_jit.move64ToDouble(scratch, FPRInfo::fpRegT0); >+ break; >+ } >+ >+ default: >+ RELEASE_ASSERT_NOT_REACHED(); >+ break; >+ } >+} >+ >+} } // namespace JSC::FTL >+ >+#endif // ENABLE(FTL_JIT) >+ >Index: Source/JavaScriptCore/ftl/FTLCArgumentGetter.h >=================================================================== >--- Source/JavaScriptCore/ftl/FTLCArgumentGetter.h (revision 0) >+++ Source/JavaScriptCore/ftl/FTLCArgumentGetter.h (working copy) >@@ -0,0 +1,140 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#ifndef FTLCArgumentGetter_h >+#define FTLCArgumentGetter_h >+ >+#include <wtf/Platform.h> >+ >+#if ENABLE(FTL_JIT) >+ >+#include "DFGAssemblyHelpers.h" >+#include "FTLValueFormat.h" >+ >+namespace JSC { namespace FTL { >+ >+// This currently only understands how to get arguments on X86-64 cdecl. This is also >+// not particularly efficient. It will generate some redundant moves. >+ >+template<typename RegisterKind> >+bool isArgumentRegister(typename RegisterKind::RegisterType reg) >+{ >+ for (unsigned i = 0; i < RegisterKind::numberOfArgumentRegisters; ++i) { >+ if (RegisterKind::toArgumentRegister(i) == reg) >+ return true; >+ } >+ return false; >+} >+ >+class CArgumentGetter { >+public: >+ // Peek offset is the number of things on the stack below the first argument. >+ // It will be 1 if you haven't pushed or popped after the call; i.e. the only >+ // thing is the return address. >+ CArgumentGetter(DFG::AssemblyHelpers& jit, int peekOffset = 1) >+ : m_jit(jit) >+ , m_peekOffset(peekOffset) >+ , m_gprArgumentIndex(0) >+ , m_fprArgumentIndex(0) >+ , m_stackArgumentIndex(0) >+ { >+ } >+ >+ void loadNext8(DFG::GPRReg destination) >+ { >+ ASSERT(!isArgumentRegister<DFG::GPRInfo>(destination)); >+ if (m_gprArgumentIndex < DFG::GPRInfo::numberOfArgumentRegisters) { >+ m_jit.move(DFG::GPRInfo::toArgumentRegister(m_gprArgumentIndex++), destination); >+ return; >+ } >+ >+ m_jit.load8(nextAddress(), destination); >+ } >+ >+ void loadNext32(DFG::GPRReg destination) >+ { >+ ASSERT(!isArgumentRegister<DFG::GPRInfo>(destination)); >+ if (m_gprArgumentIndex < DFG::GPRInfo::numberOfArgumentRegisters) { >+ m_jit.move(DFG::GPRInfo::toArgumentRegister(m_gprArgumentIndex++), destination); >+ return; >+ } >+ >+ m_jit.load32(nextAddress(), destination); >+ } >+ >+ void loadNext64(DFG::GPRReg destination) >+ { >+ ASSERT(!isArgumentRegister<DFG::GPRInfo>(destination)); >+ if (m_gprArgumentIndex < DFG::GPRInfo::numberOfArgumentRegisters) { >+ m_jit.move(DFG::GPRInfo::toArgumentRegister(m_gprArgumentIndex++), destination); >+ return; >+ } >+ >+ m_jit.load64(nextAddress(), destination); >+ } >+ >+ void loadNextPtr(DFG::GPRReg destination) >+ { >+ loadNext64(destination); >+ } >+ >+ void loadNextDouble(DFG::FPRReg destination) >+ { >+ ASSERT( >+ !isArgumentRegister<DFG::FPRInfo>(destination) >+ || destination == DFG::FPRInfo::argumentFPR0); >+ >+ if (m_fprArgumentIndex < DFG::FPRInfo::numberOfArgumentRegisters) { >+ m_jit.moveDouble(DFG::FPRInfo::toArgumentRegister(m_fprArgumentIndex++), destination); >+ return; >+ } >+ >+ m_jit.loadDouble(nextAddress(), destination); >+ } >+ >+ void loadNextAndBox( >+ ValueFormat format, DFG::GPRReg destination, DFG::GPRReg scratch = InvalidGPRReg); >+ >+private: >+ MacroAssembler::Address nextAddress() >+ { >+ return MacroAssembler::Address( >+ MacroAssembler::stackPointerRegister, >+ (m_peekOffset + m_stackArgumentIndex++) * sizeof(void*)); >+ } >+ >+ DFG::AssemblyHelpers& m_jit; >+ unsigned m_peekOffset; >+ unsigned m_gprArgumentIndex; >+ unsigned m_fprArgumentIndex; >+ unsigned m_stackArgumentIndex; >+}; >+ >+} } // namespace JSC::FTL >+ >+#endif // ENABLE(FTL_JIT) >+ >+#endif // FTLCArgumentGetter_h >+ >Index: Source/JavaScriptCore/ftl/FTLExitArgument.cpp >=================================================================== >--- Source/JavaScriptCore/ftl/FTLExitArgument.cpp (revision 0) >+++ Source/JavaScriptCore/ftl/FTLExitArgument.cpp (working copy) >@@ -0,0 +1,41 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "FTLExitArgument.h" >+ >+#if ENABLE(FTL_JIT) >+ >+namespace JSC { namespace FTL { >+ >+void ExitArgument::dump(PrintStream& out) const >+{ >+ out.print("arg", argument(), " as ", format()); >+} >+ >+} } // namespace JSC::FTL >+ >+#endif // ENABLE(FTL_JIT) >+ >Index: Source/JavaScriptCore/ftl/FTLExitArgument.h >=================================================================== >--- Source/JavaScriptCore/ftl/FTLExitArgument.h (revision 0) >+++ Source/JavaScriptCore/ftl/FTLExitArgument.h (working copy) >@@ -0,0 +1,93 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#ifndef FTLExitArgument_h >+#define FTLExitArgument_h >+ >+#include <wtf/Platform.h> >+ >+#if ENABLE(FTL_JIT) >+ >+#include "FTLValueFormat.h" >+#include <wtf/PrintStream.h> >+ >+namespace JSC { namespace FTL { >+ >+struct ExitArgumentRepresentation { >+ ValueFormat format; >+ unsigned argument; >+}; >+ >+class ExitArgument { >+public: >+ ExitArgument() >+ { >+ m_representation.format = InvalidValueFormat; >+ } >+ >+ ExitArgument(ValueFormat format, unsigned argument) >+ { >+ m_representation.format = format; >+ m_representation.argument = argument; >+ } >+ >+ explicit ExitArgument(ExitArgumentRepresentation representation) >+ { >+ m_representation = representation; >+ } >+ >+ bool operator!() const { return m_representation.format == InvalidValueFormat; } >+ >+ ValueFormat format() const >+ { >+ ASSERT(*this); >+ return m_representation.format; >+ } >+ >+ unsigned argument() const >+ { >+ ASSERT(*this); >+ return m_representation.argument; >+ } >+ >+ ExitArgument withFormat(ValueFormat format) >+ { >+ return ExitArgument(format, argument()); >+ } >+ >+ ExitArgumentRepresentation representation() const { return m_representation; } >+ >+ void dump(PrintStream&) const; >+ >+private: >+ ExitArgumentRepresentation m_representation; >+}; >+ >+} } // namespace JSC::FTL >+ >+#endif // ENABLE(FTL_JIT) >+ >+#endif // FTLExitArgument_h >+ >Index: Source/JavaScriptCore/ftl/FTLExitArgumentForOperand.cpp >=================================================================== >--- Source/JavaScriptCore/ftl/FTLExitArgumentForOperand.cpp (revision 0) >+++ Source/JavaScriptCore/ftl/FTLExitArgumentForOperand.cpp (working copy) >@@ -0,0 +1,41 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "FTLExitArgumentForOperand.h" >+ >+#if ENABLE(FTL_JIT) >+ >+namespace JSC { namespace FTL { >+ >+void ExitArgumentForOperand::dump(PrintStream& out) const >+{ >+ out.print(m_exitArgument, " for r", m_operand); >+} >+ >+} } // namespace JSC::FTL >+ >+#endif // ENABLE(FTL_JIT) >+ >Index: Source/JavaScriptCore/ftl/FTLExitArgumentForOperand.h >=================================================================== >--- Source/JavaScriptCore/ftl/FTLExitArgumentForOperand.h (revision 0) >+++ Source/JavaScriptCore/ftl/FTLExitArgumentForOperand.h (working copy) >@@ -0,0 +1,73 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#ifndef FTLExitArgumentForOperand_h >+#define FTLExitArgumentForOperand_h >+ >+#include <wtf/Platform.h> >+ >+#if ENABLE(FTL_JIT) >+ >+#include "FTLExitArgument.h" >+ >+namespace JSC { namespace FTL { >+ >+class ExitArgumentForOperand { >+public: >+ ExitArgumentForOperand() >+ : m_operand(-1) >+ { >+ } >+ >+ ExitArgumentForOperand(ExitArgument exitArgument, int operand) >+ : m_exitArgument(exitArgument) >+ , m_operand(operand) >+ { >+ } >+ >+ bool operator!() const { return !m_exitArgument; } >+ >+ const ExitArgument& exitArgument() const { return m_exitArgument; } >+ int operand() const { return m_operand; } >+ >+ void dump(PrintStream&) const; >+ >+private: >+ ExitArgument m_exitArgument; >+ int m_operand; >+}; >+ >+inline bool lesserArgumentIndex( >+ const ExitArgumentForOperand& a, const ExitArgumentForOperand& b) >+{ >+ return a.exitArgument().argument() < b.exitArgument().argument(); >+} >+ >+} } // namespace JSC::FTL >+ >+#endif // ENABLE(FTL_JIT) >+ >+#endif // FTLExitArgumentForOperand_h >+ >Index: Source/JavaScriptCore/ftl/FTLExitArgumentList.h >=================================================================== >--- Source/JavaScriptCore/ftl/FTLExitArgumentList.h (revision 0) >+++ Source/JavaScriptCore/ftl/FTLExitArgumentList.h (working copy) >@@ -0,0 +1,45 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#ifndef FTLExitArgumentList_h >+#define FTLExitArgumentList_h >+ >+#include <wtf/Platform.h> >+ >+#if ENABLE(FTL_JIT) >+ >+#include "FTLAbbreviations.h" >+#include <wtf/Vector.h> >+ >+namespace JSC { namespace FTL { >+ >+typedef Vector<LValue, 16> ExitArgumentList; >+ >+} } // namespace JSC::FTL >+ >+#endif // ENABLE(FTL_JIT) >+ >+#endif // FTLExitArgumentList_h >+ >Index: Source/JavaScriptCore/ftl/FTLExitThunkGenerator.cpp >=================================================================== >--- Source/JavaScriptCore/ftl/FTLExitThunkGenerator.cpp (revision 0) >+++ Source/JavaScriptCore/ftl/FTLExitThunkGenerator.cpp (working copy) >@@ -0,0 +1,57 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "FTLExitThunkGenerator.h" >+ >+#if ENABLE(FTL_JIT) >+ >+#include "FTLOSRExitCompilationInfo.h" >+#include "FTLState.h" >+ >+namespace JSC { namespace FTL { >+ >+using namespace JSC::DFG; >+ >+ExitThunkGenerator::ExitThunkGenerator(State& state) >+ : CCallHelpers(&state.graph.m_globalData, state.graph.m_codeBlock) >+{ >+} >+ >+ExitThunkGenerator::~ExitThunkGenerator() >+{ >+} >+ >+void ExitThunkGenerator::emitThunk(unsigned index, OSRExitCompilationInfo& info) >+{ >+ info.m_thunkLabel = label(); >+ move(TrustedImm32(index), GPRInfo::nonArgGPR0); >+ info.m_thunkJump = patchableJump(); >+} >+ >+} } // namespace JSC::FTL >+ >+#endif // ENABLE(FTL_JIT) >+ >Index: Source/JavaScriptCore/ftl/FTLExitThunkGenerator.h >=================================================================== >--- Source/JavaScriptCore/ftl/FTLExitThunkGenerator.h (revision 0) >+++ Source/JavaScriptCore/ftl/FTLExitThunkGenerator.h (working copy) >@@ -0,0 +1,53 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#ifndef FTLExitThunkGenerator_h >+#define FTLExitThunkGenerator_h >+ >+#include <wtf/Platform.h> >+ >+#if ENABLE(FTL_JIT) >+ >+#include "DFGCCallHelpers.h" >+ >+namespace JSC { namespace FTL { >+ >+class State; >+struct OSRExitCompilationInfo; >+ >+class ExitThunkGenerator : public DFG::CCallHelpers { >+public: >+ ExitThunkGenerator(State& state); >+ ~ExitThunkGenerator(); >+ >+ void emitThunk(unsigned index, OSRExitCompilationInfo&); >+}; >+ >+} } // namespace JSC::FTL >+ >+#endif // ENABLE(FTL_JIT) >+ >+#endif // FTLExitThunkGenerator_h >+ >Index: Source/JavaScriptCore/ftl/FTLExitValue.cpp >=================================================================== >--- Source/JavaScriptCore/ftl/FTLExitValue.cpp (revision 0) >+++ Source/JavaScriptCore/ftl/FTLExitValue.cpp (working copy) >@@ -0,0 +1,65 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "FTLExitValue.h" >+ >+#if ENABLE(FTL_JIT) >+ >+namespace JSC { namespace FTL { >+ >+void ExitValue::dump(PrintStream& out) const >+{ >+ switch (kind()) { >+ case InvalidExitValue: >+ out.print("Invalid"); >+ return; >+ case ExitValueDead: >+ out.print("Dead"); >+ return; >+ case ExitValueArgument: >+ out.print("Argument(", exitArgument(), ")"); >+ return; >+ case ExitValueConstant: >+ out.print("Constant(", constant(), ")"); >+ return; >+ case ExitValueInJSStack: >+ out.print("InJSStack"); >+ return; >+ case ExitValueInJSStackAsInt32: >+ out.print("InJSStackAsInt32"); >+ return; >+ case ExitValueInJSStackAsDouble: >+ out.print("InJSStackAsDouble"); >+ return; >+ } >+ >+ RELEASE_ASSERT_NOT_REACHED(); >+} >+ >+} } // namespace JSC::FTL >+ >+#endif // ENABLE(FTL_JIT) >+ >Index: Source/JavaScriptCore/ftl/FTLExitValue.h >=================================================================== >--- Source/JavaScriptCore/ftl/FTLExitValue.h (revision 0) >+++ Source/JavaScriptCore/ftl/FTLExitValue.h (working copy) >@@ -0,0 +1,151 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#ifndef FTLExitValue_h >+#define FTLExitValue_h >+ >+#include <wtf/Platform.h> >+ >+#if ENABLE(FTL_JIT) >+ >+#include "FTLExitArgument.h" >+#include "JSCJSValue.h" >+#include <wtf/PrintStream.h> >+ >+namespace JSC { namespace FTL { >+ >+// This is like ValueRecovery, but respects the way that the FTL does OSR >+// exit: the live non-constant non-flushed values are passed as arguments >+// to a noreturn tail call. ExitValue is hence mostly responsible for >+// telling us the mapping between operands in bytecode and the arguments to >+// the call. >+ >+enum ExitValueKind { >+ InvalidExitValue, >+ ExitValueDead, >+ ExitValueArgument, >+ ExitValueConstant, >+ ExitValueInJSStack, >+ ExitValueInJSStackAsInt32, >+ ExitValueInJSStackAsDouble >+}; >+ >+class ExitValue { >+public: >+ ExitValue() >+ : m_kind(InvalidExitValue) >+ { >+ } >+ >+ bool operator!() const { return m_kind == InvalidExitValue; } >+ >+ static ExitValue dead() >+ { >+ ExitValue result; >+ result.m_kind = ExitValueDead; >+ return result; >+ } >+ >+ static ExitValue inJSStack() >+ { >+ ExitValue result; >+ result.m_kind = ExitValueInJSStack; >+ return result; >+ } >+ >+ static ExitValue inJSStackAsInt32() >+ { >+ ExitValue result; >+ result.m_kind = ExitValueInJSStackAsInt32; >+ return result; >+ } >+ >+ static ExitValue inJSStackAsDouble() >+ { >+ ExitValue result; >+ result.m_kind = ExitValueInJSStackAsDouble; >+ return result; >+ } >+ >+ static ExitValue constant(JSValue value) >+ { >+ ExitValue result; >+ result.m_kind = ExitValueConstant; >+ result.u.constant = JSValue::encode(value); >+ return result; >+ } >+ >+ static ExitValue exitArgument(const ExitArgument& argument) >+ { >+ ExitValue result; >+ result.m_kind = ExitValueArgument; >+ result.u.argument = argument.representation(); >+ return result; >+ } >+ >+ ExitValueKind kind() const { return m_kind; } >+ >+ bool isDead() const { return kind() == ExitValueDead; } >+ bool isInJSStackSomehow() const >+ { >+ switch (kind()) { >+ case ExitValueInJSStack: >+ case ExitValueInJSStackAsInt32: >+ case ExitValueInJSStackAsDouble: >+ return true; >+ default: >+ return false; >+ } >+ } >+ bool isConstant() const { return kind() == ExitValueConstant; } >+ bool isArgument() const { return kind() == ExitValueArgument; } >+ >+ ExitArgument exitArgument() const >+ { >+ ASSERT(isArgument()); >+ return ExitArgument(u.argument); >+ } >+ >+ JSValue constant() const >+ { >+ ASSERT(isConstant()); >+ return JSValue::decode(u.constant); >+ } >+ >+ void dump(PrintStream&) const; >+ >+private: >+ ExitValueKind m_kind; >+ union { >+ ExitArgumentRepresentation argument; >+ EncodedJSValue constant; >+ } u; >+}; >+ >+} } // namespace JSC::FTL >+ >+#endif // ENABLE(FTL_JIT) >+ >+#endif // FTLExitValue_h >Index: Source/JavaScriptCore/ftl/FTLFormattedValue.h >=================================================================== >--- Source/JavaScriptCore/ftl/FTLFormattedValue.h (revision 148047) >+++ Source/JavaScriptCore/ftl/FTLFormattedValue.h (working copy) >@@ -31,6 +31,7 @@ > #if ENABLE(FTL_JIT) > > #include "FTLAbbreviations.h" >+#include "FTLValueFormat.h" > > namespace JSC { namespace FTL { > >@@ -41,18 +42,6 @@ namespace JSC { namespace FTL { > // use this in situations where there is no good way to say what node the value came > // from. > >-// Note that this is awkwardly similar to DataFormat in other parts of JSC, except that >-// unlike DataFormat and like ValueRecovery, it distinguishes between UInt32 and Int32. >- >-enum ValueFormat { >- InvalidValueFormat, >- ValueFormatInt32, >- ValueFormatUInt32, >- ValueFormatBoolean, >- ValueFormatJSValue, >- ValueFormatDouble >-}; >- > class FormattedValue { > public: > FormattedValue() >@@ -81,6 +70,13 @@ private: > LValue m_value; > }; > >+static inline FormattedValue noValue() { return FormattedValue(); } >+static inline FormattedValue int32Value(LValue value) { return FormattedValue(ValueFormatInt32, value); } >+static inline FormattedValue uInt32Value(LValue value) { return FormattedValue(ValueFormatUInt32, value); } >+static inline FormattedValue booleanValue(LValue value) { return FormattedValue(ValueFormatBoolean, value); } >+static inline FormattedValue jsValueValue(LValue value) { return FormattedValue(ValueFormatJSValue, value); } >+static inline FormattedValue doubleValue(LValue value) { return FormattedValue(ValueFormatDouble, value); } >+ > } } // namespace JSC::FTL > > #endif // ENABLE(FTL_JIT) >Index: Source/JavaScriptCore/ftl/FTLJITCode.cpp >=================================================================== >--- Source/JavaScriptCore/ftl/FTLJITCode.cpp (revision 148047) >+++ Source/JavaScriptCore/ftl/FTLJITCode.cpp (working copy) >@@ -42,6 +42,11 @@ JITCode::~JITCode() > LLVMDisposeExecutionEngine(m_engine); > } > >+void JITCode::initializeExitThunks(CodeRef exitThunks) >+{ >+ m_exitThunks = exitThunks; >+} >+ > void JITCode::initializeCode(LLVMExecutionEngineRef engine, CodeRef entrypoint) > { > m_engine = engine; >@@ -97,6 +102,11 @@ bool JITCode::contains(void*) > return false; > } > >+JITCode::CodePtr JITCode::exitThunks() >+{ >+ return m_exitThunks.code(); >+} >+ > JITCode* JITCode::ftl() > { > return this; >Index: Source/JavaScriptCore/ftl/FTLJITCode.h >=================================================================== >--- Source/JavaScriptCore/ftl/FTLJITCode.h (revision 148047) >+++ Source/JavaScriptCore/ftl/FTLJITCode.h (working copy) >@@ -32,6 +32,7 @@ > > #include "DFGCommonData.h" > #include "FTLLLVMHeaders.h" >+#include "FTLOSRExit.h" > #include "JITCode.h" > > namespace JSC { namespace FTL { >@@ -48,12 +49,16 @@ public: > size_t size(); > bool contains(void*); > >+ void initializeExitThunks(CodeRef); > void initializeCode(LLVMExecutionEngineRef, CodeRef entrypoint); > >+ CodePtr exitThunks(); >+ > JITCode* ftl(); > DFG::CommonData* dfgCommon(); > > DFG::CommonData common; >+ SegmentedVector<OSRExit, 8> osrExit; > > private: > // FIXME: LLVM should use our own JIT memory allocator, and we shouldn't have to >@@ -61,6 +66,7 @@ private: > // https://bugs.webkit.org/show_bug.cgi?id=113619 > LLVMExecutionEngineRef m_engine; > CodeRef m_entrypoint; >+ CodeRef m_exitThunks; > }; > > } } // namespace JSC::FTL >Index: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp >=================================================================== >--- Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (revision 148047) >+++ Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (working copy) >@@ -28,10 +28,15 @@ > > #if ENABLE(FTL_JIT) > >+#include "CodeBlockWithJITType.h" > #include "DFGAbstractState.h" > #include "FTLAbstractHeapRepository.h" >+#include "FTLExitThunkGenerator.h" > #include "FTLFormattedValue.h" > #include "FTLOutput.h" >+#include "FTLThunks.h" >+#include "FTLValueSource.h" >+#include "LinkBuffer.h" > #include "Operations.h" > > namespace JSC { namespace FTL { >@@ -41,7 +46,7 @@ using namespace DFG; > // Using this instead of typeCheck() helps to reduce the load on LLVM, by creating > // significantly less dead code. > #define FTL_TYPE_CHECK(lowValue, highValue, typesPassedThrough, failCondition) do { \ >- LValue _ftc_lowValue = (lowValue); \ >+ FormattedValue _ftc_lowValue = (lowValue); \ > Edge _ftc_highValue = (highValue); \ > SpeculatedType _ftc_typesPassedThrough = (typesPassedThrough); \ > if (!m_state.needsTypeCheck(_ftc_highValue, _ftc_typesPassedThrough)) \ >@@ -57,6 +62,9 @@ public: > , m_localsBoolean(OperandsLike, state.graph.m_blocks[0]->variablesAtHead) > , m_locals32(OperandsLike, state.graph.m_blocks[0]->variablesAtHead) > , m_locals64(OperandsLike, state.graph.m_blocks[0]->variablesAtHead) >+ , m_valueSources(OperandsLike, state.graph.m_blocks[0]->variablesAtHead) >+ , m_lastSetOperand(std::numeric_limits<int>::max()) >+ , m_exitThunkGenerator(state) > , m_state(state.graph) > { > } >@@ -80,14 +88,14 @@ public: > m_locals64[index] = buildAlloca(m_out.m_builder, m_out.int64); > } > >+ m_initialization = appendBasicBlock(m_ftlState.function); >+ m_out.jump(m_initialization); >+ m_out.appendTo(m_initialization); >+ > m_callFrame = m_out.param(0); > m_tagTypeNumber = m_out.constInt64(TagTypeNumber); > m_tagMask = m_out.constInt64(TagMask); > >- m_abortFunction = constIntToPtr( >- m_out.constIntPtr(abort), >- pointerType(functionType(m_out.voidType))); >- > for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) { > m_highBlock = m_graph.m_blocks[blockIndex].get(); > if (!m_highBlock) >@@ -98,14 +106,17 @@ public: > > closeOverFlushedLocalOps(); > >- m_out.appendTo(m_prologue, m_blocks.get(m_graph.m_blocks[0].get())); >+ m_out.appendTo(m_initialization, m_blocks.get(m_graph.m_blocks[0].get())); > > transferAndCheckArguments(); > >- m_out.jump(m_blocks.get(m_graph.m_blocks[0].get())); >+ // Leave the initialization block hanging, since we will add to it later. > > for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) > compileBlock(blockIndex); >+ >+ // And now complete the initialization block. >+ linkOSRExitsAndCompleteInitializationBlock(); > > if (verboseCompilationEnabled()) > m_ftlState.dumpState("after lowering"); >@@ -151,8 +162,9 @@ private: > > void transferAndCheckArguments() > { >- // FIXME: Set up the OSR story here. >- // https://bugs.webkit.org/show_bug.cgi?id=113623 >+ // While checking arguments, everything is in the stack. >+ for (unsigned i = m_valueSources.size(); i--;) >+ m_valueSources[i] = ValueSource(ValueInJSStack); > > for (int i = 0; i < m_graph.m_codeBlock->numParameters(); ++i) { > Node* node = m_graph.m_arguments[i]; >@@ -170,21 +182,21 @@ private: > if (variable->shouldUnboxIfPossible()) { > RELEASE_ASSERT(!variable->shouldUseDoubleFormat()); > >- SpeculatedType prediction = variable->prediction(); >+ SpeculatedType prediction = variable->argumentAwarePrediction(); > > if (isInt32Speculation(prediction)) { >- speculateBackward(BadType, jsValue, node, isNotInt32(jsValue)); >+ speculateBackward(BadType, jsValueValue(jsValue), node, isNotInt32(jsValue)); > m_out.set(unboxInt32(jsValue), m_locals32.operand(variable->local())); > continue; > } > > if (isCellSpeculation(prediction)) { >- speculateBackward(BadType, jsValue, node, isNotCell(jsValue)); >+ speculateBackward(BadType, jsValueValue(jsValue), node, isNotCell(jsValue)); > m_out.set(jsValue, m_locals64.operand(variable->local())); > continue; > } > if (isBooleanSpeculation(prediction)) { >- speculateBackward(BadType, jsValue, node, isNotBoolean(jsValue)); >+ speculateBackward(BadType, jsValueValue(jsValue), node, isNotBoolean(jsValue)); > m_out.set(unboxBoolean(jsValue), m_localsBoolean.operand(variable->local())); > continue; > } >@@ -216,19 +228,19 @@ private: > // make IR dumps easier to read. > m_out.appendTo(lowBlock, m_nextLowBlock); > >- // FIXME: We should track the OSR situation here. >- // https://bugs.webkit.org/show_bug.cgi?id=113623 >+ initializeOSRExitStateForBlock(); > > m_int32Values.clear(); > m_jsValueValues.clear(); > m_booleanValues.clear(); > m_storageValues.clear(); >+ m_timeToLive.clear(); > > m_state.reset(); > m_state.beginBasicBlock(m_highBlock); > >- for (unsigned nodeIndex = 0; nodeIndex < m_highBlock->size(); ++nodeIndex) >- compileNode(nodeIndex); >+ for (m_nodeIndex = 0; m_nodeIndex < m_highBlock->size(); ++m_nodeIndex) >+ compileNode(m_nodeIndex); > } > > void compileNode(unsigned nodeIndex) >@@ -240,9 +252,6 @@ private: > > bool shouldExecuteEffects = m_state.startExecuting(m_node); > >- if (!m_node->shouldGenerate()) >- return; // FIXME: Implement OSR magic here. https://bugs.webkit.org/show_bug.cgi?id=113623 >- > m_direction = (m_node->flags() & NodeExitsForward) ? ForwardSpeculation : BackwardSpeculation; > > switch (m_node->op()) { >@@ -258,6 +267,12 @@ private: > case SetLocal: > compileSetLocal(); > break; >+ case MovHint: >+ compileMovHint(); >+ break; >+ case ZombieHint: >+ compileZombieHint(); >+ break; > case MovHintAndCheck: > compileMovHintAndCheck(); > break; >@@ -352,6 +367,11 @@ private: > break; > } > >+ DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, use); >+ >+ if (m_node->hasResult()) >+ m_timeToLive.add(m_node, m_node->adjustedRefCount()); >+ > if (shouldExecuteEffects) > m_state.executeEffects(nodeIndex); > } >@@ -368,8 +388,12 @@ private: > > void compileGetLocal() > { >+ // GetLocal is one of the few nodes that may be left behind, with !shouldGenerate(). >+ if (!m_node->shouldGenerate()) >+ return; >+ > VariableAccessData* variable = m_node->variableAccessData(); >- SpeculatedType prediction = variable->prediction(); >+ SpeculatedType prediction = variable->argumentAwarePrediction(); > AbstractValue& value = m_state.variables().operand(variable->local()); > > if (prediction == SpecNone) { >@@ -420,13 +444,12 @@ private: > > void compileSetLocal() > { >+ observeMovHint(m_node); >+ > VariableAccessData* variable = m_node->variableAccessData(); >- SpeculatedType prediction = variable->prediction(); >+ SpeculatedType prediction = variable->argumentAwarePrediction(); > bool needsFlushing = m_flushedLocalOps.contains(m_node); > >- // FIXME: Handle the MovHint for OSR. >- // https://bugs.webkit.org/show_bug.cgi?id=113623 >- > if (variable->shouldUnboxIfPossible()) { > if (variable->shouldUseDoubleFormat()) { > // FIXME: implement doubles in FTL. >@@ -438,21 +461,27 @@ private: > if (isInt32Speculation(prediction)) { > LValue value = lowInt32(m_node->child1()); > m_out.set(value, m_locals32.operand(variable->local())); >- if (needsFlushing) >+ if (needsFlushing) { > m_out.store32(value, payloadFor(variable->local())); >+ m_valueSources[variable->local()] = ValueSource(Int32InJSStack); >+ } > return; > } > if (isCellSpeculation(prediction)) { > LValue value = lowCell(m_node->child1()); > m_out.set(value, m_locals64.operand(variable->local())); >- if (needsFlushing) >+ if (needsFlushing) { > m_out.store64(value, addressFor(variable->local())); >+ m_valueSources[variable->local()] = ValueSource(ValueInJSStack); >+ } > return; > } > if (isBooleanSpeculation(prediction)) { > m_out.set(lowBoolean(m_node->child1()), m_localsBoolean.operand(variable->local())); >- if (needsFlushing) >+ if (needsFlushing) { > m_out.store64(lowJSValue(m_node->child1()), addressFor(variable->local())); >+ m_valueSources[variable->local()] = ValueSource(ValueInJSStack); >+ } > return; > } > } >@@ -460,18 +489,32 @@ private: > LValue value = lowJSValue(m_node->child1()); > if (variable->isCaptured()) { > m_out.store64(value, addressFor(variable->local())); >+ m_valueSources[variable->local()] = ValueSource(ValueInJSStack); > return; > } > > m_out.set(value, m_locals64.operand(variable->local())); >- if (needsFlushing) >+ if (needsFlushing) { > m_out.store64(value, addressFor(variable->local())); >+ m_valueSources[variable->local()] = ValueSource(ValueInJSStack); >+ } >+ } >+ >+ void compileMovHint() >+ { >+ observeMovHint(m_node); >+ } >+ >+ void compileZombieHint() >+ { >+ VariableAccessData* data = m_node->variableAccessData(); >+ m_lastSetOperand = data->local(); >+ m_valueSources[data->local()] = ValueSource(SourceIsDead); > } > > void compileMovHintAndCheck() > { >- // FIXME: Handle the MovHint for OSR. >- // https://bugs.webkit.org/show_bug.cgi?id=113623 >+ observeMovHint(m_node); > speculate(m_node->child1()); > } > >@@ -500,7 +543,7 @@ private: > } > > LValue result = m_out.addWithOverflow32(left, right); >- speculate(Overflow, 0, 0, m_out.extractValue(result, 1)); >+ speculate(Overflow, noValue(), 0, m_out.extractValue(result, 1)); > m_int32Values.add(m_node, m_out.extractValue(result, 0)); > break; > } >@@ -524,7 +567,7 @@ private: > } > > LValue result = m_out.subWithOverflow32(left, right); >- speculate(Overflow, 0, 0, m_out.extractValue(result, 1)); >+ speculate(Overflow, noValue(), 0, m_out.extractValue(result, 1)); > m_int32Values.add(m_node, m_out.extractValue(result, 0)); > break; > } >@@ -547,7 +590,7 @@ private: > result = m_out.mul(left, right); > else { > LValue overflowResult = m_out.mulWithOverflow32(left, right); >- speculate(Overflow, 0, 0, m_out.extractValue(overflowResult, 1)); >+ speculate(Overflow, noValue(), 0, m_out.extractValue(overflowResult, 1)); > result = m_out.extractValue(overflowResult, 0); > } > >@@ -556,8 +599,8 @@ private: > LBasicBlock continuation = m_out.newBlock(); > > LBasicBlock lastNext = m_out.appendTo(slowCase, continuation); >- speculate(NegativeZero, 0, 0, m_out.lessThan(left, m_out.int32Zero)); >- speculate(NegativeZero, 0, 0, m_out.lessThan(right, m_out.int32Zero)); >+ speculate(NegativeZero, noValue(), 0, m_out.lessThan(left, m_out.int32Zero)); >+ speculate(NegativeZero, noValue(), 0, m_out.lessThan(right, m_out.int32Zero)); > m_out.jump(continuation); > m_out.appendTo(continuation, lastNext); > } >@@ -585,7 +628,7 @@ private: > // We don't have a negate-with-overflow intrinsic. Hopefully this > // does the trick, though. > LValue overflowResult = m_out.subWithOverflow32(m_out.int32Zero, value); >- speculate(Overflow, 0, 0, m_out.extractValue(overflowResult, 1)); >+ speculate(Overflow, noValue(), 0, m_out.extractValue(overflowResult, 1)); > result = m_out.extractValue(overflowResult, 0); > } > >@@ -656,7 +699,7 @@ private: > > LValue value = lowInt32(m_node->child1()); > speculateForward( >- Overflow, 0, 0, m_out.lessThan(value, m_out.int32Zero), >+ Overflow, noValue(), 0, m_out.lessThan(value, m_out.int32Zero), > FormattedValue(ValueFormatUInt32, value)); > m_int32Values.add(m_node, value); > } >@@ -675,7 +718,7 @@ private: > > if (m_node->structureSet().size() == 1) { > speculate( >- exitKind, cell, 0, >+ exitKind, jsValueValue(cell), 0, > m_out.notEqual(structure, weakPointer(m_node->structureSet()[0]))); > return; > } >@@ -692,7 +735,7 @@ private: > } > > speculate( >- exitKind, cell, 0, >+ exitKind, jsValueValue(cell), 0, > m_out.notEqual(structure, weakPointer(m_node->structureSet().last()))); > > m_out.appendTo(continuation, lastNext); >@@ -755,7 +798,7 @@ private: > case Array::Contiguous: { > if (m_node->arrayMode().isInBounds()) { > speculate( >- OutOfBounds, 0, 0, >+ OutOfBounds, noValue(), 0, > m_out.aboveOrEqual( > index, m_out.load32(storage, m_heaps.Butterfly_publicLength))); > >@@ -764,7 +807,7 @@ private: > m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties, > storage, m_out.zeroExt(index, m_out.intPtr), > m_state.forNode(m_node->child2()).m_value)); >- speculate(LoadFromHole, 0, 0, m_out.isZero64(result)); >+ speculate(LoadFromHole, noValue(), 0, m_out.isZero64(result)); > m_jsValueValues.add(m_node, result); > break; > } >@@ -865,60 +908,69 @@ private: > } > } > >- void speculateBackward(ExitKind, LValue, Node*, LValue failCondition) >+ void speculateBackward( >+ ExitKind kind, FormattedValue lowValue, Node* highValue, LValue failCondition) > { >- LBasicBlock failCase = m_out.newBlock(); >- LBasicBlock continuation = m_out.newBlock(); >- >- m_out.branch(failCondition, failCase, continuation); >- LBasicBlock lastNext = m_out.appendTo(failCase, continuation); >- // FIXME: Implement OSR exit. >- // https://bugs.webkit.org/show_bug.cgi?id=113623 >- m_out.call(m_abortFunction); >- m_out.unreachable(); >- m_out.appendTo(continuation, lastNext); >+ appendOSRExit( >+ kind, lowValue, highValue, failCondition, BackwardSpeculation, FormattedValue()); > } > >- void speculateForward(ExitKind kind, LValue lowValue, Node* highValue, LValue failCondition, const FormattedValue&) >+ void speculateForward( >+ ExitKind kind, FormattedValue lowValue, Node* highValue, LValue failCondition, >+ const FormattedValue& recovery) > { >- speculateBackward(kind, lowValue, highValue, failCondition); >- // FIXME: Implement rewiring of OSR exit to forward. >- // https://bugs.webkit.org/show_bug.cgi?id=113623 >+ appendOSRExit( >+ kind, lowValue, highValue, failCondition, ForwardSpeculation, recovery); > } > >- void speculate(ExitKind kind, LValue lowValue, Node* highValue, LValue failCondition) >+ void speculate( >+ ExitKind kind, FormattedValue lowValue, Node* highValue, LValue failCondition) > { >- speculateBackward(kind, lowValue, highValue, failCondition); >- // FIXME: Implement rewiring the OSR exit to forward, if m_direction == ForwardDirection. >- // https://bugs.webkit.org/show_bug.cgi?id=113623 >+ appendOSRExit( >+ kind, lowValue, highValue, failCondition, m_direction, FormattedValue()); > } > > void terminate(ExitKind kind) > { >- speculate(kind, 0, 0, m_out.booleanTrue); >+ speculate(kind, noValue(), 0, m_out.booleanTrue); > } > >- void backwardTypeCheck(LValue lowValue, Edge highValue, SpeculatedType typesPassedThrough, LValue failCondition) >+ void backwardTypeCheck( >+ FormattedValue lowValue, Edge highValue, SpeculatedType typesPassedThrough, >+ LValue failCondition) > { >- if (!m_state.needsTypeCheck(highValue, typesPassedThrough)) >- return; >- ASSERT(mayHaveTypeCheck(highValue.useKind())); >- speculateBackward(BadType, lowValue, highValue.node(), failCondition); >- m_state.forNode(highValue).filter(typesPassedThrough); >+ appendTypeCheck( >+ lowValue, highValue, typesPassedThrough, failCondition, BackwardSpeculation, >+ FormattedValue()); > } > >- void forwardTypeCheck(LValue lowValue, Edge highValue, SpeculatedType typesPassedThrough, LValue failCondition) >+ void forwardTypeCheck( >+ FormattedValue lowValue, Edge highValue, SpeculatedType typesPassedThrough, >+ LValue failCondition) > { >- backwardTypeCheck(lowValue, highValue, typesPassedThrough, failCondition); >- // FIXME: Implement rewiring of OSR exit to forward. >- // https://bugs.webkit.org/show_bug.cgi?id=113623 >+ appendTypeCheck( >+ lowValue, highValue, typesPassedThrough, failCondition, ForwardSpeculation, >+ FormattedValue()); > } > >- void typeCheck(LValue lowValue, Edge highValue, SpeculatedType typesPassedThrough, LValue failCondition) >+ void typeCheck( >+ FormattedValue lowValue, Edge highValue, SpeculatedType typesPassedThrough, >+ LValue failCondition) > { >- backwardTypeCheck(lowValue, highValue, typesPassedThrough, failCondition); >- // FIXME: Implement rewiring of OSR exit to forward, if m_direction == ForwardDirection. >- // https://bugs.webkit.org/show_bug.cgi?id=113623 >+ appendTypeCheck( >+ lowValue, highValue, typesPassedThrough, failCondition, m_direction, >+ FormattedValue()); >+ } >+ >+ void appendTypeCheck( >+ FormattedValue lowValue, Edge highValue, SpeculatedType typesPassedThrough, >+ LValue failCondition, SpeculationDirection direction, FormattedValue recovery) >+ { >+ if (!m_state.needsTypeCheck(highValue, typesPassedThrough)) >+ return; >+ ASSERT(mayHaveTypeCheck(highValue.useKind())); >+ appendOSRExit(BadType, lowValue, highValue.node(), failCondition, direction, recovery); >+ m_state.forNode(highValue).filter(typesPassedThrough); > } > > LValue lowInt32(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation) >@@ -929,7 +981,8 @@ private: > return result; > > if (LValue boxedResult = m_jsValueValues.get(edge.node())) { >- FTL_TYPE_CHECK(boxedResult, edge, SpecInt32, isNotInt32(boxedResult)); >+ FTL_TYPE_CHECK( >+ jsValueValue(boxedResult), edge, SpecInt32, isNotInt32(boxedResult)); > LValue result = unboxInt32(boxedResult); > m_int32Values.add(edge.node(), result); > return result; >@@ -945,7 +998,8 @@ private: > ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || isCell(edge.useKind())); > > if (LValue uncheckedResult = m_jsValueValues.get(edge.node())) { >- FTL_TYPE_CHECK(uncheckedResult, edge, SpecCell, isNotCell(uncheckedResult)); >+ FTL_TYPE_CHECK( >+ jsValueValue(uncheckedResult), edge, SpecCell, isNotCell(uncheckedResult)); > return uncheckedResult; > } > >@@ -971,7 +1025,8 @@ private: > return result; > > if (LValue unboxedResult = m_jsValueValues.get(edge.node())) { >- FTL_TYPE_CHECK(unboxedResult, edge, SpecBoolean, isNotBoolean(unboxedResult)); >+ FTL_TYPE_CHECK( >+ jsValueValue(unboxedResult), edge, SpecBoolean, isNotBoolean(unboxedResult)); > LValue result = unboxBoolean(unboxedResult); > m_booleanValues.add(edge.node(), result); > return result; >@@ -1094,7 +1149,7 @@ private: > void speculateObject(Edge edge, LValue cell) > { > FTL_TYPE_CHECK( >- cell, edge, SpecObject, >+ jsValueValue(cell), edge, SpecObject, > m_out.equal( > m_out.loadPtr(cell, m_heaps.JSCell_structure), > m_out.constIntPtr(globalData().stringStructure.get()))); >@@ -1105,6 +1160,357 @@ private: > speculateObject(edge, lowCell(edge)); > } > >+ bool isLive(Node* node) >+ { >+ HashMap<Node*, unsigned>::iterator iter = m_timeToLive.find(node); >+ ASSERT(iter != m_timeToLive.end()); >+ return !!iter->value; >+ } >+ >+ void use(Edge edge) >+ { >+ HashMap<Node*, unsigned>::iterator iter = m_timeToLive.find(edge.node()); >+ ASSERT(iter != m_timeToLive.end()); >+ ASSERT(iter->value); >+ iter->value--; >+ } >+ >+ // Wrapper used only for DFG_NODE_DO_TO_CHILDREN >+ void use(Node*, Edge edge) >+ { >+ use(edge); >+ } >+ >+ void initializeOSRExitStateForBlock() >+ { >+ for (unsigned i = m_valueSources.size(); i--;) { >+ Node* node = m_highBlock->variablesAtHead[i]; >+ if (!node) { >+ m_valueSources[i] = ValueSource(SourceIsDead); >+ continue; >+ } >+ >+ VariableAccessData* variable = node->variableAccessData(); >+ SpeculatedType prediction = variable->argumentAwarePrediction(); >+ >+ if (variable->isArgumentsAlias()) { >+ m_valueSources[i] = ValueSource(ArgumentsSource); >+ continue; >+ } >+ >+ if (!node->shouldGenerate()) { >+ m_valueSources[i] = ValueSource(SourceIsDead); >+ continue; >+ } >+ >+ if (m_flushedLocalOps.contains(node)) { >+ // This value will have been flushed to the JSStack in some form or >+ // another. >+ >+ if (variable->shouldUnboxIfPossible()) { >+ if (variable->shouldUseDoubleFormat()) { >+ m_valueSources[i] = ValueSource(DoubleInJSStack); >+ continue; >+ } >+ >+ if (isInt32Speculation(prediction)) { >+ m_valueSources[i] = ValueSource(Int32InJSStack); >+ continue; >+ } >+ } >+ >+ m_valueSources[i] = ValueSource(ValueInJSStack); >+ continue; >+ } >+ >+ if (variable->shouldUnboxIfPossible()) { >+ if (variable->shouldUseDoubleFormat()) { >+ m_valueSources[i] = ValueSource(ValueInLocals); >+ continue; >+ } >+ >+ if (isInt32Speculation(prediction)) { >+ m_valueSources[i] = ValueSource(Int32InLocals); >+ continue; >+ } >+ >+ if (isBooleanSpeculation(prediction)) { >+ m_valueSources[i] = ValueSource(BooleanInLocals); >+ continue; >+ } >+ } >+ >+ m_valueSources[i] = ValueSource(ValueInLocals); >+ } >+ } >+ >+ void appendOSRExit( >+ ExitKind kind, FormattedValue lowValue, Node* highValue, LValue failCondition, >+ SpeculationDirection direction, FormattedValue recovery) >+ { >+ m_ftlState.jitCode->osrExit.append( >+ OSRExit( >+ kind, lowValue.format(), m_graph.methodOfGettingAValueProfileFor(highValue), >+ m_node->codeOrigin, m_lastSetOperand, m_valueSources.numberOfArguments(), >+ m_valueSources.numberOfLocals())); >+ m_ftlState.osrExit.append(OSRExitCompilationInfo()); >+ >+ OSRExit& exit = m_ftlState.jitCode->osrExit.last(); >+ OSRExitCompilationInfo& info = m_ftlState.osrExit.last(); >+ >+ LBasicBlock failCase = m_out.newBlock(); >+ LBasicBlock continuation = m_out.newBlock(); >+ >+ m_out.branch(failCondition, failCase, continuation); >+ >+ m_out.appendTo(m_prologue); >+ info.m_thunkAddress = buildAlloca(m_out.m_builder, m_out.intPtr); >+ >+ LBasicBlock lastNext = m_out.appendTo(failCase, continuation); >+ >+ ExitArgumentList arguments; >+ arguments.append(m_callFrame); >+ if (!!lowValue) >+ arguments.append(lowValue.value()); >+ >+ for (unsigned i = 0; i < exit.m_values.size(); ++i) { >+ ValueSource source = m_valueSources[i]; >+ >+ switch (source.kind()) { >+ case ValueInJSStack: >+ exit.m_values[i] = ExitValue::inJSStack(); >+ break; >+ case Int32InJSStack: >+ exit.m_values[i] = ExitValue::inJSStackAsInt32(); >+ break; >+ case DoubleInJSStack: >+ exit.m_values[i] = ExitValue::inJSStackAsDouble(); >+ break; >+ case ValueInLocals: >+ addExitArgument( >+ exit, arguments, i, ValueFormatJSValue, m_out.get(m_locals64[i])); >+ break; >+ case Int32InLocals: >+ addExitArgument( >+ exit, arguments, i, ValueFormatInt32, m_out.get(m_locals32[i])); >+ break; >+ case BooleanInLocals: >+ addExitArgument( >+ exit, arguments, i, ValueFormatBoolean, m_out.get(m_localsBoolean[i])); >+ break; >+ case DoubleInLocals: >+ // FIXME: implement doubles in FTL. >+ // https://bugs.webkit.org/show_bug.cgi?id=113624 >+ RELEASE_ASSERT_NOT_REACHED(); >+ break; >+ case ArgumentsSource: >+ // FIXME: implement PhantomArguments. >+ // https://bugs.webkit.org/show_bug.cgi?id=113986 >+ RELEASE_ASSERT_NOT_REACHED(); >+ break; >+ case SourceIsDead: >+ exit.m_values[i] = ExitValue::dead(); >+ break; >+ case HaveNode: >+ addExitArgumentForNode(exit, arguments, i, source.node()); >+ break; >+ default: >+ RELEASE_ASSERT_NOT_REACHED(); >+ break; >+ } >+ } >+ >+ if (direction == ForwardSpeculation) >+ exit.convertToForward(m_highBlock, m_node, m_nodeIndex, recovery, arguments); >+ >+ // So, the really lame thing here is that we have to build an LLVM function type. >+ // Booo. >+ Vector<LType, 16> argumentTypes; >+ for (unsigned i = 0; i < arguments.size(); ++i) >+ argumentTypes.append(typeOf(arguments[i])); >+ >+ m_out.call( >+ m_out.intToPtr( >+ m_out.get(info.m_thunkAddress), >+ pointerType(functionType(m_out.voidType, argumentTypes))), >+ arguments); >+ m_out.unreachable(); >+ >+ m_out.appendTo(continuation, lastNext); >+ } >+ >+ void addExitArgumentForNode( >+ OSRExit& exit, ExitArgumentList& arguments, unsigned index, Node* node) >+ { >+ ASSERT(node->shouldGenerate()); >+ ASSERT(node->hasResult()); >+ >+ if (tryToSetConstantExitArgument(exit, index, node)) >+ return; >+ >+ if (!isLive(node)) { >+ bool found = false; >+ >+ if (needsOSRBackwardRewiring(node->op())) { >+ node = node->child1().node(); >+ if (tryToSetConstantExitArgument(exit, index, node)) >+ return; >+ if (isLive(node)) >+ found = true; >+ } >+ >+ if (!found) { >+ Node* int32ToDouble = 0; >+ Node* valueToInt32 = 0; >+ Node* uint32ToNumber = 0; >+ Node* doubleAsInt32 = 0; >+ >+ HashMap<Node*, unsigned>::iterator iter = m_timeToLive.begin(); >+ HashMap<Node*, unsigned>::iterator end = m_timeToLive.end(); >+ for (; iter != end; ++iter) { >+ if (!iter->value) >+ continue; >+ Node* candidate = iter->key; >+ if (!candidate->child1()) >+ continue; >+ if (candidate->child1() != node) >+ continue; >+ switch (candidate->op()) { >+ case Int32ToDouble: >+ case ForwardInt32ToDouble: >+ int32ToDouble = candidate; >+ break; >+ case ValueToInt32: >+ valueToInt32 = candidate; >+ break; >+ case UInt32ToNumber: >+ uint32ToNumber = candidate; >+ break; >+ case DoubleAsInt32: >+ uint32ToNumber = candidate; >+ break; >+ default: >+ ASSERT(!needsOSRForwardRewiring(candidate->op())); >+ break; >+ } >+ } >+ >+ if (doubleAsInt32) >+ node = doubleAsInt32; >+ else if (int32ToDouble) >+ node = int32ToDouble; >+ else if (valueToInt32) >+ node = valueToInt32; >+ else if (uint32ToNumber) >+ node = uint32ToNumber; >+ >+ if (isLive(node)) >+ found = true; >+ } >+ >+ if (!found) { >+ exit.m_values[index] = ExitValue::dead(); >+ return; >+ } >+ } >+ >+ ASSERT(isLive(node)); >+ >+ if (LValue result = m_int32Values.get(node)) { >+ addExitArgument(exit, arguments, index, ValueFormatInt32, result); >+ return; >+ } >+ >+ if (LValue result = m_booleanValues.get(node)) { >+ addExitArgument(exit, arguments, index, ValueFormatBoolean, result); >+ return; >+ } >+ >+ if (LValue result = m_jsValueValues.get(node)) { >+ addExitArgument(exit, arguments, index, ValueFormatJSValue, result); >+ return; >+ } >+ >+ // FIXME: Implement doubles in the FTL. >+ // https://bugs.webkit.org/show_bug.cgi?id=113624 >+ RELEASE_ASSERT_NOT_REACHED(); >+ } >+ >+ bool tryToSetConstantExitArgument(OSRExit& exit, unsigned index, Node* node) >+ { >+ if (!node) >+ return false; >+ >+ switch (node->op()) { >+ case JSConstant: >+ case WeakJSConstant: >+ exit.m_values[index] = ExitValue::constant(m_graph.valueOfJSConstant(node)); >+ return true; >+ case PhantomArguments: >+ // FIXME: implement PhantomArguments. >+ // https://bugs.webkit.org/show_bug.cgi?id=113986 >+ RELEASE_ASSERT_NOT_REACHED(); >+ return true; >+ default: >+ return false; >+ } >+ } >+ >+ void addExitArgument( >+ OSRExit& exit, ExitArgumentList& arguments, unsigned index, ValueFormat format, >+ LValue value) >+ { >+ exit.m_values[index] = ExitValue::exitArgument(ExitArgument(format, arguments.size())); >+ arguments.append(value); >+ } >+ >+ void linkOSRExitsAndCompleteInitializationBlock() >+ { >+ MacroAssemblerCodeRef osrExitThunk = >+ globalData().getCTIStub(osrExitGenerationThunkGenerator); >+ CodeLocationLabel target = CodeLocationLabel(osrExitThunk.code()); >+ >+ m_out.appendTo(m_initialization); >+ >+ LinkBuffer linkBuffer( >+ globalData(), &m_exitThunkGenerator, m_ftlState.graph.m_codeBlock, >+ JITCompilationMustSucceed); >+ >+ ASSERT(m_ftlState.osrExit.size() == m_ftlState.jitCode->osrExit.size()); >+ >+ for (unsigned i = 0; i < m_ftlState.osrExit.size(); ++i) { >+ OSRExitCompilationInfo& info = m_ftlState.osrExit[i]; >+ OSRExit& exit = m_ftlState.jitCode->osrExit[i]; >+ >+ linkBuffer.link(info.m_thunkJump, target); >+ >+ m_out.set( >+ m_out.constIntPtr( >+ linkBuffer.locationOf(info.m_thunkLabel).executableAddress()), >+ info.m_thunkAddress); >+ >+ exit.m_patchableCodeOffset = linkBuffer.offsetOf(info.m_thunkJump); >+ } >+ >+ m_ftlState.jitCode->initializeExitThunks( >+ FINALIZE_DFG_CODE( >+ linkBuffer, >+ ("FTL exit thunks for %s", toCString(CodeBlockWithJITType(m_ftlState.graph.m_codeBlock,JITCode::FTLJIT)).data()))); >+ >+ m_out.jump(m_blocks.get(m_graph.m_blocks[0].get())); >+ } >+ >+ void observeMovHint(Node* node) >+ { >+ ASSERT(node->containsMovHint()); >+ ASSERT(node->op() != ZombieHint); >+ >+ int operand = node->local(); >+ >+ m_lastSetOperand = operand; >+ m_valueSources[operand] = ValueSource(node->child1().node()); >+ } >+ > void addWeakReference(JSCell* target) > { > m_ftlState.jitCode->common.weakReferences.append( >@@ -1151,12 +1557,12 @@ private: > Output m_out; > > LBasicBlock m_prologue; >+ LBasicBlock m_initialization; > HashMap<BasicBlock*, LBasicBlock> m_blocks; > > LValue m_callFrame; > LValue m_tagTypeNumber; > LValue m_tagMask; >- LValue m_abortFunction; > > HashSet<Node*> m_flushedLocalOps; > Vector<Node*> m_flushedLocalOpWorklist; >@@ -1165,15 +1571,21 @@ private: > HashMap<Node*, LValue> m_jsValueValues; > HashMap<Node*, LValue> m_booleanValues; > HashMap<Node*, LValue> m_storageValues; >+ HashMap<Node*, unsigned> m_timeToLive; > > Operands<LValue> m_localsBoolean; > Operands<LValue> m_locals32; > Operands<LValue> m_locals64; > >+ Operands<ValueSource> m_valueSources; >+ int m_lastSetOperand; >+ ExitThunkGenerator m_exitThunkGenerator; >+ > AbstractState m_state; > BasicBlock* m_highBlock; > BasicBlock* m_nextHighBlock; > LBasicBlock m_nextLowBlock; >+ unsigned m_nodeIndex; > Node* m_node; > SpeculationDirection m_direction; > }; >Index: Source/JavaScriptCore/ftl/FTLOSRExit.cpp >=================================================================== >--- Source/JavaScriptCore/ftl/FTLOSRExit.cpp (revision 0) >+++ Source/JavaScriptCore/ftl/FTLOSRExit.cpp (working copy) >@@ -0,0 +1,103 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "FTLOSRExit.h" >+ >+#if ENABLE(FTL_JIT) >+ >+#include "CodeBlock.h" >+#include "DFGBasicBlock.h" >+#include "DFGNode.h" >+#include "FTLExitArgument.h" >+#include "FTLExitArgumentList.h" >+#include "FTLJITCode.h" >+#include "Operations.h" >+ >+namespace JSC { namespace FTL { >+ >+using namespace DFG; >+ >+OSRExit::OSRExit( >+ ExitKind exitKind, ValueFormat profileValueFormat, >+ MethodOfGettingAValueProfile valueProfile, CodeOrigin codeOrigin, >+ int lastSetOperand, unsigned numberOfArguments, unsigned numberOfLocals) >+ : OSRExitBase(exitKind, codeOrigin) >+ , m_profileValueFormat(profileValueFormat) >+ , m_valueProfile(valueProfile) >+ , m_patchableCodeOffset(0) >+ , m_lastSetOperand(lastSetOperand) >+ , m_values(numberOfArguments, numberOfLocals) >+{ >+} >+ >+CodeLocationJump OSRExit::codeLocationForRepatch(CodeBlock* ftlCodeBlock) const >+{ >+ return CodeLocationJump( >+ reinterpret_cast<char*>( >+ ftlCodeBlock->getJITCode()->ftl()->exitThunks().dataLocation()) + >+ m_patchableCodeOffset); >+} >+ >+void OSRExit::convertToForward( >+ BasicBlock* block, Node* currentNode, unsigned nodeIndex, >+ const FormattedValue &value, ExitArgumentList& arguments) >+{ >+ Node* node; >+ Node* lastMovHint; >+ if (!doSearchForForwardConversion(block, currentNode, nodeIndex, !!value, node, lastMovHint)) >+ return; >+ >+ ASSERT(node->codeOrigin != currentNode->codeOrigin); >+ >+ m_codeOrigin = node->codeOrigin; >+ >+ if (!value) >+ return; >+ >+ int overriddenOperand = lastMovHint->local(); >+ m_lastSetOperand = overriddenOperand; >+ >+ // Is the value for this operand being passed as an argument to the exit, or is >+ // it something else? If it's an argument already, then replace that argument; >+ // otherwise add another argument. >+ if (m_values[overriddenOperand].isArgument()) { >+ ExitArgument exitArgument = m_values[overriddenOperand].exitArgument(); >+ arguments[exitArgument.argument()] = value.value(); >+ m_values[overriddenOperand] = ExitValue::exitArgument( >+ exitArgument.withFormat(value.format())); >+ return; >+ } >+ >+ unsigned argument = arguments.size(); >+ arguments.append(value.value()); >+ m_values[m_lastSetOperand] = ExitValue::exitArgument( >+ ExitArgument(value.format(), argument)); >+} >+ >+} } // namespace JSC::FTL >+ >+#endif // ENABLE(FTL_JIT) >+ >Index: Source/JavaScriptCore/ftl/FTLOSRExit.h >=================================================================== >--- Source/JavaScriptCore/ftl/FTLOSRExit.h (revision 0) >+++ Source/JavaScriptCore/ftl/FTLOSRExit.h (working copy) >@@ -0,0 +1,179 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#ifndef FTLOSRExit_h >+#define FTLOSRExit_h >+ >+#include <wtf/Platform.h> >+ >+#if ENABLE(FTL_JIT) >+ >+#include "CodeOrigin.h" >+#include "DFGExitProfile.h" >+#include "DFGOSRExitBase.h" >+#include "FTLAbbreviations.h" >+#include "FTLExitArgumentList.h" >+#include "FTLExitValue.h" >+#include "FTLFormattedValue.h" >+#include "MethodOfGettingAValueProfile.h" >+#include "Operands.h" >+#include "ValueProfile.h" >+ >+namespace JSC { namespace FTL { >+ >+// Tracks one OSR exit site within the FTL JIT. OSR exit in FTL works by deconstructing >+// the crazy that is OSR down to simple SSA CFG primitives that any compiler backend >+// (including of course LLVM) can grok and do meaningful things to. Except for >+// watchpoint-based exits, which haven't yet been implemented (see webkit.org/b/113647), >+// an exit is just a conditional branch in the emitted code where one destination is the >+// continuation and the other is a basic block that performs a no-return tail-call to an >+// exit thunk. This thunk takes as its arguments the live non-constant >+// not-already-accounted-for bytecode state. To appreciate how this works consider the >+// following JavaScript program, and its lowering down to LLVM IR including the relevant >+// exits: >+// >+// function foo(o) { >+// var a = o.a; // predicted int >+// var b = o.b; >+// var c = o.c; // NB this is dead >+// a = a | 5; // our example OSR exit: need to check if a is an int >+// return a + b; >+// } >+// >+// Just consider the "a | 5". In the DFG IR, this looks like: >+// >+// BitOr(Check:Int32:@a, Int32:5) >+// >+// Where @a is the node for the GetLocal node that gets the value of the 'a' variable. >+// Conceptually, this node can be further broken down to the following (note that this >+// particular lowering never actually happens - we skip this step and go straight to >+// LLVM IR - but it's still useful to see this): >+// >+// exitIf(@a is not int32); >+// continuation; >+// >+// Where 'exitIf()' is a function that will exit if the argument is true, and >+// 'continuation' is the stuff that we will do after the exitIf() check. (Note that >+// FTL refers to 'exitIf()' as 'speculate()', which is in line with DFG terminology.) >+// This then gets broken down to the following LLVM IR, assuming that %0 is the LLVM >+// value corresponding to variable 'a', and %1 is the LLVM value for variable 'b': >+// >+// %2 = ... // the predictate corresponding to '@a is not int32' >+// br i1 %2, label %3, label %4 >+// ; <label>:3 >+// call void exitThunk1(%0, %1) // pass 'a' and 'b', since they're both live-in-bytecode >+// unreachable >+// ; <label>:4 >+// ... // code for the continuation >+// >+// Where 'exitThunk1' is the IR to get the exit thunk for *this* OSR exit. Each OSR >+// exit will appear to LLVM to have a distinct exit thunk. >+// >+// Note that this didn't have to pass '5', 'o', or 'c' to the exit thunk. 5 is a >+// constant and the DFG already knows that, and can already tell the OSR exit machinery >+// what that contant is and which bytecode variables (if any) it needs to be dropped >+// into. This is conveyed to the exit statically, via the OSRExit data structure below. >+// See the code for ExitValue for details. 'o' is an argument, and arguments are always >+// "flushed" - if you never assign them then their values are still in the argument >+// stack slots, and if you do assign them then we eagerly store them into those slots. >+// 'c' is dead in bytecode, and the DFG knows this; we statically tell the exit thunk >+// that it's dead and don't have to pass anything. The exit thunk will "initialize" its >+// value to Undefined. >+// >+// This approach to OSR exit has a number of virtues: >+// >+// - It is an entirely unsurprising representation for a compiler that already groks >+// CFG-like IRs for C-like languages. All existing analyses and transformations just >+// work. >+// >+// - It lends itself naturally to modern approaches to code motion. For example, you >+// could sink operations from above the exit to below it, if you just duplicate the >+// operation into the OSR exit block. This is both legal and desirable. It works >+// because the backend sees the OSR exit block as being no different than any other, >+// and LLVM already supports sinking if it sees that a value is only partially used. >+// Hence there exists a value that dominates the exit but is only used by the exit >+// thunk and not by the continuation, sinking ought to kick in for that value. >+// Hoisting operations from below it to above it is also possible, for similar >+// reasons. >+// >+// - The no-return tail-call to the OSR exit thunk can be subjected to specialized >+// code-size reduction optimizations, though this is optional. For example, instead >+// of actually emitting a call along with all that goes with it (like placing the >+// arguments into argument position), the backend could choose to simply inform us >+// where it had placed the arguments and expect the callee (i.e. the exit thunk) to >+// figure it out from there. It could also tell us what we need to do to pop stack, >+// although again, it doesn't have to; it could just emit that code normally. Though >+// we don't support this yet, we could; the only thing that would change on our end >+// is that we'd need feedback from the backend about the location of the arguments >+// and a description of the things that need to be done to pop stack. This would >+// involve switching the m_values array to use something more akin to ValueRecovery >+// rather than the current ExitValue, albeit possibly with some hacks to better >+// understand the kinds of places where the LLVM backend would put values. >+// >+// - It could be extended to allow the backend to do its own exit hoisting, by using >+// intrinsics (or meta-data, or something) to inform the backend that it's safe to >+// make the predicate passed to 'exitIf()' more truthy. >+// >+// - It could be extended to support watchpoints (see webkit.org/b/113647) by making >+// the predicate passed to 'exitIf()' be an intrinsic that the backend knows to be >+// true at compile-time. The backend could then turn the conditional branch into a >+// replaceable jump, much like the DFG does. >+ >+struct OSRExit : public DFG::OSRExitBase { >+ OSRExit( >+ ExitKind, ValueFormat profileValueFormat, MethodOfGettingAValueProfile, >+ CodeOrigin, int lastSetOperand, unsigned numberOfArguments, >+ unsigned numberOfLocals); >+ >+ MacroAssemblerCodeRef m_code; >+ >+ // The first argument to the exit call may be a value we wish to profile. >+ // If that's the case, the format will be not Invalid and we'll have a >+ // method of getting a value profile. Note that all of the ExitArgument's >+ // are already aware of this possible off-by-one, so there is no need to >+ // correct them. >+ ValueFormat m_profileValueFormat; >+ MethodOfGettingAValueProfile m_valueProfile; >+ >+ // Offset within the exit stubs of the stub for this exit. >+ unsigned m_patchableCodeOffset; >+ >+ int m_lastSetOperand; >+ >+ Operands<ExitValue> m_values; >+ >+ CodeLocationJump codeLocationForRepatch(CodeBlock* ftlCodeBlock) const; >+ >+ void convertToForward( >+ DFG::BasicBlock*, DFG::Node* currentNode, unsigned nodeIndex, >+ const FormattedValue&, ExitArgumentList& arguments); >+}; >+ >+} } // namespace JSC::FTL >+ >+#endif // ENABLE(FTL_JIT) >+ >+#endif // FTLOSRExit_h >+ >Index: Source/JavaScriptCore/ftl/FTLOSRExitCompilationInfo.h >=================================================================== >--- Source/JavaScriptCore/ftl/FTLOSRExitCompilationInfo.h (revision 0) >+++ Source/JavaScriptCore/ftl/FTLOSRExitCompilationInfo.h (working copy) >@@ -0,0 +1,54 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#ifndef FTLOSRExitCompilationInfo_h >+#define FTLOSRExitCompilationInfo_h >+ >+#include <wtf/Platform.h> >+ >+#if ENABLE(FTL_JIT) >+ >+#include "FTLAbbreviations.h" >+#include "MacroAssembler.h" >+ >+namespace JSC { namespace FTL { >+ >+struct OSRExitCompilationInfo { >+ OSRExitCompilationInfo() >+ : m_thunkAddress(0) >+ { >+ } >+ >+ MacroAssembler::Label m_thunkLabel; >+ MacroAssembler::PatchableJump m_thunkJump; >+ LValue m_thunkAddress; >+}; >+ >+} } // namespace JSC::FTL >+ >+#endif // ENABLE(FTL_JIT) >+ >+#endif // FTLOSRExitCompilationInfo_h >+ >Index: Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp >=================================================================== >--- Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp (revision 0) >+++ Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp (working copy) >@@ -0,0 +1,192 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "FTLOSRExitCompiler.h" >+ >+#if ENABLE(FTL_JIT) >+ >+#include "DFGOSRExitCompilerCommon.h" >+#include "DFGOSRExitPreparation.h" >+#include "FTLCArgumentGetter.h" >+#include "FTLExitArgumentForOperand.h" >+#include "FTLJITCode.h" >+#include "FTLOSRExit.h" >+#include "RepatchBuffer.h" >+ >+namespace JSC { namespace FTL { >+ >+using namespace DFG; >+ >+static void compileStub( >+ unsigned exitID, OSRExit& exit, JSGlobalData* globalData, CodeBlock* codeBlock) >+{ >+ CCallHelpers jit(globalData, codeBlock); >+ >+ // This is actually fairly easy, even though it is horribly gross. We know that >+ // LLVM would have passes us all of the state via arguments. We know how to get >+ // the arguments. And, we know how to pop stack back to the JIT stack frame, sort >+ // of: we know that it's two frames beneath us. This is terrible and I feel >+ // ashamed of it, but it will work for now. >+ >+ CArgumentGetter arguments(jit); >+ >+ // First recover our call frame and tag thingies. >+ arguments.loadNextPtr(GPRInfo::callFrameRegister); >+ jit.move(MacroAssembler::TrustedImm64(TagTypeNumber), GPRInfo::tagTypeNumberRegister); >+ jit.move(MacroAssembler::TrustedImm64(TagMask), GPRInfo::tagMaskRegister); >+ >+ // Do some value profiling. >+ if (exit.m_profileValueFormat != InvalidValueFormat) { >+ arguments.loadNextAndBox(exit.m_profileValueFormat, GPRInfo::nonArgGPR0); >+ >+ if (exit.m_kind == BadCache || exit.m_kind == BadIndexingType) { >+ CodeOrigin codeOrigin = exit.m_codeOriginForExitProfile; >+ if (ArrayProfile* arrayProfile = jit.baselineCodeBlockFor(codeOrigin)->getArrayProfile(codeOrigin.bytecodeIndex)) { >+ jit.loadPtr(MacroAssembler::Address(GPRInfo::nonArgGPR0, JSCell::structureOffset()), GPRInfo::nonArgGPR1); >+ jit.storePtr(GPRInfo::nonArgGPR1, arrayProfile->addressOfLastSeenStructure()); >+ jit.load8(MacroAssembler::Address(GPRInfo::nonArgGPR1, Structure::indexingTypeOffset()), GPRInfo::nonArgGPR1); >+ jit.move(MacroAssembler::TrustedImm32(1), GPRInfo::nonArgGPR2); >+ jit.lshift32(GPRInfo::nonArgGPR1, GPRInfo::nonArgGPR2); >+ jit.or32(GPRInfo::nonArgGPR2, MacroAssembler::AbsoluteAddress(arrayProfile->addressOfArrayModes())); >+ } >+ } >+ >+ if (!!exit.m_valueProfile) >+ jit.store64(GPRInfo::nonArgGPR0, exit.m_valueProfile.getSpecFailBucket(0)); >+ } >+ >+ // Start by dumping all argument exit values to the stack. >+ >+ Vector<ExitArgumentForOperand, 16> sortedArguments; >+ for (unsigned i = exit.m_values.size(); i--;) { >+ ExitValue value = exit.m_values[i]; >+ int operand = exit.m_values.operandForIndex(i); >+ >+ if (!value.isArgument()) >+ continue; >+ >+ sortedArguments.append(ExitArgumentForOperand(value.exitArgument(), operand)); >+ } >+ std::sort(sortedArguments.begin(), sortedArguments.end(), lesserArgumentIndex); >+ >+ for (unsigned i = 0; i < sortedArguments.size(); ++i) { >+ ExitArgumentForOperand argument = sortedArguments[i]; >+ >+ arguments.loadNextAndBox(argument.exitArgument().format(), GPRInfo::nonArgGPR0); >+ jit.store64(GPRInfo::nonArgGPR0, AssemblyHelpers::addressFor(argument.operand())); >+ } >+ >+ // Box anything that is already on the stack, or that is a constant. >+ >+ for (unsigned i = exit.m_values.size(); i--;) { >+ ExitValue value = exit.m_values[i]; >+ int operand = exit.m_values.operandForIndex(i); >+ >+ MacroAssembler::Address address = AssemblyHelpers::addressFor(operand); >+ >+ switch (value.kind()) { >+ case ExitValueDead: >+ jit.store64(MacroAssembler::TrustedImm64(JSValue::encode(jsUndefined())), address); >+ break; >+ case ExitValueConstant: >+ jit.store64(MacroAssembler::TrustedImm64(JSValue::encode(value.constant())), address); >+ break; >+ case ExitValueInJSStack: >+ break; >+ case ExitValueInJSStackAsInt32: >+ jit.load32( >+ address.withOffset(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), >+ GPRInfo::regT0); >+ jit.or64(GPRInfo::tagTypeNumberRegister, GPRInfo::regT0); >+ jit.store64(GPRInfo::regT0, address); >+ break; >+ case ExitValueInJSStackAsDouble: >+ jit.loadDouble(address, FPRInfo::fpRegT0); >+ jit.boxDouble(FPRInfo::fpRegT0, GPRInfo::regT0); >+ jit.store64(GPRInfo::regT0, address); >+ break; >+ case ExitValueArgument: >+ break; >+ default: >+ RELEASE_ASSERT_NOT_REACHED(); >+ break; >+ } >+ } >+ >+ handleExitCounts(jit, exit); >+ reifyInlinedCallFrames(jit, exit); >+ >+ // Adjust the C stack. The frame pointer should at this point still hold the pointer >+ // to the frame of the LLVM-generated code. >+ >+ jit.move(MacroAssembler::framePointerRegister, MacroAssembler::stackPointerRegister); >+ jit.pop(MacroAssembler::framePointerRegister); >+ jit.pop(GPRInfo::nonArgGPR0); // ignore the result. >+ >+ if (exit.m_lastSetOperand != std::numeric_limits<int>::max()) { >+ jit.load64( >+ AssemblyHelpers::addressFor(exit.m_lastSetOperand), GPRInfo::cachedResultRegister); >+ } >+ >+ adjustAndJumpToTarget(jit, exit); >+ >+ LinkBuffer patchBuffer(*globalData, &jit, codeBlock); >+ exit.m_code = FINALIZE_CODE_IF( >+ shouldShowDisassembly(), >+ patchBuffer, >+ ("FTL OSR exit #%u (bc#%u, %s) from %s", >+ exitID, exit.m_codeOrigin.bytecodeIndex, >+ exitKindToString(exit.m_kind), toCString(*codeBlock).data())); >+} >+ >+extern "C" void* compileFTLOSRExit(ExecState* exec, unsigned exitID) >+{ >+ SamplingRegion samplingRegion("FTL OSR Exit Compilation"); >+ >+ CodeBlock* codeBlock = exec->codeBlock(); >+ >+ ASSERT(codeBlock); >+ ASSERT(codeBlock->getJITType() == JITCode::FTLJIT); >+ >+ JSGlobalData* globalData = &exec->globalData(); >+ >+ OSRExit& exit = codeBlock->getJITCode()->ftl()->osrExit[exitID]; >+ >+ prepareCodeOriginForOSRExit(exec, exit.m_codeOrigin); >+ >+ compileStub(exitID, exit, globalData, codeBlock); >+ >+ RepatchBuffer repatchBuffer(codeBlock); >+ repatchBuffer.relink( >+ exit.codeLocationForRepatch(codeBlock), CodeLocationLabel(exit.m_code.code())); >+ >+ return exit.m_code.code().executableAddress(); >+} >+ >+} } // namespace JSC::FTL >+ >+#endif // ENABLE(FTL_JIT) >+ >Index: Source/JavaScriptCore/ftl/FTLOSRExitCompiler.h >=================================================================== >--- Source/JavaScriptCore/ftl/FTLOSRExitCompiler.h (revision 0) >+++ Source/JavaScriptCore/ftl/FTLOSRExitCompiler.h (working copy) >@@ -0,0 +1,48 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#ifndef FTLOSRExitCompiler_h >+#define FTLOSRExitCompiler_h >+ >+#include <wtf/Platform.h> >+ >+#if ENABLE(FTL_JIT) >+ >+#include "DFGOperations.h" >+ >+namespace JSC { namespace FTL { >+ >+// Takes the call frame and the index of the exit, and returns the address to >+// jump to. >+extern "C" { >+void* DFG_OPERATION compileFTLOSRExit(ExecState*, unsigned exitID) WTF_INTERNAL; >+} >+ >+} } // namespace JSC::FTL >+ >+#endif // ENABLE(FTL_JIT) >+ >+#endif // FTLOSRExitCompiler_h >+ >Index: Source/JavaScriptCore/ftl/FTLOutput.h >=================================================================== >--- Source/JavaScriptCore/ftl/FTLOutput.h (revision 148047) >+++ Source/JavaScriptCore/ftl/FTLOutput.h (working copy) >@@ -135,19 +135,20 @@ public: > LValue zeroExt(LValue value, LType type) { return buildZExt(m_builder, value, type); } > LValue intCast(LValue value, LType type) { return buildIntCast(m_builder, value, type); } > LValue castToInt32(LValue value) { return intCast(value, int32); } >+ LValue intToPtr(LValue value, LType type) { return buildIntToPtr(m_builder, value, type); } > > LValue get(LValue reference) { return buildLoad(m_builder, reference); } > LValue set(LValue value, LValue reference) { return buildStore(m_builder, value, reference); } > > LValue load(TypedPointer pointer, LType refType) > { >- LValue result = get(buildIntToPtr(m_builder, pointer.value(), refType)); >+ LValue result = get(intToPtr(pointer.value(), refType)); > pointer.heap().decorateInstruction(result, *m_heaps); > return result; > } > void store(LValue value, TypedPointer pointer, LType refType) > { >- LValue result = set(value, buildIntToPtr(m_builder, pointer.value(), refType)); >+ LValue result = set(value, intToPtr(pointer.value(), refType)); > pointer.heap().decorateInstruction(result, *m_heaps); > } > >@@ -244,10 +245,18 @@ public: > LValue select(LValue value, LValue taken, LValue notTaken) { return buildSelect(m_builder, value, taken, notTaken); } > LValue extractValue(LValue aggVal, unsigned index) { return buildExtractValue(m_builder, aggVal, index); } > >+ template<typename VectorType> >+ LValue call(LValue function, const VectorType& vector) { return buildCall(m_builder, function, vector); } > LValue call(LValue function) { return buildCall(m_builder, function); } > LValue call(LValue function, LValue arg1) { return buildCall(m_builder, function, arg1); } > LValue call(LValue function, LValue arg1, LValue arg2) { return buildCall(m_builder, function, arg1, arg2); } > >+ LValue convertToTailCall(LValue call) >+ { >+ setTailCall(call, IsTailCall); >+ return call; >+ } >+ > void jump(LBasicBlock destination) { buildBr(m_builder, destination); } > void branch(LValue condition, LBasicBlock taken, LBasicBlock notTaken) { buildCondBr(m_builder, condition, taken, notTaken); } > void ret(LValue value) { buildRet(m_builder, value); } >Index: Source/JavaScriptCore/ftl/FTLState.h >=================================================================== >--- Source/JavaScriptCore/ftl/FTLState.h (revision 148047) >+++ Source/JavaScriptCore/ftl/FTLState.h (working copy) >@@ -33,6 +33,7 @@ > #include "DFGGraph.h" > #include "FTLAbbreviations.h" > #include "FTLJITCode.h" >+#include "FTLOSRExitCompilationInfo.h" > #include <wtf/Noncopyable.h> > > namespace JSC { namespace FTL { >@@ -49,6 +50,7 @@ public: > LModule module; > LValue function; > RefPtr<JITCode> jitCode; >+ Vector<OSRExitCompilationInfo> osrExit; > > void dumpState(const char* when); > }; >Index: Source/JavaScriptCore/ftl/FTLThunks.cpp >=================================================================== >--- Source/JavaScriptCore/ftl/FTLThunks.cpp (revision 0) >+++ Source/JavaScriptCore/ftl/FTLThunks.cpp (working copy) >@@ -0,0 +1,84 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "FTLThunks.h" >+ >+#if ENABLE(FTL_JIT) >+ >+#include "DFGGPRInfo.h" >+#include "DFGFPRInfo.h" >+#include "FTLOSRExitCompiler.h" >+#include "LinkBuffer.h" >+#include "MacroAssembler.h" >+ >+namespace JSC { namespace FTL { >+ >+using namespace DFG; >+ >+MacroAssemblerCodeRef osrExitGenerationThunkGenerator(JSGlobalData* globalData) >+{ >+ MacroAssembler jit; >+ >+ size_t scratchSize = sizeof(EncodedJSValue) * (GPRInfo::numberOfArgumentRegisters + FPRInfo::numberOfArgumentRegisters); >+ ScratchBuffer* scratchBuffer = globalData->scratchBufferForSize(scratchSize); >+ EncodedJSValue* buffer = static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()); >+ >+ for (unsigned i = 0; i < GPRInfo::numberOfArgumentRegisters; ++i) >+ jit.store64(GPRInfo::toArgumentRegister(i), buffer + i); >+ for (unsigned i = 0; i < FPRInfo::numberOfArgumentRegisters; ++i) { >+ jit.move(MacroAssembler::TrustedImmPtr(buffer + GPRInfo::numberOfArgumentRegisters + i), GPRInfo::nonArgGPR1); >+ jit.storeDouble(FPRInfo::toArgumentRegister(i), GPRInfo::nonArgGPR1); >+ } >+ >+ // Tell GC mark phase how much of the scratch buffer is active during call. >+ jit.move(MacroAssembler::TrustedImmPtr(scratchBuffer->activeLengthPtr()), GPRInfo::nonArgGPR1); >+ jit.storePtr(MacroAssembler::TrustedImmPtr(scratchSize), GPRInfo::nonArgGPR1); >+ >+ // argument 0 is already the call frame. >+ jit.move(GPRInfo::nonArgGPR0, GPRInfo::argumentGPR1); >+ MacroAssembler::Call functionCall = jit.call(); >+ >+ jit.move(MacroAssembler::TrustedImmPtr(scratchBuffer->activeLengthPtr()), GPRInfo::nonPreservedNonReturnGPR); >+ jit.storePtr(MacroAssembler::TrustedImmPtr(0), GPRInfo::nonPreservedNonReturnGPR); >+ >+ for (unsigned i = 0; i < FPRInfo::numberOfArgumentRegisters; ++i) { >+ jit.move(MacroAssembler::TrustedImmPtr(buffer + GPRInfo::numberOfArgumentRegisters + i), GPRInfo::nonPreservedNonReturnGPR); >+ jit.loadDouble(GPRInfo::nonPreservedNonReturnGPR, FPRInfo::toArgumentRegister(i)); >+ } >+ for (unsigned i = 0; i < GPRInfo::numberOfArgumentRegisters; ++i) >+ jit.load64(buffer + i, GPRInfo::toArgumentRegister(i)); >+ >+ jit.jump(GPRInfo::returnValueGPR); >+ >+ LinkBuffer patchBuffer(*globalData, &jit, GLOBAL_THUNK_ID); >+ patchBuffer.link(functionCall, compileFTLOSRExit); >+ return FINALIZE_CODE(patchBuffer, ("FTL OSR exit generation thunk")); >+} >+ >+} } // namespace JSC::FTL >+ >+#endif // ENABLE(FTL_JIT) >+ >Index: Source/JavaScriptCore/ftl/FTLThunks.h >=================================================================== >--- Source/JavaScriptCore/ftl/FTLThunks.h (revision 0) >+++ Source/JavaScriptCore/ftl/FTLThunks.h (working copy) >@@ -0,0 +1,47 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#ifndef FTLThunks_h >+#define FTLThunks_h >+ >+#include <wtf/Platform.h> >+ >+#if ENABLE(FTL_JIT) >+ >+#include "MacroAssemblerCodeRef.h" >+ >+namespace JSC { >+ >+class JSGlobalData; >+ >+namespace FTL { >+ >+MacroAssemblerCodeRef osrExitGenerationThunkGenerator(JSGlobalData*); >+ >+} } // namespace JSC::FTL >+ >+#endif // ENABLE(FTL_JIT) >+ >+#endif // FTLTHunks_h >Index: Source/JavaScriptCore/ftl/FTLValueFormat.cpp >=================================================================== >--- Source/JavaScriptCore/ftl/FTLValueFormat.cpp (revision 0) >+++ Source/JavaScriptCore/ftl/FTLValueFormat.cpp (working copy) >@@ -0,0 +1,64 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "FTLValueFormat.h" >+ >+#if ENABLE(FTL_JIT) >+ >+namespace WTF { >+ >+using namespace JSC::FTL; >+ >+void printInternal(PrintStream& out, ValueFormat format) >+{ >+ switch (format) { >+ case InvalidValueFormat: >+ out.print("Invalid"); >+ return; >+ case ValueFormatInt32: >+ out.print("Int32"); >+ return; >+ case ValueFormatUInt32: >+ out.print("UInt32"); >+ return; >+ case ValueFormatBoolean: >+ out.print("Boolean"); >+ return; >+ case ValueFormatJSValue: >+ out.print("JSValue"); >+ return; >+ case ValueFormatDouble: >+ out.print("Double"); >+ return; >+ } >+ >+ RELEASE_ASSERT_NOT_REACHED(); >+} >+ >+} // namespace WTF >+ >+#endif // ENABLE(FTL_JIT) >+ >Index: Source/JavaScriptCore/ftl/FTLValueFormat.h >=================================================================== >--- Source/JavaScriptCore/ftl/FTLValueFormat.h (revision 0) >+++ Source/JavaScriptCore/ftl/FTLValueFormat.h (working copy) >@@ -0,0 +1,60 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#ifndef FTLValueFormat_h >+#define FTLValueFormat_h >+ >+#include <wtf/Platform.h> >+ >+#if ENABLE(FTL_JIT) >+ >+#include <wtf/PrintStream.h> >+ >+namespace JSC { namespace FTL { >+ >+// Note that this is awkwardly similar to DataFormat in other parts of JSC, except that >+// unlike DataFormat and like ValueRecovery, it distinguishes between UInt32 and Int32. >+ >+enum ValueFormat { >+ InvalidValueFormat, >+ ValueFormatInt32, >+ ValueFormatUInt32, >+ ValueFormatBoolean, >+ ValueFormatJSValue, >+ ValueFormatDouble >+}; >+ >+} } // namespace JSC::FTL >+ >+namespace WTF { >+ >+void printInternal(PrintStream&, JSC::FTL::ValueFormat); >+ >+} // namespace WTF >+ >+#endif // ENABLE(FTL_JIT) >+ >+#endif // FTLValueFormat_h >+ >Index: Source/JavaScriptCore/ftl/FTLValueSource.cpp >=================================================================== >--- Source/JavaScriptCore/ftl/FTLValueSource.cpp (revision 0) >+++ Source/JavaScriptCore/ftl/FTLValueSource.cpp (working copy) >@@ -0,0 +1,77 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "FTLValueSource.h" >+ >+#if ENABLE(FTL_JIT) >+ >+namespace JSC { namespace FTL { >+ >+void ValueSource::dump(PrintStream& out) const >+{ >+ switch (kind()) { >+ case SourceNotSet: >+ out.print("SourceNotSet"); >+ return; >+ case ValueInJSStack: >+ out.print("ValueInJSStack"); >+ return; >+ case Int32InJSStack: >+ out.print("Int32InJSStack"); >+ return; >+ case DoubleInJSStack: >+ out.print("DoubleInJSStack"); >+ return; >+ case ValueInLocals: >+ out.print("ValueInLocals"); >+ return; >+ case Int32InLocals: >+ out.print("Int32InLocals"); >+ return; >+ case BooleanInLocals: >+ out.print("BooleanInLocals"); >+ return; >+ case DoubleInLocals: >+ out.print("DoubleInLocals"); >+ return; >+ case ArgumentsSource: >+ out.print("ArgumentsSource"); >+ return; >+ case SourceIsDead: >+ out.print("SourceIsDead"); >+ return; >+ case HaveNode: >+ out.print("Node(", node(), ")"); >+ return; >+ } >+ >+ RELEASE_ASSERT_NOT_REACHED(); >+} >+ >+} } // namespace JSC::FTL >+ >+#endif // ENABLE(FTL_JIT) >+ >Index: Source/JavaScriptCore/ftl/FTLValueSource.h >=================================================================== >--- Source/JavaScriptCore/ftl/FTLValueSource.h (revision 0) >+++ Source/JavaScriptCore/ftl/FTLValueSource.h (working copy) >@@ -0,0 +1,96 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#ifndef FTLValueSource_h >+#define FTLValueSource_h >+ >+#include <wtf/Platform.h> >+ >+#if ENABLE(FTL_JIT) >+ >+#include "DFGNode.h" >+#include <wtf/PrintStream.h> >+#include <wtf/StdLibExtras.h> >+ >+namespace JSC { namespace FTL { >+ >+enum ValueSourceKind { >+ SourceNotSet, >+ ValueInJSStack, >+ Int32InJSStack, >+ DoubleInJSStack, >+ ValueInLocals, >+ Int32InLocals, >+ BooleanInLocals, >+ DoubleInLocals, >+ ArgumentsSource, >+ SourceIsDead, >+ HaveNode >+}; >+ >+class ValueSource { >+public: >+ ValueSource() >+ : m_value(SourceNotSet) >+ { >+ } >+ >+ explicit ValueSource(ValueSourceKind kind) >+ : m_value(kind) >+ { >+ } >+ >+ explicit ValueSource(DFG::Node* node) >+ : m_value(bitwise_cast<uintptr_t>(node)) >+ { >+ } >+ >+ ValueSourceKind kind() const >+ { >+ if (m_value < static_cast<uintptr_t>(HaveNode)) >+ return static_cast<ValueSourceKind>(m_value); >+ return HaveNode; >+ } >+ >+ bool operator!() const { return kind() != SourceNotSet; } >+ >+ DFG::Node* node() const >+ { >+ ASSERT(kind() == HaveNode); >+ return bitwise_cast<DFG::Node*>(m_value); >+ } >+ >+ void dump(PrintStream&) const; >+ >+private: >+ uintptr_t m_value; >+}; >+ >+} } // namespace JSC::FTL >+ >+#endif // ENABLE(FTL_JIT) >+ >+#endif // FTLValueSource_h >+
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 113623
:
196508
|
196539
|
196562
|
196565
|
196700
|
196704
|
197166
|
197216
|
197373
|
197502
|
197706
|
197914
|
197920