Source/JavaScriptCore/ChangeLog

 12013-11-16 Filip Pizlo <fpizlo@apple.com>
 2
 3 FTL should have an explicit notion of bytecode liveness
 4 https://bugs.webkit.org/show_bug.cgi?id=124181
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 This makes FTL OSR exit use bytecode liveness analysis to determine which variables
 9 to include values for. The decision of how to get the values of variables is based on
 10 forward propagation of MovHints and SetLocals.
 11
 12 This fixes a bunch of bugs (like https://bugs.webkit.org/show_bug.cgi?id=124138 but
 13 also others that I noticed when I started writing more targetted tests) and allows us
 14 to remove some sketchy code.
 15
 16 * CMakeLists.txt:
 17 * GNUmakefile.list.am:
 18 * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
 19 * JavaScriptCore.xcodeproj/project.pbxproj:
 20 * bytecode/BytecodeBasicBlock.h:
 21 * bytecode/BytecodeLivenessAnalysis.cpp:
 22 (JSC::isValidRegisterForLiveness):
 23 (JSC::setForOperand):
 24 (JSC::computeUsesForBytecodeOffset):
 25 (JSC::computeDefsForBytecodeOffset):
 26 (JSC::stepOverInstruction):
 27 (JSC::computeLocalLivenessForBytecodeOffset):
 28 (JSC::BytecodeLivenessAnalysis::runLivenessFixpoint):
 29 (JSC::BytecodeLivenessAnalysis::operandIsLiveAtBytecodeOffset):
 30 (JSC::getLivenessInfo):
 31 (JSC::BytecodeLivenessAnalysis::getLivenessInfoAtBytecodeOffset):
 32 (JSC::BytecodeLivenessAnalysis::computeFullLiveness):
 33 * bytecode/BytecodeLivenessAnalysis.h:
 34 * bytecode/BytecodeLivenessAnalysisInlines.h: Added.
 35 (JSC::operandIsAlwaysLive):
 36 (JSC::operandThatIsNotAlwaysLiveIsLive):
 37 (JSC::operandIsLive):
 38 * bytecode/CodeBlock.h:
 39 (JSC::CodeBlock::captureCount):
 40 (JSC::CodeBlock::captureStart):
 41 (JSC::CodeBlock::captureEnd):
 42 * bytecode/CodeOrigin.cpp:
 43 (JSC::InlineCallFrame::dumpInContext):
 44 * bytecode/FullBytecodeLiveness.h: Added.
 45 (JSC::FullBytecodeLiveness::FullBytecodeLiveness):
 46 (JSC::FullBytecodeLiveness::getOut):
 47 (JSC::FullBytecodeLiveness::operandIsLive):
 48 (JSC::FullBytecodeLiveness::getLiveness):
 49 * dfg/DFGAvailability.cpp: Added.
 50 (JSC::DFG::Availability::dump):
 51 (JSC::DFG::Availability::dumpInContext):
 52 * dfg/DFGAvailability.h: Added.
 53 (JSC::DFG::Availability::Availability):
 54 (JSC::DFG::Availability::unavailable):
 55 (JSC::DFG::Availability::withFlush):
 56 (JSC::DFG::Availability::withNode):
 57 (JSC::DFG::Availability::withUnavailableNode):
 58 (JSC::DFG::Availability::nodeIsUndecided):
 59 (JSC::DFG::Availability::nodeIsUnavailable):
 60 (JSC::DFG::Availability::hasNode):
 61 (JSC::DFG::Availability::node):
 62 (JSC::DFG::Availability::flushedAt):
 63 (JSC::DFG::Availability::operator!):
 64 (JSC::DFG::Availability::operator==):
 65 (JSC::DFG::Availability::merge):
 66 (JSC::DFG::Availability::mergeNodes):
 67 (JSC::DFG::Availability::unavailableMarker):
 68 * dfg/DFGBasicBlock.h:
 69 * dfg/DFGByteCodeParser.cpp:
 70 (JSC::DFG::ByteCodeParser::parseBlock):
 71 * dfg/DFGDisassembler.cpp:
 72 (JSC::DFG::Disassembler::Disassembler):
 73 * dfg/DFGFlushFormat.cpp:
 74 (WTF::printInternal):
 75 * dfg/DFGFlushFormat.h:
 76 (JSC::DFG::resultFor):
 77 (JSC::DFG::useKindFor):
 78 (JSC::DFG::dataFormatFor):
 79 * dfg/DFGFlushedAt.cpp:
 80 (JSC::DFG::FlushedAt::dump):
 81 * dfg/DFGFlushedAt.h:
 82 (JSC::DFG::FlushedAt::FlushedAt):
 83 (JSC::DFG::FlushedAt::merge):
 84 * dfg/DFGGraph.cpp:
 85 (JSC::DFG::Graph::dump):
 86 (JSC::DFG::Graph::livenessFor):
 87 (JSC::DFG::Graph::isLiveInBytecode):
 88 * dfg/DFGGraph.h:
 89 (JSC::DFG::Graph::baselineCodeBlockFor):
 90 * dfg/DFGOSRAvailabilityAnalysisPhase.cpp:
 91 (JSC::DFG::OSRAvailabilityAnalysisPhase::run):
 92 * dfg/DFGOSRAvailabilityAnalysisPhase.h:
 93 * dfg/DFGPlan.cpp:
 94 (JSC::DFG::Plan::compileInThreadImpl):
 95 * dfg/DFGResurrectionForValidationPhase.cpp: Added.
 96 (JSC::DFG::ResurrectionForValidationPhase::ResurrectionForValidationPhase):
 97 (JSC::DFG::ResurrectionForValidationPhase::run):
 98 (JSC::DFG::performResurrectionForValidation):
 99 * dfg/DFGResurrectionForValidationPhase.h: Added.
 100 * dfg/DFGSSAConversionPhase.cpp:
 101 (JSC::DFG::SSAConversionPhase::run):
 102 * dfg/DFGValueSource.h:
 103 (JSC::DFG::ValueSource::forFlushFormat):
 104 * dfg/DFGVariableAccessData.h:
 105 * ftl/FTLExitValue.cpp:
 106 (JSC::FTL::ExitValue::dumpInContext):
 107 * ftl/FTLInlineCacheSize.cpp:
 108 (JSC::FTL::sizeOfGetById):
 109 * ftl/FTLLocation.cpp:
 110 (JSC::FTL::Location::gpr):
 111 (JSC::FTL::Location::fpr):
 112 (JSC::FTL::Location::directGPR):
 113 * ftl/FTLLowerDFGToLLVM.cpp:
 114 (JSC::FTL::LowerDFGToLLVM::LowerDFGToLLVM):
 115 (JSC::FTL::LowerDFGToLLVM::compileBlock):
 116 (JSC::FTL::LowerDFGToLLVM::compileNode):
 117 (JSC::FTL::LowerDFGToLLVM::compileSetLocal):
 118 (JSC::FTL::LowerDFGToLLVM::compileZombieHint):
 119 (JSC::FTL::LowerDFGToLLVM::compilePutById):
 120 (JSC::FTL::LowerDFGToLLVM::compileInvalidationPoint):
 121 (JSC::FTL::LowerDFGToLLVM::initializeOSRExitStateForBlock):
 122 (JSC::FTL::LowerDFGToLLVM::appendOSRExit):
 123 (JSC::FTL::LowerDFGToLLVM::emitOSRExitCall):
 124 (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
 125 (JSC::FTL::LowerDFGToLLVM::addExitArgumentForNode):
 126 (JSC::FTL::LowerDFGToLLVM::observeMovHint):
 127 * ftl/FTLOutput.h:
 128 (JSC::FTL::Output::alloca):
 129 * ftl/FTLValueSource.cpp: Removed.
 130 * ftl/FTLValueSource.h: Removed.
 131 * llvm/LLVMAPIFunctions.h:
 132 * runtime/DumpContext.cpp:
 133 (JSC::DumpContext::DumpContext):
 134 * runtime/DumpContext.h:
 135 * runtime/Options.h:
 136 * runtime/SymbolTable.h:
 137 (JSC::SharedSymbolTable::captureStart):
 138 (JSC::SharedSymbolTable::captureEnd):
 139 (JSC::SharedSymbolTable::captureCount):
 140
11412013-11-15 Alexey Proskuryakov <ap@apple.com>
2142
3143 Support exporting symmetric keys as JWK
159377

Source/JavaScriptCore/CMakeLists.txt

@@set(JavaScriptCore_SOURCES
9191 dfg/DFGArgumentsSimplificationPhase.cpp
9292 dfg/DFGArrayMode.cpp
9393 dfg/DFGAtTailAbstractState.cpp
 94 dfg/DFGAvailability.cpp
9495 dfg/DFGBackwardsPropagationPhase.cpp
9596 dfg/DFGBasicBlock.cpp
9697 dfg/DFGBinarySwitch.cpp

@@set(JavaScriptCore_SOURCES
158159 dfg/DFGPlan.cpp
159160 dfg/DFGPredictionInjectionPhase.cpp
160161 dfg/DFGPredictionPropagationPhase.cpp
 162 dfg/DFGResurrectionForValidationPhase.cpp
161163 dfg/DFGSSAConversionPhase.cpp
162164 dfg/DFGSpeculativeJIT.cpp
163165 dfg/DFGSpeculativeJIT32_64.cpp
159352

Source/JavaScriptCore/GNUmakefile.list.am

@@javascriptcore_sources += \
100100 Source/JavaScriptCore/bytecode/ArrayProfile.cpp \
101101 Source/JavaScriptCore/bytecode/ArrayProfile.h \
102102 Source/JavaScriptCore/bytecode/ByValInfo.h \
103  Source/JavaScriptCore/bytecode/BytecodeBasicBlock.cpp \
104  Source/JavaScriptCore/bytecode/BytecodeBasicBlock.h \
105  Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysis.cpp \
106  Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysis.h \
 103 Source/JavaScriptCore/bytecode/BytecodeBasicBlock.cpp \
 104 Source/JavaScriptCore/bytecode/BytecodeBasicBlock.h \
 105 Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysis.cpp \
 106 Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysis.h \
 107 Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysisInlines.h \
107108 Source/JavaScriptCore/bytecode/BytecodeConventions.h \
108109 Source/JavaScriptCore/bytecode/CallLinkInfo.cpp \
109110 Source/JavaScriptCore/bytecode/CallLinkInfo.h \

@@javascriptcore_sources += \
132133 Source/JavaScriptCore/bytecode/ExitKind.cpp \
133134 Source/JavaScriptCore/bytecode/ExitKind.h \
134135 Source/JavaScriptCore/bytecode/ExpressionRangeInfo.h \
 136 Source/JavaScriptCore/bytecode/FullBytecodeLiveness.h \
135137 Source/JavaScriptCore/bytecode/GetByIdStatus.cpp \
136138 Source/JavaScriptCore/bytecode/GetByIdStatus.h \
137139 Source/JavaScriptCore/bytecode/HandlerInfo.h \

@@javascriptcore_sources += \
207209 Source/JavaScriptCore/dfg/DFGArrayifySlowPathGenerator.h \
208210 Source/JavaScriptCore/dfg/DFGAtTailAbstractState.cpp \
209211 Source/JavaScriptCore/dfg/DFGAtTailAbstractState.h \
 212 Source/JavaScriptCore/dfg/DFGAvailability.cpp \
 213 Source/JavaScriptCore/dfg/DFGAvailability.h \
210214 Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp \
211215 Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.h \
212216 Source/JavaScriptCore/dfg/DFGBasicBlock.cpp \

@@javascriptcore_sources += \
358362 Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp \
359363 Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.h \
360364 Source/JavaScriptCore/dfg/DFGRegisterBank.h \
 365 Source/JavaScriptCore/dfg/DFGResurrectionForValidationPhase.cpp \
 366 Source/JavaScriptCore/dfg/DFGResurrectionForValidationPhase.h \
361367 Source/JavaScriptCore/dfg/DFGSafeToExecute.h \
362368 Source/JavaScriptCore/dfg/DFGSaneStringGetByValSlowPathGenerator.h \
363369 Source/JavaScriptCore/dfg/DFGScoreBoard.h \

@@javascriptcore_sources += \
469475 Source/JavaScriptCore/ftl/FTLValueFormat.cpp \
470476 Source/JavaScriptCore/ftl/FTLValueFormat.h \
471477 Source/JavaScriptCore/ftl/FTLValueFromBlock.h \
472  Source/JavaScriptCore/ftl/FTLValueSource.cpp \
473  Source/JavaScriptCore/ftl/FTLValueSource.h \
474478 Source/JavaScriptCore/heap/CodeBlockSet.cpp \
475479 Source/JavaScriptCore/heap/CodeBlockSet.h \
476480 Source/JavaScriptCore/heap/CopiedAllocator.h \
159352

Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj

338338 <ClCompile Include="..\dfg\DFGArgumentsSimplificationPhase.cpp" />
339339 <ClCompile Include="..\dfg\DFGArrayMode.cpp" />
340340 <ClCompile Include="..\dfg\DFGAtTailAbstractState.cpp" />
 341 <ClCompile Include="..\dfg\DFGAvailability.cpp" />
341342 <ClCompile Include="..\dfg\DFGBackwardsPropagationPhase.cpp" />
342343 <ClCompile Include="..\dfg\DFGBasicBlock.cpp" />
343344 <ClCompile Include="..\dfg\DFGBinarySwitch.cpp" />

403404 <ClCompile Include="..\dfg\DFGPlan.cpp" />
404405 <ClCompile Include="..\dfg\DFGPredictionInjectionPhase.cpp" />
405406 <ClCompile Include="..\dfg\DFGPredictionPropagationPhase.cpp" />
 407 <ClCompile Include="..\dfg\DFGResurrectionForValidationPhase.cpp" />
406408 <ClCompile Include="..\dfg\DFGSpeculativeJIT.cpp" />
407409 <ClCompile Include="..\dfg\DFGSpeculativeJIT32_64.cpp" />
408410 <ClCompile Include="..\dfg\DFGSpeculativeJIT64.cpp" />

745747 <ClInclude Include="..\bytecode\ByValInfo.h" />
746748 <ClInclude Include="..\bytecode\BytecodeBasicBlock.h" />
747749 <ClInclude Include="..\bytecode\BytecodeLivenessAnalysis.h" />
 750 <ClInclude Include="..\bytecode\BytecodeLivenessAnalysisInline.h" />
748751 <ClInclude Include="..\bytecode\CallLinkInfo.h" />
749752 <ClInclude Include="..\bytecode\CallLinkStatus.h" />
750753 <ClInclude Include="..\bytecode\CallReturnOffsetToBytecodeOffset.h" />

762765 <ClInclude Include="..\bytecode\ExecutionCounter.h" />
763766 <ClInclude Include="..\bytecode\ExitKind.h" />
764767 <ClInclude Include="..\bytecode\ExpressionRangeInfo.h" />
 768 <ClInclude Include="..\bytecode\FullBytecodeLivenss.h" />
765769 <ClInclude Include="..\bytecode\GetByIdStatus.h" />
766770 <ClInclude Include="..\bytecode\HandlerInfo.h" />
767771 <ClInclude Include="..\bytecode\InlineCallFrameSet.h" />

812816 <ClInclude Include="..\dfg\DFGArrayifySlowPathGenerator.h" />
813817 <ClInclude Include="..\dfg\DFGArrayMode.h" />
814818 <ClInclude Include="..\dfg\DFGAtTailAbstractState.h" />
 819 <ClInclude Include="..\dfg\DFGAvailability.h" />
815820 <ClInclude Include="..\dfg\DFGBackwardsPropagationPhase.h" />
816821 <ClInclude Include="..\dfg\DFGBasicBlock.h" />
817822 <ClInclude Include="..\dfg\DFGBasicBlockInlines.h" />

895900 <ClInclude Include="..\dfg\DFGPredictionPropagationPhase.h" />
896901 <ClInclude Include="..\dfg\DFGRegisterBank.h" />
897902 <ClInclude Include="..\dfg\DFGRegisterSet.h" />
 903 <ClInclude Include="..\dfg\DFGResurrectionForValidationPhase.h" />
898904 <ClInclude Include="..\dfg\DFGSafeToExecute.h" />
899905 <ClInclude Include="..\dfg\DFGSaneStringGetByValSlowPathGenerator.h" />
900906 <ClInclude Include="..\dfg\DFGScoreBoard.h" />
159352

Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

104104 0F235BE217178E1C00690C7F /* FTLThunks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F235BCC17178E1C00690C7F /* FTLThunks.h */; settings = {ATTRIBUTES = (Private, ); }; };
105105 0F235BE317178E1C00690C7F /* FTLValueFormat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F235BCD17178E1C00690C7F /* FTLValueFormat.cpp */; };
106106 0F235BE417178E1C00690C7F /* FTLValueFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F235BCE17178E1C00690C7F /* FTLValueFormat.h */; settings = {ATTRIBUTES = (Private, ); }; };
107  0F235BE517178E1C00690C7F /* FTLValueSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F235BCF17178E1C00690C7F /* FTLValueSource.cpp */; };
108  0F235BE617178E1C00690C7F /* FTLValueSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F235BD017178E1C00690C7F /* FTLValueSource.h */; settings = {ATTRIBUTES = (Private, ); }; };
109107 0F235BEB17178E7300690C7F /* DFGOSRExitBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F235BE717178E7300690C7F /* DFGOSRExitBase.cpp */; };
110108 0F235BEC17178E7300690C7F /* DFGOSRExitBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F235BE817178E7300690C7F /* DFGOSRExitBase.h */; settings = {ATTRIBUTES = (Private, ); }; };
111109 0F235BED17178E7300690C7F /* DFGOSRExitPreparation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F235BE917178E7300690C7F /* DFGOSRExitPreparation.cpp */; };

260258 0F63947815DCE34B006A597C /* DFGStructureAbstractValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F63947615DCE347006A597C /* DFGStructureAbstractValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
261259 0F63948415E48118006A597C /* DFGArrayMode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F63948115E48114006A597C /* DFGArrayMode.cpp */; };
262260 0F63948515E4811B006A597C /* DFGArrayMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F63948215E48114006A597C /* DFGArrayMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
 261 0F666EC0183566F900D017F1 /* BytecodeLivenessAnalysisInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F666EBE183566F900D017F1 /* BytecodeLivenessAnalysisInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
 262 0F666EC1183566F900D017F1 /* FullBytecodeLiveness.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F666EBF183566F900D017F1 /* FullBytecodeLiveness.h */; settings = {ATTRIBUTES = (Private, ); }; };
 263 0F666EC61835672B00D017F1 /* DFGAvailability.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F666EC21835672B00D017F1 /* DFGAvailability.cpp */; };
 264 0F666EC71835672B00D017F1 /* DFGAvailability.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F666EC31835672B00D017F1 /* DFGAvailability.h */; settings = {ATTRIBUTES = (Private, ); }; };
 265 0F666ECC1836B37E00D017F1 /* DFGResurrectionForValidationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F666ECA1836B37E00D017F1 /* DFGResurrectionForValidationPhase.cpp */; };
 266 0F666ECD1836B37E00D017F1 /* DFGResurrectionForValidationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F666ECB1836B37E00D017F1 /* DFGResurrectionForValidationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
263267 0F66E16B14DF3F1600B7B2E4 /* DFGAdjacencyList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F66E16814DF3F1300B7B2E4 /* DFGAdjacencyList.h */; settings = {ATTRIBUTES = (Private, ); }; };
264268 0F66E16C14DF3F1600B7B2E4 /* DFGEdge.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F66E16914DF3F1300B7B2E4 /* DFGEdge.h */; settings = {ATTRIBUTES = (Private, ); }; };
265269 0F7025A91714B0FA00382C0E /* DFGOSRExitCompilerCommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7025A71714B0F800382C0E /* DFGOSRExitCompilerCommon.cpp */; };

13951399 0F235BCC17178E1C00690C7F /* FTLThunks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLThunks.h; path = ftl/FTLThunks.h; sourceTree = "<group>"; };
13961400 0F235BCD17178E1C00690C7F /* FTLValueFormat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLValueFormat.cpp; path = ftl/FTLValueFormat.cpp; sourceTree = "<group>"; };
13971401 0F235BCE17178E1C00690C7F /* FTLValueFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLValueFormat.h; path = ftl/FTLValueFormat.h; sourceTree = "<group>"; };
1398  0F235BCF17178E1C00690C7F /* FTLValueSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLValueSource.cpp; path = ftl/FTLValueSource.cpp; sourceTree = "<group>"; };
1399  0F235BD017178E1C00690C7F /* FTLValueSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLValueSource.h; path = ftl/FTLValueSource.h; sourceTree = "<group>"; };
14001402 0F235BE717178E7300690C7F /* DFGOSRExitBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOSRExitBase.cpp; path = dfg/DFGOSRExitBase.cpp; sourceTree = "<group>"; };
14011403 0F235BE817178E7300690C7F /* DFGOSRExitBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExitBase.h; path = dfg/DFGOSRExitBase.h; sourceTree = "<group>"; };
14021404 0F235BE917178E7300690C7F /* DFGOSRExitPreparation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOSRExitPreparation.cpp; path = dfg/DFGOSRExitPreparation.cpp; sourceTree = "<group>"; };

15501552 0F63947615DCE347006A597C /* DFGStructureAbstractValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStructureAbstractValue.h; path = dfg/DFGStructureAbstractValue.h; sourceTree = "<group>"; };
15511553 0F63948115E48114006A597C /* DFGArrayMode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGArrayMode.cpp; path = dfg/DFGArrayMode.cpp; sourceTree = "<group>"; };
15521554 0F63948215E48114006A597C /* DFGArrayMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGArrayMode.h; path = dfg/DFGArrayMode.h; sourceTree = "<group>"; };
 1555 0F666EBE183566F900D017F1 /* BytecodeLivenessAnalysisInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeLivenessAnalysisInlines.h; sourceTree = "<group>"; };
 1556 0F666EBF183566F900D017F1 /* FullBytecodeLiveness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FullBytecodeLiveness.h; sourceTree = "<group>"; };
 1557 0F666EC21835672B00D017F1 /* DFGAvailability.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGAvailability.cpp; path = dfg/DFGAvailability.cpp; sourceTree = "<group>"; };
 1558 0F666EC31835672B00D017F1 /* DFGAvailability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAvailability.h; path = dfg/DFGAvailability.h; sourceTree = "<group>"; };
 1559 0F666ECA1836B37E00D017F1 /* DFGResurrectionForValidationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGResurrectionForValidationPhase.cpp; path = dfg/DFGResurrectionForValidationPhase.cpp; sourceTree = "<group>"; };
 1560 0F666ECB1836B37E00D017F1 /* DFGResurrectionForValidationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGResurrectionForValidationPhase.h; path = dfg/DFGResurrectionForValidationPhase.h; sourceTree = "<group>"; };
15531561 0F66E16814DF3F1300B7B2E4 /* DFGAdjacencyList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAdjacencyList.h; path = dfg/DFGAdjacencyList.h; sourceTree = "<group>"; };
15541562 0F66E16914DF3F1300B7B2E4 /* DFGEdge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGEdge.h; path = dfg/DFGEdge.h; sourceTree = "<group>"; };
15551563 0F7025A71714B0F800382C0E /* DFGOSRExitCompilerCommon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOSRExitCompilerCommon.cpp; path = dfg/DFGOSRExitCompilerCommon.cpp; sourceTree = "<group>"; };

28442852 0F235BCD17178E1C00690C7F /* FTLValueFormat.cpp */,
28452853 0F235BCE17178E1C00690C7F /* FTLValueFormat.h */,
28462854 0FDB2CC8173DA51E007B3C1B /* FTLValueFromBlock.h */,
2847  0F235BCF17178E1C00690C7F /* FTLValueSource.cpp */,
2848  0F235BD017178E1C00690C7F /* FTLValueSource.h */,
28492855 );
28502856 name = ftl;
28512857 sourceTree = "<group>";

37443750 0F63948215E48114006A597C /* DFGArrayMode.h */,
37453751 A7D9A28F17A0BC7400EE2618 /* DFGAtTailAbstractState.cpp */,
37463752 A7D9A29017A0BC7400EE2618 /* DFGAtTailAbstractState.h */,
 3753 0F666EC21835672B00D017F1 /* DFGAvailability.cpp */,
 3754 0F666EC31835672B00D017F1 /* DFGAvailability.h */,
37473755 0F714CA116EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.cpp */,
37483756 0F714CA216EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.h */,
37493757 A7D89CE317A0B8CC00773AD8 /* DFGBasicBlock.cpp */,

38943902 0FFFC95114EF909500C72532 /* DFGPredictionPropagationPhase.cpp */,
38953903 0FFFC95214EF909500C72532 /* DFGPredictionPropagationPhase.h */,
38963904 86EC9DC11328DF82002B2AD7 /* DFGRegisterBank.h */,
 3905 0F666ECA1836B37E00D017F1 /* DFGResurrectionForValidationPhase.cpp */,
 3906 0F666ECB1836B37E00D017F1 /* DFGResurrectionForValidationPhase.h */,
38973907 A77A423C17A0BBFD00A8DB81 /* DFGSafeToExecute.h */,
38983908 A741017E179DAF80002EB8BA /* DFGSaneStringGetByValSlowPathGenerator.h */,
38993909 86ECA3F9132DF25A002B2AD7 /* DFGScoreBoard.h */,

40364046 969A078F0ED1D3AE00F1F681 /* bytecode */ = {
40374047 isa = PBXGroup;
40384048 children = (
4039  C2FCAE0C17A9C24E0034C735 /* BytecodeBasicBlock.cpp */,
4040  C2FCAE0D17A9C24E0034C735 /* BytecodeBasicBlock.h */,
4041  C2FCAE0E17A9C24E0034C735 /* BytecodeLivenessAnalysis.cpp */,
4042  C2FCAE0F17A9C24E0034C735 /* BytecodeLivenessAnalysis.h */,
40434049 0F8335B41639C1E3001443B5 /* ArrayAllocationProfile.cpp */,
40444050 0F8335B51639C1E3001443B5 /* ArrayAllocationProfile.h */,
40454051 0F63945115D07051006A597C /* ArrayProfile.cpp */,
40464052 0F63945215D07051006A597C /* ArrayProfile.h */,
 4053 C2FCAE0C17A9C24E0034C735 /* BytecodeBasicBlock.cpp */,
 4054 C2FCAE0D17A9C24E0034C735 /* BytecodeBasicBlock.h */,
40474055 0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */,
 4056 C2FCAE0E17A9C24E0034C735 /* BytecodeLivenessAnalysis.cpp */,
 4057 C2FCAE0F17A9C24E0034C735 /* BytecodeLivenessAnalysis.h */,
 4058 0F666EBE183566F900D017F1 /* BytecodeLivenessAnalysisInlines.h */,
40484059 0F8023E91613832300A0BA45 /* ByValInfo.h */,
40494060 0F0B83AE14BCF71400885B4F /* CallLinkInfo.cpp */,
40504061 0F0B83AF14BCF71400885B4F /* CallLinkInfo.h */,

40734084 0FB105821675480C00F8AB6E /* ExitKind.cpp */,
40744085 0FB105831675480C00F8AB6E /* ExitKind.h */,
40754086 0F0B83AA14BCF5B900885B4F /* ExpressionRangeInfo.h */,
 4087 0F666EBF183566F900D017F1 /* FullBytecodeLiveness.h */,
40764088 0F93329514CA7DC10085F3C6 /* GetByIdStatus.cpp */,
40774089 0F93329614CA7DC10085F3C6 /* GetByIdStatus.h */,
40784090 0F0B83A814BCF55E00885B4F /* HandlerInfo.h */,

44314443 0FEA0A201708B00700BB722C /* FTLTypedPointer.h in Headers */,
44324444 0F235BE417178E1C00690C7F /* FTLValueFormat.h in Headers */,
44334445 0FDB2CCA173DA523007B3C1B /* FTLValueFromBlock.h in Headers */,
4434  0F235BE617178E1C00690C7F /* FTLValueSource.h in Headers */,
44354446 BC18C4040E16F5CD00B34460 /* FunctionConstructor.h in Headers */,
44364447 0FF0F1A016B72A1A005DF95B /* FunctionExecutableDump.h in Headers */,
44374448 BC18C4050E16F5CD00B34460 /* FunctionPrototype.h in Headers */,

44614472 2A6F462617E959CE00C45C98 /* HeapOperation.h in Headers */,
44624473 14F97447138C853E00DA1C67 /* HeapRootVisitor.h in Headers */,
44634474 C24D31E3161CD695002AA4DB /* HeapStatistics.h in Headers */,
 4475 0F666EC1183566F900D017F1 /* FullBytecodeLiveness.h in Headers */,
44644476 C2E526BE1590EF000054E48D /* HeapTimer.h in Headers */,
44654477 0F4680D514BBD24B00BFE272 /* HostCallReturnValue.h in Headers */,
44664478 BC18C40F0E16F5CD00B34460 /* Identifier.h in Headers */,

47034715 95CD45770E1C4FDD0085358E /* ProfileGenerator.h in Headers */,
47044716 BC18C4510E16F5CD00B34460 /* ProfileNode.h in Headers */,
47054717 0FF729A5166AD351000F5BA3 /* ProfilerBytecode.h in Headers */,
 4718 0F666EC0183566F900D017F1 /* BytecodeLivenessAnalysisInlines.h in Headers */,
47064719 0FF729B9166AD360000F5BA3 /* ProfilerBytecodes.h in Headers */,
47074720 0F13912A16771C36009CCB07 /* ProfilerBytecodeSequence.h in Headers */,
47084721 0FF729BA166AD360000F5BA3 /* ProfilerCompilation.h in Headers */,

48134826 A7A8AF3F17ADB5F3005AB174 /* Uint8Array.h in Headers */,
48144827 A7A8AF4017ADB5F3005AB174 /* Uint8ClampedArray.h in Headers */,
48154828 0F5F08CF146C7633000472A9 /* UnconditionalFinalizer.h in Headers */,
 4829 0F666EC71835672B00D017F1 /* DFGAvailability.h in Headers */,
48164830 A7B601821639FD2A00372BA3 /* UnlinkedCodeBlock.h in Headers */,
48174831 0F2E892C16D028AD009E4FD2 /* UnusedPointer.h in Headers */,
48184832 0F963B3813FC6FE90002D9B2 /* ValueProfile.h in Headers */,

48434857 0FC8150A14043BF500CFA603 /* WriteBarrierSupport.h in Headers */,
48444858 9688CB160ED12B4E001D649F /* X86Assembler.h in Headers */,
48454859 451539B912DC994500EF7AC4 /* Yarr.h in Headers */,
 4860 0F666ECD1836B37E00D017F1 /* DFGResurrectionForValidationPhase.h in Headers */,
48464861 86704B8512DBA33700A9FE7B /* YarrInterpreter.h in Headers */,
48474862 86704B8712DBA33700A9FE7B /* YarrJIT.h in Headers */,
48484863 86704B8812DBA33700A9FE7B /* YarrParser.h in Headers */,

54515466 0FEA0A161706BB9000BB722C /* FTLState.cpp in Sources */,
54525467 0F235BE117178E1C00690C7F /* FTLThunks.cpp in Sources */,
54535468 0F235BE317178E1C00690C7F /* FTLValueFormat.cpp in Sources */,
5454  0F235BE517178E1C00690C7F /* FTLValueSource.cpp in Sources */,
54555469 147F39CB107EC37600427A48 /* FunctionConstructor.cpp in Sources */,
54565470 0FF0F19F16B72A17005DF95B /* FunctionExecutableDump.cpp in Sources */,
54575471 147F39CC107EC37600427A48 /* FunctionPrototype.cpp in Sources */,

56305644 0FF729B3166AD35C000F5BA3 /* ProfilerOrigin.cpp in Sources */,
56315645 0FF729B4166AD35C000F5BA3 /* ProfilerOriginStack.cpp in Sources */,
56325646 C2FCAE1017A9C24E0034C735 /* BytecodeBasicBlock.cpp in Sources */,
 5647 0F666ECC1836B37E00D017F1 /* DFGResurrectionForValidationPhase.cpp in Sources */,
56335648 0FB1058B1675483100F8AB6E /* ProfilerOSRExit.cpp in Sources */,
56345649 0FB1058D1675483700F8AB6E /* ProfilerOSRExitSite.cpp in Sources */,
56355650 0F13912B16771C3A009CCB07 /* ProfilerProfiledBytecodes.cpp in Sources */,

56985713 0FC81516140511B500CFA603 /* VTableSpectrum.cpp in Sources */,
56995714 FED94F2E171E3E2300BE77A4 /* Watchdog.cpp in Sources */,
57005715 FED94F30171E3E2300BE77A4 /* WatchdogMac.cpp in Sources */,
 5716 0F666EC61835672B00D017F1 /* DFGAvailability.cpp in Sources */,
57015717 0F919D2515853CE0004A4E7D /* Watchpoint.cpp in Sources */,
57025718 1ACF7377171CA6FB00C9BB1E /* Weak.cpp in Sources */,
57035719 14E84F9E14EE1ACC00D6D5D4 /* WeakBlock.cpp in Sources */,
159352

Source/JavaScriptCore/bytecode/BytecodeBasicBlock.h

@@namespace JSC {
3636
3737class CodeBlock;
3838
39 typedef HashMap<unsigned, FastBitVector, WTF::IntHash<unsigned>, WTF::UnsignedWithZeroKeyHashTraits<unsigned> > BytecodeToBitmapMap;
40 
4139class BytecodeBasicBlock : public RefCounted<BytecodeBasicBlock> {
4240public:
4341 enum SpecialBlockType { EntryBlock, ExitBlock };
159352

Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysis.cpp

2626#include "config.h"
2727#include "BytecodeLivenessAnalysis.h"
2828
 29#include "BytecodeLivenessAnalysisInlines.h"
2930#include "CodeBlock.h"
 31#include "FullBytecodeLiveness.h"
3032#include "PreciseJumpTargets.h"
3133
3234namespace JSC {

@@BytecodeLivenessAnalysis::BytecodeLivene
3840 compute();
3941}
4042
41 static int numberOfCapturedVariables(CodeBlock* codeBlock)
42 {
43  if (!codeBlock->symbolTable())
44  return 0;
45  return codeBlock->symbolTable()->captureCount();
46 }
47 
48 static int captureStart(CodeBlock* codeBlock)
49 {
50  if (!codeBlock->symbolTable())
51  return 0;
52  return codeBlock->symbolTable()->captureStart();
53 }
54 
55 static int captureEnd(CodeBlock* codeBlock)
56 {
57  if (!codeBlock->symbolTable())
58  return 0;
59  return codeBlock->symbolTable()->captureEnd();
60 }
61 
6243static bool isValidRegisterForLiveness(CodeBlock* codeBlock, int operand)
6344{
6445 VirtualRegister virtualReg(operand);
6546 return !codeBlock->isConstantRegisterIndex(operand) // Don't care about constants.
6647 && virtualReg.isLocal() // Don't care about arguments.
67  && (!numberOfCapturedVariables(codeBlock) // If we have no captured variables, we're good to go.
68  || (virtualReg.offset() > captureStart(codeBlock) || (virtualReg.offset() <= captureEnd(codeBlock))));
 48 && (!codeBlock->captureCount() // If we have no captured variables, we're good to go.
 49 || (virtualReg.offset() > codeBlock->captureStart() || (virtualReg.offset() <= codeBlock->captureEnd())));
6950}
7051
7152static void setForOperand(CodeBlock* codeBlock, FastBitVector& bits, int operand)
7253{
7354 ASSERT(isValidRegisterForLiveness(codeBlock, operand));
7455 VirtualRegister virtualReg(operand);
75  if (virtualReg.offset() > captureStart(codeBlock))
 56 if (virtualReg.offset() > codeBlock->captureStart())
7657 bits.set(virtualReg.toLocal());
7758 else
78  bits.set(virtualReg.toLocal() - numberOfCapturedVariables(codeBlock));
 59 bits.set(virtualReg.toLocal() - codeBlock->captureCount());
7960}
8061
8162static void computeUsesForBytecodeOffset(CodeBlock* codeBlock, unsigned bytecodeOffset, FastBitVector& uses)

@@static void computeUsesForBytecodeOffset
303284 int base = instruction[2].u.operand;
304285 int count = instruction[3].u.operand;
305286 for (int i = 0; i < count; i++) {
306  if (isValidRegisterForLiveness(codeBlock, base + i))
307  setForOperand(codeBlock, uses, base + i);
 287 if (isValidRegisterForLiveness(codeBlock, base - i))
 288 setForOperand(codeBlock, uses, base - i);
308289 }
309290 return;
310291 }

@@static void computeUsesForBytecodeOffset
315296 if (isValidRegisterForLiveness(codeBlock, instruction[2].u.operand))
316297 setForOperand(codeBlock, uses, instruction[2].u.operand);
317298 int argCount = instruction[3].u.operand;
318  int registerOffset = instruction[4].u.operand;
 299 int registerOffset = -instruction[4].u.operand;
319300 int lastArg = registerOffset + CallFrame::thisArgumentOffset();
320  for (int i = 0; i < argCount; i++) {
321  if (isValidRegisterForLiveness(codeBlock, lastArg - i))
322  setForOperand(codeBlock, uses, lastArg - i);
 301 for (int i = opcodeID == op_construct ? 1 : 0; i < argCount; i++) {
 302 if (isValidRegisterForLiveness(codeBlock, lastArg + i))
 303 setForOperand(codeBlock, uses, lastArg + i);
323304 }
324305 return;
325306 }

@@static void computeUsesForBytecodeOffset
333314 setForOperand(codeBlock, uses, instruction[2].u.operand);
334315 return;
335316 }
336 #define LLINT_HELPER_OPCODES(opcode, length) case opcode:
337  FOR_EACH_LLINT_OPCODE_EXTENSION(LLINT_HELPER_OPCODES)
338  return;
339 #undef LLINT_HELPER_OPCODES
 317 default:
 318 RELEASE_ASSERT_NOT_REACHED();
 319 break;
340320 }
341321}
342322

@@static void computeDefsForBytecodeOffset
492472 case op_enter: {
493473 defs.setAll();
494474 return;
495  }
496  }
 475 } }
497476}
498477
499478static unsigned getLeaderOffsetForBasicBlock(RefPtr<BytecodeBasicBlock>* basicBlock)

@@static BytecodeBasicBlock* findBasicBloc
540519 return basicBlock[1].get();
541520}
542521
 522static void stepOverInstruction(CodeBlock* codeBlock, Vector<RefPtr<BytecodeBasicBlock>>& basicBlocks, unsigned bytecodeOffset, FastBitVector& uses, FastBitVector& defs, FastBitVector& out)
 523{
 524 uses.clearAll();
 525 defs.clearAll();
 526
 527 computeUsesForBytecodeOffset(codeBlock, bytecodeOffset, uses);
 528 computeDefsForBytecodeOffset(codeBlock, bytecodeOffset, defs);
 529
 530 out.exclude(defs);
 531 out.merge(uses);
 532
 533 // If we have an exception handler, we want the live-in variables of the
 534 // exception handler block to be included in the live-in of this particular bytecode.
 535 if (HandlerInfo* handler = codeBlock->handlerForBytecodeOffset(bytecodeOffset)) {
 536 BytecodeBasicBlock* handlerBlock = findBasicBlockWithLeaderOffset(basicBlocks, handler->target);
 537 ASSERT(handlerBlock);
 538 out.merge(handlerBlock->in());
 539 }
 540}
 541
543542static void computeLocalLivenessForBytecodeOffset(CodeBlock* codeBlock, BytecodeBasicBlock* block, Vector<RefPtr<BytecodeBasicBlock> >& basicBlocks, unsigned targetOffset, FastBitVector& result)
544543{
545544 ASSERT(!block->isExitBlock());
546545 ASSERT(!block->isEntryBlock());
547546
548547 FastBitVector out = block->out();
549  HandlerInfo* handler = 0;
550548
551549 FastBitVector uses;
552550 FastBitVector defs;

@@static void computeLocalLivenessForBytec
557555 unsigned bytecodeOffset = block->bytecodeOffsets()[i];
558556 if (targetOffset > bytecodeOffset)
559557 break;
560 
561  uses.clearAll();
562  defs.clearAll();
563 
564  computeUsesForBytecodeOffset(codeBlock, bytecodeOffset, uses);
565  computeDefsForBytecodeOffset(codeBlock, bytecodeOffset, defs);
566 
567  out.exclude(defs);
568  out.merge(uses);
569 
570  // If we have an exception handler, we want the live-in variables of the
571  // exception handler block to be included in the live-in of this particular bytecode.
572  if ((handler = codeBlock->handlerForBytecodeOffset(bytecodeOffset))) {
573  BytecodeBasicBlock* handlerBlock = findBasicBlockWithLeaderOffset(basicBlocks, handler->target);
574  ASSERT(handlerBlock);
575  out.merge(handlerBlock->in());
576  }
 558
 559 stepOverInstruction(codeBlock, basicBlocks, bytecodeOffset, uses, defs, out);
577560 }
578561
579562 result.set(out);

@@void BytecodeLivenessAnalysis::runLivene
590573{
591574 UnlinkedCodeBlock* unlinkedCodeBlock = m_codeBlock->unlinkedCodeBlock();
592575 unsigned numberOfVariables = unlinkedCodeBlock->m_numVars +
593  unlinkedCodeBlock->m_numCalleeRegisters - numberOfCapturedVariables(m_codeBlock);
 576 unlinkedCodeBlock->m_numCalleeRegisters - m_codeBlock->captureCount();
594577
595578 for (unsigned i = 0; i < m_basicBlocks.size(); i++) {
596579 BytecodeBasicBlock* block = m_basicBlocks[i].get();

@@void BytecodeLivenessAnalysis::getLivene
629612
630613bool BytecodeLivenessAnalysis::operandIsLiveAtBytecodeOffset(int operand, unsigned bytecodeOffset)
631614{
632  int numCapturedVars = numberOfCapturedVariables(m_codeBlock);
633  if (VirtualRegister(operand).isArgument())
634  return true;
635  if (operand <= captureStart(m_codeBlock) && operand > captureEnd(m_codeBlock))
 615 if (operandIsAlwaysLive(m_codeBlock, operand))
636616 return true;
637617 FastBitVector result;
638618 getLivenessInfoForNonCapturedVarsAtBytecodeOffset(bytecodeOffset, result);
639  return result.get(operand - numCapturedVars);
 619 return operandThatIsNotAlwaysLiveIsLive(m_codeBlock, result, operand);
640620}
641621
642 FastBitVector BytecodeLivenessAnalysis::getLivenessInfoAtBytecodeOffset(unsigned bytecodeOffset)
 622FastBitVector getLivenessInfo(CodeBlock* codeBlock, const FastBitVector& out)
643623{
644  FastBitVector temp;
645624 FastBitVector result;
646625
647  getLivenessInfoForNonCapturedVarsAtBytecodeOffset(bytecodeOffset, temp);
648 
649  unsigned numCapturedVars = numberOfCapturedVariables(m_codeBlock);
 626 unsigned numCapturedVars = codeBlock->captureCount();
650627 if (numCapturedVars) {
651  int firstCapturedLocal = VirtualRegister(captureStart(m_codeBlock)).toLocal();
652  result.resize(temp.numBits() + numCapturedVars);
 628 int firstCapturedLocal = VirtualRegister(codeBlock->captureStart()).toLocal();
 629 result.resize(out.numBits() + numCapturedVars);
653630 for (unsigned i = 0; i < numCapturedVars; ++i)
654631 result.set(firstCapturedLocal + i);
655632 } else
656  result.resize(temp.numBits());
 633 result.resize(out.numBits());
657634
658  int tempLength = temp.numBits();
659  ASSERT(tempLength >= 0);
660  for (int i = 0; i < tempLength; i++) {
661  if (!temp.get(i))
 635 int outLength = out.numBits();
 636 ASSERT(outLength >= 0);
 637 for (int i = 0; i < outLength; i++) {
 638 if (!out.get(i))
662639 continue;
663640
664641 if (!numCapturedVars) {

@@FastBitVector BytecodeLivenessAnalysis::
666643 continue;
667644 }
668645
669  if (virtualRegisterForLocal(i).offset() > captureStart(m_codeBlock))
 646 if (virtualRegisterForLocal(i).offset() > codeBlock->captureStart())
670647 result.set(i);
671648 else
672649 result.set(numCapturedVars + i);

@@FastBitVector BytecodeLivenessAnalysis::
674651 return result;
675652}
676653
 654FastBitVector BytecodeLivenessAnalysis::getLivenessInfoAtBytecodeOffset(unsigned bytecodeOffset)
 655{
 656 FastBitVector out;
 657 getLivenessInfoForNonCapturedVarsAtBytecodeOffset(bytecodeOffset, out);
 658 return getLivenessInfo(m_codeBlock, out);
 659}
 660
 661void BytecodeLivenessAnalysis::computeFullLiveness(FullBytecodeLiveness& result)
 662{
 663 FastBitVector out;
 664 FastBitVector uses;
 665 FastBitVector defs;
 666
 667 result.m_codeBlock = m_codeBlock;
 668 result.m_map.clear();
 669
 670 for (unsigned i = m_basicBlocks.size(); i--;) {
 671 BytecodeBasicBlock* block = m_basicBlocks[i].get();
 672 if (block->isEntryBlock() || block->isExitBlock())
 673 continue;
 674
 675 out = block->out();
 676 uses.resize(out.numBits());
 677 defs.resize(out.numBits());
 678
 679 for (unsigned i = block->bytecodeOffsets().size(); i--;) {
 680 unsigned bytecodeOffset = block->bytecodeOffsets()[i];
 681 stepOverInstruction(m_codeBlock, m_basicBlocks, bytecodeOffset, uses, defs, out);
 682 result.m_map.add(bytecodeOffset, out);
 683 }
 684 }
 685}
 686
677687void BytecodeLivenessAnalysis::dumpResults()
678688{
679689 Interpreter* interpreter = m_codeBlock->vm()->interpreter;
159352

Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysis.h

3434namespace JSC {
3535
3636class CodeBlock;
 37class FullBytecodeLiveness;
3738
3839class BytecodeLivenessAnalysis {
3940public:
4041 BytecodeLivenessAnalysis(CodeBlock*);
41 
 42
4243 bool operandIsLiveAtBytecodeOffset(int operand, unsigned bytecodeOffset);
4344 FastBitVector getLivenessInfoAtBytecodeOffset(unsigned bytecodeOffset);
 45
 46 void computeFullLiveness(FullBytecodeLiveness& result);
4447
4548private:
4649 void compute();

@@private:
5356 Vector<RefPtr<BytecodeBasicBlock> > m_basicBlocks;
5457};
5558
 59inline bool operandIsAlwaysLive(CodeBlock*, int operand);
 60inline bool operandThatIsNotAlwaysLiveIsLive(CodeBlock*, const FastBitVector& out, int operand);
 61inline bool operandIsLive(CodeBlock*, const FastBitVector& out, int operand);
 62
 63FastBitVector getLivenessInfo(CodeBlock*, const FastBitVector& out);
 64
5665} // namespace JSC
5766
5867#endif // BytecodeLivenessAnalysis_h
159352

Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysisInlines.h

 1/*
 2 * Copyright (C) 2013 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 23 * THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef BytecodeLivenessAnalysisInlines_h
 27#define BytecodeLivenessAnalysisInlines_h
 28
 29#include "BytecodeLivenessAnalysis.h"
 30#include "CodeBlock.h"
 31
 32namespace JSC {
 33
 34inline bool operandIsAlwaysLive(CodeBlock* codeBlock, int operand)
 35{
 36 if (VirtualRegister(operand).isArgument())
 37 return true;
 38 return operand <= codeBlock->captureStart() && operand > codeBlock->captureEnd();
 39}
 40
 41inline bool operandThatIsNotAlwaysLiveIsLive(CodeBlock* codeBlock, const FastBitVector& out, int operand)
 42{
 43 VirtualRegister virtualReg(operand);
 44 if (virtualReg.offset() > codeBlock->captureStart())
 45 return out.get(virtualReg.toLocal());
 46 size_t index = virtualReg.toLocal() - codeBlock->captureCount();
 47 if (index >= out.numBits())
 48 return false;
 49 return out.get(index);
 50}
 51
 52inline bool operandIsLive(CodeBlock* codeBlock, const FastBitVector& out, int operand)
 53{
 54 return operandIsAlwaysLive(codeBlock, operand) || operandThatIsNotAlwaysLiveIsLive(codeBlock, out, operand);
 55}
 56
 57} // namespace JSC
 58
 59#endif // BytecodeLivenessAnalysisInlines_h
 60
0

Source/JavaScriptCore/bytecode/CodeBlock.h

@@public:
354354 {
355355 return m_needsActivation;
356356 }
 357
 358 unsigned captureCount() const
 359 {
 360 if (!symbolTable())
 361 return 0;
 362 return symbolTable()->captureCount();
 363 }
 364
 365 int captureStart() const
 366 {
 367 if (!symbolTable())
 368 return 0;
 369 return symbolTable()->captureStart();
 370 }
 371
 372 int captureEnd() const
 373 {
 374 if (!symbolTable())
 375 return 0;
 376 return symbolTable()->captureEnd();
 377 }
357378
358379 bool isCaptured(VirtualRegister operand, InlineCallFrame* = 0) const;
359380
159352

Source/JavaScriptCore/bytecode/CodeOrigin.cpp

@@void InlineCallFrame::dumpInContext(Prin
116116 else
117117 out.print(", known callee: ", inContext(calleeRecovery.constant(), context));
118118 out.print(", numArgs+this = ", arguments.size());
119  out.print(", stack >= r", stackOffset);
 119 out.print(", stack < loc", VirtualRegister(stackOffset).toLocal());
120120 out.print(">");
121121}
122122
159352

Source/JavaScriptCore/bytecode/FullBytecodeLiveness.h

 1/*
 2 * Copyright (C) 2013 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 23 * THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef FullBytecodeLiveness_h
 27#define FullBytecodeLiveness_h
 28
 29#include <wtf/FastBitVector.h>
 30
 31namespace JSC {
 32
 33class BytecodeLivenessAnalysis;
 34
 35typedef HashMap<unsigned, FastBitVector, WTF::IntHash<unsigned>, WTF::UnsignedWithZeroKeyHashTraits<unsigned> > BytecodeToBitmapMap;
 36
 37class FullBytecodeLiveness {
 38public:
 39 FullBytecodeLiveness() : m_codeBlock(0) { }
 40
 41 // We say "out" to refer to the bitvector that contains raw results for a bytecode
 42 // instruction.
 43 const FastBitVector& getOut(unsigned bytecodeIndex) const
 44 {
 45 BytecodeToBitmapMap::const_iterator iter = m_map.find(bytecodeIndex);
 46 ASSERT(iter != m_map.end());
 47 return iter->value;
 48 }
 49
 50 bool operandIsLive(int operand, unsigned bytecodeIndex) const
 51 {
 52 return operandIsAlwaysLive(m_codeBlock, operand) || operandThatIsNotAlwaysLiveIsLive(m_codeBlock, getOut(bytecodeIndex), operand);
 53 }
 54
 55 FastBitVector getLiveness(unsigned bytecodeIndex) const
 56 {
 57 return getLivenessInfo(m_codeBlock, getOut(bytecodeIndex));
 58 }
 59
 60private:
 61 friend class BytecodeLivenessAnalysis;
 62
 63 CodeBlock* m_codeBlock;
 64 BytecodeToBitmapMap m_map;
 65};
 66
 67} // namespace JSC
 68
 69#endif // FullBytecodeLiveness_h
 70
0

Source/JavaScriptCore/dfg/DFGAvailability.cpp

 1/*
 2 * Copyright (C) 2013 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "DFGAvailability.h"
 28
 29#if ENABLE(DFG_JIT)
 30
 31#include "DFGNode.h"
 32
 33namespace JSC { namespace DFG {
 34
 35void Availability::dump(PrintStream& out) const
 36{
 37 out.print(m_flushedAt, "/");
 38
 39 if (nodeIsUndecided()) {
 40 out.print("Undecided");
 41 return;
 42 }
 43
 44 if (nodeIsUnavailable()) {
 45 out.print("Unavailable");
 46 return;
 47 }
 48
 49 out.print(node());
 50}
 51
 52void Availability::dumpInContext(PrintStream& out, DumpContext*) const
 53{
 54 dump(out);
 55}
 56
 57} } // namespace JSC::DFG
 58
 59#endif // ENABLE(DFG_JIT)
 60
0

Source/JavaScriptCore/dfg/DFGAvailability.h

 1/*
 2 * Copyright (C) 2013 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef DFGAvailability_h
 27#define DFGAvailability_h
 28
 29#if ENABLE(DFG_JIT)
 30
 31#include "DFGFlushedAt.h"
 32#include "DFGVariableAccessData.h"
 33
 34namespace JSC { namespace DFG {
 35
 36struct Node;
 37
 38class Availability {
 39public:
 40 Availability()
 41 : m_node(0)
 42 , m_flushedAt(DeadFlush)
 43 {
 44 }
 45
 46 explicit Availability(Node* node)
 47 : m_node(node)
 48 , m_flushedAt(ConflictingFlush)
 49 {
 50 }
 51
 52 explicit Availability(FlushedAt flushedAt)
 53 : m_node(unavailableMarker())
 54 , m_flushedAt(flushedAt)
 55 {
 56 }
 57
 58 Availability(Node* node, FlushedAt flushedAt)
 59 : m_node(node)
 60 , m_flushedAt(flushedAt)
 61 {
 62 }
 63
 64 static Availability unavailable()
 65 {
 66 return Availability(unavailableMarker(), FlushedAt(ConflictingFlush));
 67 }
 68
 69 Availability withFlush(FlushedAt flush) const
 70 {
 71 return Availability(m_node, flush);
 72 }
 73
 74 Availability withNode(Node* node) const
 75 {
 76 return Availability(node, m_flushedAt);
 77 }
 78
 79 Availability withUnavailableNode() const
 80 {
 81 return withNode(unavailableMarker());
 82 }
 83
 84 bool nodeIsUndecided() const { return !m_node; }
 85 bool nodeIsUnavailable() const { return m_node == unavailableMarker(); }
 86
 87 bool hasNode() const { return !nodeIsUndecided() && !nodeIsUnavailable(); }
 88
 89 Node* node() const
 90 {
 91 ASSERT(!nodeIsUndecided());
 92 ASSERT(!nodeIsUnavailable());
 93 return m_node;
 94 }
 95
 96 FlushedAt flushedAt() const { return m_flushedAt; }
 97
 98 bool operator!() const { return nodeIsUnavailable() && flushedAt().format() == ConflictingFlush; }
 99
 100 bool operator==(const Availability& other) const
 101 {
 102 return m_node == other.m_node
 103 && m_flushedAt == other.m_flushedAt;
 104 }
 105
 106 Availability merge(const Availability& other) const
 107 {
 108 return Availability(
 109 mergeNodes(m_node, other.m_node),
 110 m_flushedAt.merge(other.m_flushedAt));
 111 }
 112
 113 void dump(PrintStream&) const;
 114 void dumpInContext(PrintStream&, DumpContext*) const;
 115
 116private:
 117 static Node* mergeNodes(Node* a, Node* b)
 118 {
 119 if (!a)
 120 return b;
 121 if (!b)
 122 return a;
 123 if (a == b)
 124 return a;
 125 return unavailableMarker();
 126 }
 127
 128 static Node* unavailableMarker()
 129 {
 130 return bitwise_cast<Node*>(static_cast<intptr_t>(1));
 131 }
 132
 133 Node* m_node;
 134 FlushedAt m_flushedAt;
 135};
 136
 137} } // namespace JSC::DFG
 138
 139#endif // ENABLE(DFG_JIT)
 140
 141#endif // DFGAvailability_h
 142
0

Source/JavaScriptCore/dfg/DFGBasicBlock.h

2929#if ENABLE(DFG_JIT)
3030
3131#include "DFGAbstractValue.h"
 32#include "DFGAvailability.h"
3233#include "DFGBranchDirection.h"
3334#include "DFGFlushedAt.h"
3435#include "DFGNode.h"

@@struct BasicBlock : RefCounted<BasicBloc
140141 struct SSAData {
141142 Operands<FlushedAt> flushAtHead;
142143 Operands<FlushedAt> flushAtTail;
143  Operands<Node*> availabilityAtHead;
144  Operands<Node*> availabilityAtTail;
 144 Operands<Availability> availabilityAtHead;
 145 Operands<Availability> availabilityAtTail;
145146 HashSet<Node*> liveAtHead;
146147 HashSet<Node*> liveAtTail;
147148 HashMap<Node*, AbstractValue> valuesAtHead;
159352

Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

@@bool ByteCodeParser::parseBlock(unsigned
30733073 break;
30743074 }
30753075 Node* base = cellConstantWithStructureCheck(globalObject, status.structureSet().singletonStructure());
 3076 addToGraph(Phantom, get(VirtualRegister(scope)));
30763077 if (JSValue specificValue = status.specificValue())
30773078 set(VirtualRegister(dst), cellConstant(specificValue.asCell()));
30783079 else

@@bool ByteCodeParser::parseBlock(unsigned
30813082 }
30823083 case GlobalVar:
30833084 case GlobalVarWithVarInjectionChecks: {
 3085 addToGraph(Phantom, get(VirtualRegister(scope)));
30843086 SymbolTableEntry entry = globalObject->symbolTable()->get(uid);
30853087 if (!entry.couldBeWatched() || !m_graph.watchpoints().isStillValid(entry.watchpointSet())) {
30863088 set(VirtualRegister(dst), addToGraph(GetGlobalVar, OpInfo(operand), OpInfo(prediction)));

@@bool ByteCodeParser::parseBlock(unsigned
31313133 break;
31323134 }
31333135 Node* base = cellConstantWithStructureCheck(globalObject, status.oldStructure());
 3136 addToGraph(Phantom, get(VirtualRegister(scope)));
31343137 handlePutByOffset(base, identifierNumber, static_cast<PropertyOffset>(operand), get(VirtualRegister(value)));
31353138 // Keep scope alive until after put.
31363139 addToGraph(Phantom, get(VirtualRegister(scope)));

@@bool ByteCodeParser::parseBlock(unsigned
31383141 }
31393142 case GlobalVar:
31403143 case GlobalVarWithVarInjectionChecks: {
 3144 addToGraph(Phantom, get(VirtualRegister(scope)));
31413145 SymbolTableEntry entry = globalObject->symbolTable()->get(uid);
31423146 ASSERT(!entry.couldBeWatched() || !m_graph.watchpoints().isStillValid(entry.watchpointSet()));
31433147 addToGraph(PutGlobalVar, OpInfo(operand), get(VirtualRegister(value)));
159352

Source/JavaScriptCore/dfg/DFGDisassembler.cpp

@@namespace JSC { namespace DFG {
3838Disassembler::Disassembler(Graph& graph)
3939 : m_graph(graph)
4040{
 41 m_dumpContext.graph = &m_graph;
4142 m_labelForBlockIndex.resize(graph.numBlocks());
4243}
4344
159352

Source/JavaScriptCore/dfg/DFGFlushFormat.cpp

@@void printInternal(PrintStream& out, Flu
5656 case FlushedJSValue:
5757 out.print("FlushedJSValue");
5858 return;
 59 case ConflictingFlush:
 60 out.print("ConflictingFlush");
 61 return;
5962 }
6063 RELEASE_ASSERT_NOT_REACHED();
6164}
159352

Source/JavaScriptCore/dfg/DFGFlushFormat.h

@@enum FlushFormat {
4545 FlushedDouble,
4646 FlushedCell,
4747 FlushedBoolean,
48  FlushedJSValue
 48 FlushedJSValue,
 49 ConflictingFlush
4950};
5051
5152inline NodeFlags resultFor(FlushFormat format)

@@inline NodeFlags resultFor(FlushFormat f
5455 case DeadFlush:
5556 case FlushedJSValue:
5657 case FlushedCell:
 58 case ConflictingFlush:
5759 return NodeResultJS;
5860 case FlushedInt32:
5961 return NodeResultInt32;

@@inline UseKind useKindFor(FlushFormat fo
7375 switch (format) {
7476 case DeadFlush:
7577 case FlushedJSValue:
 78 case ConflictingFlush:
7679 return UntypedUse;
7780 case FlushedCell:
7881 return CellUse;

@@inline DataFormat dataFormatFor(FlushFor
9396{
9497 switch (format) {
9598 case DeadFlush:
 99 case ConflictingFlush:
96100 return DataFormatDead;
97101 case FlushedJSValue:
98102 return DataFormatJS;
159352

Source/JavaScriptCore/dfg/DFGFlushedAt.cpp

@@namespace JSC { namespace DFG {
3232
3333void FlushedAt::dump(PrintStream& out) const
3434{
35  if (m_format == DeadFlush)
 35 if (m_format == DeadFlush || m_format == ConflictingFlush)
3636 out.print(m_format);
3737 else
3838 out.print("r", m_virtualRegister, ":", m_format);
159352

Source/JavaScriptCore/dfg/DFGFlushedAt.h

@@public:
4242 {
4343 }
4444
 45 explicit FlushedAt(FlushFormat format)
 46 : m_format(format)
 47 {
 48 ASSERT(format == DeadFlush || format == ConflictingFlush);
 49 }
 50
4551 FlushedAt(FlushFormat format, VirtualRegister virtualRegister)
4652 : m_format(format)
4753 , m_virtualRegister(virtualRegister)

@@public:
6571
6672 bool operator!=(const FlushedAt& other) const { return !(*this == other); }
6773
 74 FlushedAt merge(const FlushedAt& other) const
 75 {
 76 if (!*this)
 77 return other;
 78 if (!other)
 79 return *this;
 80 if (*this == other)
 81 return *this;
 82 return FlushedAt(ConflictingFlush);
 83 }
 84
6885 void dump(PrintStream&) const;
6986 void dumpInContext(PrintStream&, DumpContext*) const;
7087
159352

Source/JavaScriptCore/dfg/DFGGraph.cpp

2626#include "config.h"
2727#include "DFGGraph.h"
2828
 29#include "BytecodeLivenessAnalysisInlines.h"
2930#include "CodeBlock.h"
3031#include "CodeBlockWithJITType.h"
3132#include "DFGClobberSet.h"
3233#include "DFGJITCode.h"
3334#include "DFGVariableAccessDataDump.h"
 35#include "FullBytecodeLiveness.h"
3436#include "FunctionExecutableDump.h"
3537#include "OperandsInlines.h"
3638#include "Operations.h"

@@void Graph::dumpBlockHeader(PrintStream&
393395void Graph::dump(PrintStream& out, DumpContext* context)
394396{
395397 DumpContext myContext;
 398 myContext.graph = this;
396399 if (!context)
397400 context = &myContext;
398401

@@void Graph::initializeNodeOwners()
643646 block->at(nodeIndex)->misc.owner = block;
644647 }
645648}
 649
 650FullBytecodeLiveness& Graph::livenessFor(CodeBlock* codeBlock)
 651{
 652 HashMap<CodeBlock*, std::unique_ptr<FullBytecodeLiveness>>::iterator iter = m_bytecodeLiveness.find(codeBlock);
 653 if (iter != m_bytecodeLiveness.end())
 654 return *iter->value;
 655
 656 std::unique_ptr<FullBytecodeLiveness> liveness = std::make_unique<FullBytecodeLiveness>();
 657 codeBlock->livenessAnalysis().computeFullLiveness(*liveness);
 658 FullBytecodeLiveness& result = *liveness;
 659 m_bytecodeLiveness.add(codeBlock, std::move(liveness));
 660 return result;
 661}
 662
 663FullBytecodeLiveness& Graph::livenessFor(InlineCallFrame* inlineCallFrame)
 664{
 665 return livenessFor(baselineCodeBlockFor(inlineCallFrame));
 666}
 667
 668bool Graph::isLiveInBytecode(VirtualRegister operand, CodeOrigin codeOrigin)
 669{
 670 for (;;) {
 671 if (operand.offset() < codeOrigin.stackOffset() + JSStack::CallFrameHeaderSize) {
 672 VirtualRegister reg = VirtualRegister(
 673 operand.offset() - codeOrigin.stackOffset());
 674
 675 if (reg.isArgument()) {
 676 RELEASE_ASSERT(reg.offset() < JSStack::CallFrameHeaderSize);
 677
 678 if (!codeOrigin.inlineCallFrame->isClosureCall)
 679 return false;
 680
 681 if (reg.offset() == JSStack::Callee)
 682 return true;
 683 if (reg.offset() == JSStack::ScopeChain)
 684 return true;
 685
 686 return false;
 687 }
 688
 689 return livenessFor(codeOrigin.inlineCallFrame).operandIsLive(
 690 reg.offset(), codeOrigin.bytecodeIndex);
 691 }
 692
 693 if (!codeOrigin.inlineCallFrame)
 694 break;
 695
 696 codeOrigin = codeOrigin.inlineCallFrame->caller;
 697 }
 698
 699 return true;
 700}
646701
647702} } // namespace JSC::DFG
648703
159352

Source/JavaScriptCore/dfg/DFGGraph.h

@@public:
416416 return executableFor(codeOrigin.inlineCallFrame);
417417 }
418418
 419 CodeBlock* baselineCodeBlockFor(InlineCallFrame* inlineCallFrame)
 420 {
 421 if (!inlineCallFrame)
 422 return m_profiledBlock;
 423 return baselineCodeBlockForInlineCallFrame(inlineCallFrame);
 424 }
 425
419426 CodeBlock* baselineCodeBlockFor(const CodeOrigin& codeOrigin)
420427 {
421428 return baselineCodeBlockForOriginAndBaselineCodeBlock(codeOrigin, m_profiledBlock);

@@public:
776783 DesiredWatchpoints& watchpoints() { return m_plan.watchpoints; }
777784 DesiredStructureChains& chains() { return m_plan.chains; }
778785
 786 FullBytecodeLiveness& livenessFor(CodeBlock*);
 787 FullBytecodeLiveness& livenessFor(InlineCallFrame*);
 788 bool isLiveInBytecode(VirtualRegister, CodeOrigin);
 789
779790 VM& m_vm;
780791 Plan& m_plan;
781792 CodeBlock* m_codeBlock;

@@public:
797808 SegmentedVector<SwitchData, 4> m_switchData;
798809 Vector<InlineVariableData, 4> m_inlineVariableData;
799810 OwnPtr<InlineCallFrameSet> m_inlineCallFrames;
 811 HashMap<CodeBlock*, std::unique_ptr<FullBytecodeLiveness>> m_bytecodeLiveness;
800812 bool m_hasArguments;
801813 HashSet<ExecutableBase*> m_executablesWhoseArgumentsEscaped;
802814 BitVector m_lazyVars;
159352

Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp

@@public:
4747 {
4848 ASSERT(m_graph.m_form == SSA);
4949
50  Vector<BasicBlock*> depthFirst;
51  m_graph.getBlocksInDepthFirstOrder(depthFirst);
 50 for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
 51 BasicBlock* block = m_graph.block(blockIndex);
 52 if (!block)
 53 continue;
 54 block->ssa->availabilityAtHead.fill(Availability());
 55 block->ssa->availabilityAtTail.fill(Availability());
 56 }
5257
53  for (unsigned i = 0; i < depthFirst.size(); ++i) {
54  BasicBlock* block = depthFirst[i];
55  block->ssa->availabilityAtHead.fill(0);
56  block->ssa->availabilityAtTail.fill(0);
 58 BasicBlock* root = m_graph.block(0);
 59 for (unsigned argument = root->ssa->availabilityAtHead.numberOfArguments(); argument--;) {
 60 root->ssa->availabilityAtHead.argument(argument) =
 61 Availability::unavailable().withFlush(
 62 FlushedAt(FlushedJSValue, virtualRegisterForArgument(argument)));
5763 }
 64 for (unsigned local = root->ssa->availabilityAtHead.numberOfLocals(); local--;)
 65 root->ssa->availabilityAtHead.local(local) = Availability::unavailable();
5866
59  for (unsigned i = 0; i < depthFirst.size(); ++i) {
60  BasicBlock* block = depthFirst[i];
61 
62  // We edit availabilityAtTail in-place, but first initialize it to
63  // availabilityAtHead.
64  Operands<Node*>& availability = block->ssa->availabilityAtTail;
65  availability = block->ssa->availabilityAtHead;
66 
67  for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
68  Node* node = block->at(nodeIndex);
69  switch (node->op()) {
70  case SetLocal:
71  case MovHint:
72  case MovHintAndCheck: {
73  availability.operand(node->local()) = node->child1().node();
74  break;
75  }
76 
77  case ZombieHint: {
78  availability.operand(node->local()) = 0;
79  break;
80  }
81 
82  case GetArgument: {
83  availability.operand(node->local()) = node;
84  break;
85  }
86 
87  default:
88  break;
89  }
 67 if (m_graph.m_plan.mode == FTLForOSREntryMode) {
 68 for (unsigned local = m_graph.m_profiledBlock->m_numCalleeRegisters; local--;) {
 69 root->ssa->availabilityAtHead.local(local) =
 70 Availability::unavailable().withFlush(
 71 FlushedAt(FlushedJSValue, virtualRegisterForLocal(local)));
9072 }
 73 }
 74
 75 // This could be made more efficient by processing blocks in reverse postorder.
 76 Operands<Availability> availability;
 77 bool changed;
 78 do {
 79 changed = false;
9180
92  for (unsigned j = block->numSuccessors(); j--;) {
93  BasicBlock* successor = block->successor(j);
94  Operands<Node*>& successorAvailability = successor->ssa->availabilityAtHead;
95  for (unsigned k = availability.size(); k--;) {
96  Node* myNode = availability[k];
97  if (!myNode)
98  continue;
99 
100  if (!successor->ssa->liveAtHead.contains(myNode))
101  continue;
102 
103  // Note that this may overwrite availability with a bogus node
104  // at merge points. This is fine, since merge points have
105  // MovHint(Phi)'s to work around this. The outcome of this is
106  // you might have a program in which a node happens to remain
107  // live into some block B, and separately (due to copy
108  // propagation) just one of the predecessors of B issued a
109  // MovHint putting that node into some local. Then in B we might
110  // think that that node is a valid value for that local. Of
111  // course if that local was actually live in B, B would have a
112  // Phi for it. So essentially we'll have OSR exit dropping this
113  // node's value into the local when we otherwise (in the DFG)
114  // would have dropped undefined into the local. This seems
115  // harmless.
116 
117  successorAvailability[k] = myNode;
 81 for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
 82 BasicBlock* block = m_graph.block(blockIndex);
 83 if (!block)
 84 continue;
 85
 86 availability = block->ssa->availabilityAtHead;
 87
 88 for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
 89 Node* node = block->at(nodeIndex);
 90
 91 switch (node->op()) {
 92 case SetLocal: {
 93 VariableAccessData* variable = node->variableAccessData();
 94 availability.operand(variable->local()) =
 95 Availability(node->child1().node(), variable->flushedAt());
 96 break;
 97 }
 98
 99 case GetArgument: {
 100 VariableAccessData* variable = node->variableAccessData();
 101 availability.operand(variable->local()) =
 102 Availability(node, variable->flushedAt());
 103 break;
 104 }
 105
 106 case MovHint:
 107 case MovHintAndCheck: {
 108 VariableAccessData* variable = node->variableAccessData();
 109 availability.operand(variable->local()) =
 110 Availability(node->child1().node());
 111 break;
 112 }
 113
 114 case ZombieHint: {
 115 VariableAccessData* variable = node->variableAccessData();
 116 availability.operand(variable->local()) = Availability::unavailable();
 117 break;
 118 }
 119
 120 default:
 121 break;
 122 }
 123 }
 124
 125 if (availability == block->ssa->availabilityAtTail)
 126 continue;
 127
 128 block->ssa->availabilityAtTail = availability;
 129 changed = true;
 130
 131 for (unsigned successorIndex = block->numSuccessors(); successorIndex--;) {
 132 BasicBlock* successor = block->successor(successorIndex);
 133 for (unsigned i = availability.size(); i--;) {
 134 successor->ssa->availabilityAtHead[i] = availability[i].merge(
 135 successor->ssa->availabilityAtHead[i]);
 136 }
118137 }
119138 }
120  }
 139 } while (changed);
121140
122141 return true;
123142 }
159352

Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.h

@@namespace JSC { namespace DFG {
3636
3737class Graph;
3838
39 // Computes BasicBlock::ssa->availabiltiyAtHead/Tail. This relies on liveness
40 // analysis phase having been run and the graph not having been transformed
41 // after that.
 39// Computes BasicBlock::ssa->availabiltiyAtHead/Tail. This is a forward flow type inference
 40// over MovHints and SetLocals.
4241
4342bool performOSRAvailabilityAnalysis(Graph&);
4443
159352

Source/JavaScriptCore/dfg/DFGPlan.cpp

5050#include "DFGOSREntrypointCreationPhase.h"
5151#include "DFGPredictionInjectionPhase.h"
5252#include "DFGPredictionPropagationPhase.h"
 53#include "DFGResurrectionForValidationPhase.h"
5354#include "DFGSSAConversionPhase.h"
5455#include "DFGStackLayoutPhase.h"
5556#include "DFGTierUpCheckInjectionPhase.h"

@@Plan::CompilationPath Plan::compileInThr
268269 performLICM(dfg);
269270 performLivenessAnalysis(dfg);
270271 performCFA(dfg);
 272 if (Options::validateFTLOSRExitLiveness())
 273 performResurrectionForValidation(dfg);
271274 performDCE(dfg); // We rely on this to convert dead SetLocals into the appropriate hint, and to kill dead code that won't be recognized as dead by LLVM.
272275 performStackLayout(dfg);
273276 performLivenessAnalysis(dfg);
159352

Source/JavaScriptCore/dfg/DFGResurrectionForValidationPhase.cpp

 1/*
 2 * Copyright (C) 2013 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "DFGResurrectionForValidationPhase.h"
 28
 29#if ENABLE(DFG_JIT)
 30
 31#include "DFGBasicBlockInlines.h"
 32#include "DFGGraph.h"
 33#include "DFGInsertionSet.h"
 34#include "DFGPhase.h"
 35#include "Operations.h"
 36
 37namespace JSC { namespace DFG {
 38
 39class ResurrectionForValidationPhase : public Phase {
 40public:
 41 ResurrectionForValidationPhase(Graph& graph)
 42 : Phase(graph, "resurrection for validation")
 43 {
 44 }
 45
 46 bool run()
 47 {
 48 InsertionSet insertionSet(m_graph);
 49
 50 for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
 51 BasicBlock* block = m_graph.block(blockIndex);
 52 if (!block)
 53 continue;
 54
 55 for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
 56 Node* node = block->at(nodeIndex);
 57 if (!node->hasResult())
 58 continue;
 59 insertionSet.insertNode(
 60 nodeIndex + 1, SpecNone, Phantom, node->codeOrigin, Edge(node));
 61 }
 62
 63 insertionSet.execute(block);
 64 }
 65
 66 return true;
 67 }
 68};
 69
 70bool performResurrectionForValidation(Graph& graph)
 71{
 72 SamplingRegion samplingRegion("DFG Resurrection For Validation Phase");
 73 return runPhase<ResurrectionForValidationPhase>(graph);
 74}
 75
 76} } // namespace JSC::DFG
 77
 78#endif // ENABLE(DFG_JIT)
 79
0

Source/JavaScriptCore/dfg/DFGResurrectionForValidationPhase.h

 1/*
 2 * Copyright (C) 2013 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef DFGResurrectionForValidationPhase_h
 27#define DFGResurrectionForValidationPhase_h
 28
 29#include <wtf/Platform.h>
 30
 31#if ENABLE(DFG_JIT)
 32
 33#include "DFGCommon.h"
 34
 35namespace JSC { namespace DFG {
 36
 37class Graph;
 38
 39// Places a Phantom after every value-producing node, thereby disabling DCE from killing it.
 40// This is useful for validating our OSR exit machinery by instituting the requirement that
 41// any live-in-bytecode variable should be OSR-available. Without this phase, it's impossible
 42// to make such an assertion because our DCE is more aggressive than the bytecode liveness
 43// analysis.
 44
 45bool performResurrectionForValidation(Graph&);
 46
 47} } // namespace JSC::DFG
 48
 49#endif // ENABLE(DFG_JIT)
 50
 51#endif // DFGResurrectionForValidationPhase_h
 52
0

Source/JavaScriptCore/dfg/DFGSSAConversionPhase.cpp

@@public:
158158 for (unsigned j = block->predecessors.size(); j--;) {
159159 BasicBlock* predecessor = block->predecessors[j];
160160 predecessor->appendNonTerminal(
161  m_graph, SpecNone, Upsilon, block->last()->codeOrigin,
 161 m_graph, SpecNone, Upsilon, predecessor->last()->codeOrigin,
162162 OpInfo(node), Edge(predecessor->variablesAtTail[i], useKind));
163163 }
164164
165  m_insertionSet.insertNode(
166  0, SpecNone, MovHint, node->codeOrigin, OpInfo(variable),
167  Edge(node));
 165 if (m_flushedLocalOps.contains(node)) {
 166 // Do nothing. For multiple reasons.
 167
 168 // Reason #1: If the local is flushed then we don't need to bother
 169 // with a MovHint since every path to this point in the code will
 170 // have flushed the bytecode variable using a SetLocal and hence
 171 // the Availability::flushedAt() will agree, and that will be
 172 // sufficient for figuring out how to recover the variable's value.
 173
 174 // Reason #2: If we had inserted a MovHint and the Phi function had
 175 // died (because the only user of the value was the "flush" - i.e.
 176 // some asynchronous runtime thingy) then the MovHint would turn
 177 // into a ZombieHint, which would fool us into thinking that the
 178 // variable is dead.
 179
 180 // Reason #3: If we had inserted a MovHint then even if the Phi
 181 // stayed alive, we would still end up generating inefficient code
 182 // since we would be telling the OSR exit compiler to use some SSA
 183 // value for the bytecode variable rather than just telling it that
 184 // the value was already on the stack.
 185 } else {
 186 m_insertionSet.insertNode(
 187 0, SpecNone, MovHint, node->codeOrigin, OpInfo(variable),
 188 Edge(node));
 189 }
168190 }
169191 }
170192
159352

Source/JavaScriptCore/dfg/DFGValueSource.h

@@public:
145145 {
146146 switch (format) {
147147 case DeadFlush:
 148 case ConflictingFlush:
148149 return ValueSource(SourceIsDead);
149150 case FlushedJSValue:
150151 return ValueSource(ValueInJSStack, where);
159352

Source/JavaScriptCore/dfg/DFGVariableAccessData.h

2626#ifndef DFGVariableAccessData_h
2727#define DFGVariableAccessData_h
2828
 29#include "DFGCommon.h"
2930#include "DFGDoubleFormatState.h"
3031#include "DFGFlushFormat.h"
3132#include "DFGFlushedAt.h"

3940
4041namespace JSC { namespace DFG {
4142
 43struct Node;
 44
4245enum DoubleBallot { VoteValue, VoteDouble };
4346
4447class VariableAccessData : public UnionFind<VariableAccessData> {
159352

Source/JavaScriptCore/ftl/FTLExitValue.cpp

@@void ExitValue::dumpInContext(PrintStrea
4848 out.print("Constant(", inContext(constant(), context), ")");
4949 return;
5050 case ExitValueInJSStack:
51  out.print("InJSStack");
 51 out.print("InJSStack:r", virtualRegister());
5252 return;
5353 case ExitValueInJSStackAsInt32:
54  out.print("InJSStackAsInt32");
 54 out.print("InJSStackAsInt32:r", virtualRegister());
5555 return;
5656 case ExitValueInJSStackAsInt52:
57  out.print("InJSStackAsInt52");
 57 out.print("InJSStackAsInt52:r", virtualRegister());
5858 return;
5959 case ExitValueInJSStackAsDouble:
60  out.print("InJSStackAsDouble");
 60 out.print("InJSStackAsDouble:r", virtualRegister());
6161 return;
6262 }
6363
159352

Source/JavaScriptCore/ftl/FTLInlineCacheSize.cpp

@@namespace JSC { namespace FTL {
3939
4040size_t sizeOfGetById()
4141{
42  return 29;
 42 return 30;
4343}
4444
4545size_t sizeOfPutById()
159352

Source/JavaScriptCore/ftl/FTLLocation.cpp

@@GPRReg Location::gpr() const
9292 // for example, the architecture encodes CX as 1 and DX as 2 while Dwarf does the
9393 // opposite. Hence we need the switch.
9494
95  ASSERT(involvesGPR());
 95 RELEASE_ASSERT(involvesGPR());
9696
9797 switch (dwarfRegNum()) {
9898 case 0:

@@bool Location::isFPR() const
125125
126126FPRReg Location::fpr() const
127127{
128  ASSERT(isFPR());
 128 RELEASE_ASSERT(isFPR());
129129 return static_cast<FPRReg>(dwarfRegNum() - 17);
130130}
131131

@@void Location::restoreInto(MacroAssemble
200200
201201GPRReg Location::directGPR() const
202202{
203  ASSERT(!addend());
 203 RELEASE_ASSERT(!addend());
204204 return gpr();
205205}
206206
159352

Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp

3838#include "FTLLoweredNodeValue.h"
3939#include "FTLOutput.h"
4040#include "FTLThunks.h"
41 #include "FTLValueSource.h"
4241#include "LinkBuffer.h"
4342#include "OperandsInlines.h"
4443#include "Operations.h"

@@public:
7069 , m_ftlState(state)
7170 , m_heaps(state.context)
7271 , m_out(state.context)
73  , m_valueSources(OperandsLike, state.graph.block(0)->variablesAtHead)
 72 , m_availability(OperandsLike, state.graph.block(0)->variablesAtHead)
7473 , m_state(state.graph)
7574 , m_interpreter(state.graph, m_state)
7675 , m_stackmapIDs(0)

@@private:
204203
205204 initializeOSRExitStateForBlock();
206205
207  m_live = block->ssa->liveAtHead;
208 
209206 m_state.reset();
210207 m_state.beginBasicBlock(m_highBlock);
211208

@@private:
475472 break;
476473 }
477474
478  if (m_node->shouldGenerate())
479  DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, use);
480 
481  if (m_node->adjustedRefCount())
482  m_live.add(m_node);
483 
484475 if (shouldExecuteEffects)
485476 m_interpreter.executeEffects(nodeIndex);
486477

@@private:
619610 case FlushedJSValue: {
620611 LValue value = lowJSValue(m_node->child1());
621612 m_out.store64(value, addressFor(variable->machineLocal()));
622  m_valueSources.operand(variable->local()) = ValueSource(ValueInJSStack, variable->machineLocal());
623  return;
 613 break;
624614 }
625615
626616 case FlushedDouble: {
627617 LValue value = lowDouble(m_node->child1());
628618 m_out.storeDouble(value, addressFor(variable->machineLocal()));
629  m_valueSources.operand(variable->local()) = ValueSource(DoubleInJSStack, variable->machineLocal());
630  return;
 619 break;
631620 }
632621
633622 case FlushedInt32: {
634623 LValue value = lowInt32(m_node->child1());
635624 m_out.store32(value, payloadFor(variable->machineLocal()));
636  m_valueSources.operand(variable->local()) = ValueSource(Int32InJSStack, variable->machineLocal());
637  return;
 625 break;
638626 }
639627
640628 case FlushedInt52: {
641629 LValue value = lowInt52(m_node->child1());
642630 m_out.store64(value, addressFor(variable->machineLocal()));
643  m_valueSources.operand(variable->local()) = ValueSource(Int52InJSStack, variable->machineLocal());
644  return;
 631 break;
645632 }
646633
647634 case FlushedCell: {
648635 LValue value = lowCell(m_node->child1());
649636 m_out.store64(value, addressFor(variable->machineLocal()));
650  m_valueSources.operand(variable->local()) = ValueSource(ValueInJSStack, variable->machineLocal());
651  return;
 637 break;
652638 }
653639
654640 case FlushedBoolean: {

@@private:
656642 m_out.store64(
657643 lowJSValue(m_node->child1(), ManualOperandSpeculation),
658644 addressFor(variable->machineLocal()));
659  m_valueSources.operand(variable->local()) = ValueSource(ValueInJSStack, variable->machineLocal());
660  return;
 645 break;
661646 }
662647
663  case DeadFlush:
 648 default:
664649 RELEASE_ASSERT_NOT_REACHED();
 650 break;
665651 }
666652
667  RELEASE_ASSERT_NOT_REACHED();
 653 m_availability.operand(variable->local()) = Availability(variable->flushedAt());
668654 }
669655
670656 void compileMovHint()

@@private:
675661 void compileZombieHint()
676662 {
677663 VariableAccessData* data = m_node->variableAccessData();
678  m_valueSources.operand(data->local()) = ValueSource(SourceIsDead);
 664 m_availability.operand(data->local()) = Availability::unavailable();
679665 }
680666
681667 void compileMovHintAndCheck()

@@private:
12871273 {
12881274 // See above; CellUse is easier so we do only that for now.
12891275 ASSERT(m_node->child1().useKind() == CellUse);
1290 
 1276
12911277 LValue base = lowCell(m_node->child1());
12921278 LValue value = lowJSValue(m_node->child2());
12931279 StringImpl* uid = m_graph.identifiers()[m_node->identifierNumber()];

@@private:
25442530 void compileInvalidationPoint()
25452531 {
25462532 if (verboseCompilationEnabled())
2547  dataLog(" Invalidation point with value sources: ", m_valueSources, "\n");
 2533 dataLog(" Invalidation point with availability: ", m_availability, "\n");
25482534
25492535 m_ftlState.jitCode->osrExit.append(OSRExit(
25502536 UncountableInvalidation, InvalidValueFormat, MethodOfGettingAValueProfile(),
25512537 m_codeOriginForExitTarget, m_codeOriginForExitProfile,
2552  m_valueSources.numberOfArguments(), m_valueSources.numberOfLocals()));
 2538 m_availability.numberOfArguments(), m_availability.numberOfLocals()));
25532539 m_ftlState.finalizer->osrExit.append(OSRExitCompilationInfo());
25542540
25552541 OSRExit& exit = m_ftlState.jitCode->osrExit.last();

@@private:
25572543
25582544 ExitArgumentList arguments;
25592545
2560  buildExitArguments(exit, arguments, FormattedValue());
 2546 buildExitArguments(exit, arguments, FormattedValue(), exit.m_codeOrigin);
25612547 callStackmap(exit, arguments);
25622548
25632549 info.m_isInvalidationPoint = true;

@@private:
38223808 m_out.appendTo(continuation, lastNext);
38233809 }
38243810
3825  bool isLive(Node* node)
3826  {
3827  return m_live.contains(node);
3828  }
3829 
3830  void use(Edge edge)
3831  {
3832  ASSERT(edge->hasResult());
3833  if (!edge.doesKill())
3834  return;
3835  m_live.remove(edge.node());
3836  }
3837 
3838  // Wrapper used only for DFG_NODE_DO_TO_CHILDREN
3839  void use(Node*, Edge edge)
3840  {
3841  use(edge);
3842  }
3843 
38443811 LBasicBlock lowBlock(BasicBlock* block)
38453812 {
38463813 return m_blocks.get(block);

@@private:
38483815
38493816 void initializeOSRExitStateForBlock()
38503817 {
3851  for (unsigned i = m_valueSources.size(); i--;) {
3852  FlushedAt flush = m_highBlock->ssa->flushAtHead[i];
3853  switch (flush.format()) {
3854  case DeadFlush: {
3855  // Must consider available nodes instead.
3856  Node* node = m_highBlock->ssa->availabilityAtHead[i];
3857  if (!node) {
3858  m_valueSources[i] = ValueSource(SourceIsDead);
3859  break;
3860  }
3861 
3862  m_valueSources[i] = ValueSource(node);
3863  break;
3864  }
3865 
3866  case FlushedInt32:
3867  m_valueSources[i] = ValueSource(Int32InJSStack, flush.virtualRegister());
3868  break;
3869 
3870  case FlushedInt52:
3871  m_valueSources[i] = ValueSource(Int52InJSStack, flush.virtualRegister());
3872  break;
3873 
3874  case FlushedDouble:
3875  m_valueSources[i] = ValueSource(DoubleInJSStack, flush.virtualRegister());
3876  break;
3877 
3878  case FlushedCell:
3879  case FlushedBoolean:
3880  case FlushedJSValue:
3881  m_valueSources[i] = ValueSource(ValueInJSStack, flush.virtualRegister());
3882  break;
3883  }
3884  }
 3818 m_availability = m_highBlock->ssa->availabilityAtHead;
38853819 }
38863820
38873821 void appendOSRExit(

@@private:
38893823 SpeculationDirection direction, FormattedValue recovery)
38903824 {
38913825 if (verboseCompilationEnabled())
3892  dataLog(" OSR exit with value sources: ", m_valueSources, "\n");
3893 
 3826 dataLog(" OSR exit #", m_ftlState.jitCode->osrExit.size(), " with availability: ", m_availability, "\n");
 3827
38943828 ASSERT(m_ftlState.jitCode->osrExit.size() == m_ftlState.finalizer->osrExit.size());
38953829
38963830 m_ftlState.jitCode->osrExit.append(OSRExit(
38973831 kind, lowValue.format(), m_graph.methodOfGettingAValueProfileFor(highValue),
38983832 m_codeOriginForExitTarget, m_codeOriginForExitProfile,
3899  m_valueSources.numberOfArguments(), m_valueSources.numberOfLocals()));
 3833 m_availability.numberOfArguments(), m_availability.numberOfLocals()));
39003834 m_ftlState.finalizer->osrExit.append(OSRExitCompilationInfo());
39013835
39023836 OSRExit& exit = m_ftlState.jitCode->osrExit.last();

@@private:
39243858 {
39253859 ExitArgumentList arguments;
39263860
3927  buildExitArguments(exit, arguments, lowValue);
 3861 CodeOrigin codeOrigin = exit.m_codeOrigin;
39283862
3929  if (direction == ForwardSpeculation) {
3930  ASSERT(m_node);
 3863 if (direction == BackwardSpeculation)
 3864 buildExitArguments(exit, arguments, lowValue, codeOrigin);
 3865 else {
 3866 ASSERT(direction == ForwardSpeculation);
 3867 if (!recovery) {
 3868 for (unsigned nodeIndex = m_nodeIndex; nodeIndex < m_highBlock->size(); ++nodeIndex) {
 3869 Node* node = m_highBlock->at(nodeIndex);
 3870 if (node->codeOriginForExitTarget == codeOrigin)
 3871 continue;
 3872 codeOrigin = node->codeOriginForExitTarget;
 3873 break;
 3874 }
 3875 }
 3876
 3877 buildExitArguments(exit, arguments, lowValue, codeOrigin);
39313878 exit.convertToForward(m_highBlock, m_node, m_nodeIndex, recovery, arguments);
39323879 }
39333880

@@private:
39353882 }
39363883
39373884 void buildExitArguments(
3938  OSRExit& exit, ExitArgumentList& arguments, FormattedValue lowValue)
 3885 OSRExit& exit, ExitArgumentList& arguments, FormattedValue lowValue,
 3886 CodeOrigin codeOrigin)
39393887 {
39403888 arguments.append(m_callFrame);
39413889 if (!!lowValue)
39423890 arguments.append(lowValue.value());
39433891
39443892 for (unsigned i = 0; i < exit.m_values.size(); ++i) {
3945  ValueSource source = m_valueSources[i];
 3893 int operand = exit.m_values.operandForIndex(i);
 3894 bool isLive = m_graph.isLiveInBytecode(VirtualRegister(operand), codeOrigin);
 3895 if (!isLive) {
 3896 exit.m_values[i] = ExitValue::dead();
 3897 continue;
 3898 }
39463899
3947  switch (source.kind()) {
3948  case ValueInJSStack:
3949  exit.m_values[i] = ExitValue::inJSStack(source.virtualRegister());
3950  break;
3951  case Int32InJSStack:
3952  exit.m_values[i] = ExitValue::inJSStackAsInt32(source.virtualRegister());
3953  break;
3954  case Int52InJSStack:
3955  exit.m_values[i] = ExitValue::inJSStackAsInt52(source.virtualRegister());
 3900 Availability availability = m_availability[i];
 3901 FlushedAt flush = availability.flushedAt();
 3902 switch (flush.format()) {
 3903 case DeadFlush:
 3904 case ConflictingFlush:
 3905 if (availability.hasNode()) {
 3906 addExitArgumentForNode(exit, arguments, i, availability.node());
 3907 break;
 3908 }
 3909
 3910 if (Options::validateFTLOSRExitLiveness()) {
 3911 dataLog("Expected r", operand, " to be available but it wasn't.\n");
 3912 RELEASE_ASSERT_NOT_REACHED();
 3913 }
 3914
 3915 // This means that the DFG's DCE proved that the value is dead in bytecode
 3916 // even though the bytecode liveness analysis thinks it's live. This is
 3917 // acceptable since the DFG's DCE is by design more aggressive while still
 3918 // being sound.
 3919 exit.m_values[i] = ExitValue::dead();
39563920 break;
3957  case DoubleInJSStack:
3958  exit.m_values[i] = ExitValue::inJSStackAsDouble(source.virtualRegister());
 3921
 3922 case FlushedJSValue:
 3923 case FlushedCell:
 3924 case FlushedBoolean:
 3925 exit.m_values[i] = ExitValue::inJSStack(flush.virtualRegister());
39593926 break;
3960  case SourceIsDead:
3961  exit.m_values[i] = ExitValue::dead();
 3927
 3928 case FlushedInt32:
 3929 exit.m_values[i] = ExitValue::inJSStackAsInt32(flush.virtualRegister());
39623930 break;
3963  case HaveNode:
3964  addExitArgumentForNode(exit, arguments, i, source.node());
 3931
 3932 case FlushedInt52:
 3933 exit.m_values[i] = ExitValue::inJSStackAsInt52(flush.virtualRegister());
39653934 break;
3966  default:
3967  RELEASE_ASSERT_NOT_REACHED();
 3935
 3936 case FlushedDouble:
 3937 exit.m_values[i] = ExitValue::inJSStackAsDouble(flush.virtualRegister());
39683938 break;
39693939 }
39703940 }

@@private:
39913961 if (tryToSetConstantExitArgument(exit, index, node))
39923962 return;
39933963
3994  if (!isLive(node)) {
3995  bool found = false;
3996 
3997  if (permitsOSRBackwardRewiring(node->op())) {
3998  node = node->child1().node();
3999  if (tryToSetConstantExitArgument(exit, index, node))
4000  return;
4001  if (isLive(node))
4002  found = true;
4003  }
4004 
4005  if (!found) {
4006  Node* bestNode = 0;
4007  unsigned bestScore = 0;
4008 
4009  HashSet<Node*>::iterator iter = m_live.begin();
4010  HashSet<Node*>::iterator end = m_live.end();
4011  for (; iter != end; ++iter) {
4012  Node* candidate = *iter;
4013  if (candidate->flags() & NodeHasVarArgs)
4014  continue;
4015  if (!candidate->child1())
4016  continue;
4017  if (candidate->child1() != node)
4018  continue;
4019  unsigned myScore = forwardRewiringSelectionScore(candidate->op());
4020  if (myScore <= bestScore)
4021  continue;
4022  bestNode = candidate;
4023  bestScore = myScore;
4024  }
4025 
4026  if (bestNode) {
4027  ASSERT(isLive(bestNode));
4028  node = bestNode;
4029  found = true;
4030  }
4031  }
4032 
4033  if (!found) {
4034  exit.m_values[index] = ExitValue::dead();
4035  return;
4036  }
4037  }
4038 
4039  ASSERT(isLive(node));
4040 
40413964 LoweredNodeValue value = m_int32Values.get(node);
40423965 if (isValid(value)) {
40433966 addExitArgument(exit, arguments, index, ValueFormatInt32, value.value());

@@private:
41144037
41154038 VirtualRegister operand = node->local();
41164039
4117  m_valueSources.operand(operand) = ValueSource(node->child1().node());
 4040 m_availability.operand(operand) = Availability(node->child1().node());
41184041 }
41194042
41204043 void setInt32(Node* node, LValue value)

@@private:
42724195 HashMap<Node*, LoweredNodeValue> m_booleanValues;
42734196 HashMap<Node*, LoweredNodeValue> m_storageValues;
42744197 HashMap<Node*, LoweredNodeValue> m_doubleValues;
4275  HashSet<Node*> m_live;
42764198
42774199 HashMap<Node*, LValue> m_phis;
42784200
4279  Operands<ValueSource> m_valueSources;
 4201 Operands<Availability> m_availability;
42804202
42814203 InPlaceAbstractState m_state;
42824204 AbstractInterpreter<InPlaceAbstractState> m_interpreter;
159352

Source/JavaScriptCore/ftl/FTLOutput.h

@@public:
199199 LValue intToPtr(LValue value, LType type) { return buildIntToPtr(m_builder, value, type); }
200200 LValue bitCast(LValue value, LType type) { return buildBitCast(m_builder, value, type); }
201201
 202 LValue alloca(LType type) { return buildAlloca(m_builder, type); }
202203 LValue get(LValue reference) { return buildLoad(m_builder, reference); }
203204 LValue set(LValue value, LValue reference) { return buildStore(m_builder, value, reference); }
204205
159352

Source/JavaScriptCore/ftl/FTLValueSource.cpp

1 /*
2  * Copyright (C) 2013 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #include "config.h"
27 #include "FTLValueSource.h"
28 
29 #if ENABLE(FTL_JIT)
30 
31 namespace JSC { namespace FTL {
32 
33 void ValueSource::dump(PrintStream& out) const
34 {
35  switch (kind()) {
36  case SourceNotSet:
37  out.print("SourceNotSet");
38  return;
39  case ValueInJSStack:
40  out.print("ValueInJSStack:", virtualRegister());
41  return;
42  case Int32InJSStack:
43  out.print("Int32InJSStack:", virtualRegister());
44  return;
45  case Int52InJSStack:
46  out.print("Int52InJSStack:", virtualRegister());
47  return;
48  case DoubleInJSStack:
49  out.print("DoubleInJSStack:", virtualRegister());
50  return;
51  case SourceIsDead:
52  out.print("SourceIsDead");
53  return;
54  case HaveNode:
55  out.print("Node(", node(), ")");
56  return;
57  }
58 
59  RELEASE_ASSERT_NOT_REACHED();
60 }
61 
62 void ValueSource::dumpInContext(PrintStream& out, DumpContext*) const
63 {
64  dump(out);
65 }
66 
67 } } // namespace JSC::FTL
68 
69 #endif // ENABLE(FTL_JIT)
70 
159352

Source/JavaScriptCore/ftl/FTLValueSource.h

1 /*
2  * Copyright (C) 2013 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #ifndef FTLValueSource_h
27 #define FTLValueSource_h
28 
29 #include <wtf/Platform.h>
30 
31 #if ENABLE(FTL_JIT)
32 
33 #include "DFGNode.h"
34 #include <wtf/PrintStream.h>
35 #include <wtf/StdLibExtras.h>
36 
37 namespace JSC { namespace FTL {
38 
39 enum ValueSourceKind {
40  SourceNotSet,
41  ValueInJSStack,
42  Int32InJSStack,
43  Int52InJSStack,
44  DoubleInJSStack,
45  SourceIsDead,
46  HaveNode
47 };
48 
49 class ValueSource {
50 public:
51  ValueSource()
52  : m_kind(SourceNotSet)
53  {
54  }
55 
56  explicit ValueSource(ValueSourceKind kind)
57  : m_kind(kind)
58  {
59  ASSERT(m_kind == SourceIsDead);
60  }
61 
62  explicit ValueSource(DFG::Node* node)
63  : m_kind(HaveNode)
64  {
65  m_value.node = node;
66  }
67 
68  ValueSource(ValueSourceKind kind, VirtualRegister reg)
69  : m_kind(kind)
70  {
71  ASSERT(m_kind == ValueInJSStack || m_kind == Int32InJSStack || m_kind == Int52InJSStack || m_kind == DoubleInJSStack);
72  m_value.virtualRegister = reg.offset();
73  }
74 
75  ValueSourceKind kind() const
76  {
77  return m_kind;
78  }
79 
80  bool operator!() const { return kind() == SourceNotSet; }
81 
82  DFG::Node* node() const
83  {
84  ASSERT(kind() == HaveNode);
85  return m_value.node;
86  }
87 
88  VirtualRegister virtualRegister() const
89  {
90  ASSERT(kind() == ValueInJSStack || kind() == Int32InJSStack || kind() == Int52InJSStack || kind() == DoubleInJSStack);
91  return VirtualRegister(m_value.virtualRegister);
92  }
93 
94  void dump(PrintStream&) const;
95  void dumpInContext(PrintStream&, DumpContext*) const;
96 
97 private:
98  ValueSourceKind m_kind;
99  union {
100  DFG::Node* node;
101  int virtualRegister;
102  } m_value;
103 };
104 
105 } } // namespace JSC::FTL
106 
107 #endif // ENABLE(FTL_JIT)
108 
109 #endif // FTLValueSource_h
110 
159352

Source/JavaScriptCore/llvm/LLVMAPIFunctions.h

535535 macro(LLVMBool, TargetHasJIT, (LLVMTargetRef T)) \
536536 macro(LLVMBool, TargetHasTargetMachine, (LLVMTargetRef T)) \
537537 macro(LLVMBool, TargetHasAsmBackend, (LLVMTargetRef T)) \
538  macro(LLVMTargetMachineRef, CreateTargetMachine, (LLVMTargetRef T, char *Triple, char *CPU, char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc, LLVMCodeModel CodeModel)) \
539538 macro(void, DisposeTargetMachine, (LLVMTargetMachineRef T)) \
540539 macro(LLVMTargetRef, GetTargetMachineTarget, (LLVMTargetMachineRef T)) \
541540 macro(char *, GetTargetMachineTriple, (LLVMTargetMachineRef T)) \
159352

Source/JavaScriptCore/runtime/DumpContext.cpp

2828
2929namespace JSC {
3030
31 DumpContext::DumpContext() { }
 31DumpContext::DumpContext()
 32 : graph(0)
 33{
 34}
 35
3236DumpContext::~DumpContext() { }
3337
3438bool DumpContext::isEmpty() const
159352

Source/JavaScriptCore/runtime/DumpContext.h

3232
3333namespace JSC {
3434
 35namespace DFG { class Graph; }
 36
3537struct DumpContext {
3638 DumpContext();
3739 ~DumpContext();

@@struct DumpContext {
4143 void dump(PrintStream&, const char* prefix = "") const;
4244
4345 StringHashDumpContext<Structure> structures;
 46 DFG::Graph* graph;
4447};
4548
4649} // namespace JSC
159352

Source/JavaScriptCore/runtime/Options.h

@@typedef OptionRange optionRange;
126126 v(bool, enableLLVMFastISel, false) \
127127 v(bool, useLLVMSmallCodeModel, false) \
128128 v(bool, dumpLLVMIR, false) \
 129 v(bool, validateFTLOSRExitLiveness, false) \
129130 v(bool, llvmAlwaysFailsBeforeCompile, false) \
130131 v(bool, llvmAlwaysFailsBeforeLink, false) \
131132 v(bool, llvmSimpleOpt, true) \
159352

Source/JavaScriptCore/runtime/SymbolTable.h

@@public:
469469 bool usesNonStrictEval() { return m_usesNonStrictEval; }
470470 void setUsesNonStrictEval(bool usesNonStrictEval) { m_usesNonStrictEval = usesNonStrictEval; }
471471
472  int captureStart() { return m_captureStart; }
 472 int captureStart() const { return m_captureStart; }
473473 void setCaptureStart(int captureStart) { m_captureStart = captureStart; }
474474
475  int captureEnd() { return m_captureEnd; }
 475 int captureEnd() const { return m_captureEnd; }
476476 void setCaptureEnd(int captureEnd) { m_captureEnd = captureEnd; }
477477
478  int captureCount() { return -(m_captureEnd - m_captureStart); }
 478 int captureCount() const { return -(m_captureEnd - m_captureStart); }
479479
480480 int parameterCount() { return m_parameterCountIncludingThis - 1; }
481481 int parameterCountIncludingThis() { return m_parameterCountIncludingThis; }
159352