| Differences between
and this patch
- Source/JavaScriptCore/ChangeLog +235 lines
Lines 1-3 Source/JavaScriptCore/ChangeLog_sec1
1
2014-09-22  Filip Pizlo  <fpizlo@apple.com>
2
3
        FTL should sink object allocations
4
        https://bugs.webkit.org/show_bug.cgi?id=136330
5
6
        Reviewed by NOBODY (OOPS!).
7
        
8
        Work in progress.
9
10
        * CMakeLists.txt:
11
        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
12
        * JavaScriptCore.xcodeproj/project.pbxproj:
13
        * bytecode/StructureSet.h:
14
        (JSC::StructureSet::iterator::iterator):
15
        (JSC::StructureSet::iterator::operator*):
16
        (JSC::StructureSet::iterator::operator++):
17
        (JSC::StructureSet::iterator::operator==):
18
        (JSC::StructureSet::iterator::operator!=):
19
        (JSC::StructureSet::begin):
20
        (JSC::StructureSet::end):
21
        * dfg/DFGAbstractInterpreter.h:
22
        (JSC::DFG::AbstractInterpreter::phiChildren):
23
        * dfg/DFGAbstractInterpreterInlines.h:
24
        (JSC::DFG::AbstractInterpreter<AbstractStateType>::AbstractInterpreter):
25
        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
26
        * dfg/DFGAvailability.h:
27
        (JSC::DFG::Availability::shouldUseNode):
28
        (JSC::DFG::Availability::isFlushUseful):
29
        (JSC::DFG::Availability::isDead):
30
        * dfg/DFGAvailabilityMap.cpp: Added.
31
        (JSC::DFG::AvailabilityMap::prune):
32
        (JSC::DFG::AvailabilityMap::dump):
33
        (JSC::DFG::AvailabilityMap::operator==):
34
        (JSC::DFG::AvailabilityMap::merge):
35
        * dfg/DFGAvailabilityMap.h: Added.
36
        (JSC::DFG::AvailabilityMap::forEachAvailability):
37
        * dfg/DFGBasicBlock.cpp:
38
        (JSC::DFG::BasicBlock::SSAData::SSAData):
39
        * dfg/DFGBasicBlock.h:
40
        (JSC::DFG::BasicBlock::begin):
41
        (JSC::DFG::BasicBlock::end):
42
        (JSC::DFG::BasicBlock::SuccessorsIterable::SuccessorsIterable):
43
        (JSC::DFG::BasicBlock::SuccessorsIterable::iterator::iterator):
44
        (JSC::DFG::BasicBlock::SuccessorsIterable::iterator::operator*):
45
        (JSC::DFG::BasicBlock::SuccessorsIterable::iterator::operator++):
46
        (JSC::DFG::BasicBlock::SuccessorsIterable::iterator::operator==):
47
        (JSC::DFG::BasicBlock::SuccessorsIterable::iterator::operator!=):
48
        (JSC::DFG::BasicBlock::SuccessorsIterable::begin):
49
        (JSC::DFG::BasicBlock::SuccessorsIterable::end):
50
        (JSC::DFG::BasicBlock::successors):
51
        * dfg/DFGClobberize.h:
52
        (JSC::DFG::clobberize):
53
        * dfg/DFGConstantFoldingPhase.cpp:
54
        (JSC::DFG::ConstantFoldingPhase::foldConstants):
55
        * dfg/DFGDoesGC.cpp:
56
        (JSC::DFG::doesGC):
57
        * dfg/DFGFixupPhase.cpp:
58
        (JSC::DFG::FixupPhase::fixupNode):
59
        * dfg/DFGGraph.cpp:
60
        (JSC::DFG::Graph::mergeRelevantToOSR):
61
        * dfg/DFGGraph.h:
62
        (JSC::DFG::Graph::NaturalBlockIterable::NaturalBlockIterable):
63
        (JSC::DFG::Graph::NaturalBlockIterable::iterator::iterator):
64
        (JSC::DFG::Graph::NaturalBlockIterable::iterator::operator*):
65
        (JSC::DFG::Graph::NaturalBlockIterable::iterator::operator++):
66
        (JSC::DFG::Graph::NaturalBlockIterable::iterator::operator==):
67
        (JSC::DFG::Graph::NaturalBlockIterable::iterator::operator!=):
68
        (JSC::DFG::Graph::NaturalBlockIterable::iterator::findNext):
69
        (JSC::DFG::Graph::NaturalBlockIterable::begin):
70
        (JSC::DFG::Graph::NaturalBlockIterable::end):
71
        (JSC::DFG::Graph::blocksInNaturalOrder):
72
        (JSC::DFG::Graph::doToChildrenWithNode):
73
        (JSC::DFG::Graph::doToChildEdges):
74
        (JSC::DFG::Graph::doToChildren):
75
        * dfg/DFGHeapLocation.cpp:
76
        (WTF::printInternal):
77
        * dfg/DFGHeapLocation.h:
78
        * dfg/DFGInsertOSRHintsForUpdate.cpp: Added.
79
        (JSC::DFG::insertOSRHintsForUpdate):
80
        * dfg/DFGInsertOSRHintsForUpdate.h: Added.
81
        * dfg/DFGInsertionSet.h:
82
        (JSC::DFG::InsertionSet::graph):
83
        * dfg/DFGNode.h:
84
        (JSC::DFG::Node::convertToPutByOffsetHint):
85
        (JSC::DFG::Node::convertToPutStructureHint):
86
        (JSC::DFG::Node::convertToPhantomNewObject):
87
        (JSC::DFG::Node::isCellConstant):
88
        (JSC::DFG::Node::hasIdentifier):
89
        (JSC::DFG::Node::hasTransition):
90
        (JSC::DFG::Node::hasStorageAccessData):
91
        (JSC::DFG::Node::hasObjectMaterializationData):
92
        (JSC::DFG::Node::objectMaterializationData):
93
        (JSC::DFG::Node::isPhantomObjectAllocation):
94
        * dfg/DFGNodeType.h:
95
        * dfg/DFGOSRAvailabilityAnalysisPhase.cpp:
96
        (JSC::DFG::OSRAvailabilityAnalysisPhase::run):
97
        (JSC::DFG::LocalOSRAvailabilityCalculator::endBlock):
98
        (JSC::DFG::LocalOSRAvailabilityCalculator::executeNode):
99
        * dfg/DFGOSRAvailabilityAnalysisPhase.h:
100
        * dfg/DFGObjectAllocationSinkingPhase.cpp: Added.
101
        (JSC::DFG::ObjectAllocationSinkingPhase::ObjectAllocationSinkingPhase):
102
        (JSC::DFG::ObjectAllocationSinkingPhase::run):
103
        (JSC::DFG::ObjectAllocationSinkingPhase::performSinking):
104
        (JSC::DFG::ObjectAllocationSinkingPhase::pruneSinkingCandidates):
105
        (JSC::DFG::ObjectAllocationSinkingPhase::determineMaterializationPoints):
106
        (JSC::DFG::ObjectAllocationSinkingPhase::placeMaterializationPoints):
107
        (JSC::DFG::ObjectAllocationSinkingPhase::lowerNonReadingOperationsOnPhantomAllocations):
108
        (JSC::DFG::ObjectAllocationSinkingPhase::promoteSunkenFields):
109
        (JSC::DFG::ObjectAllocationSinkingPhase::resolve):
110
        (JSC::DFG::ObjectAllocationSinkingPhase::doNothing):
111
        (JSC::DFG::ObjectAllocationSinkingPhase::handleNode):
112
        (JSC::DFG::ObjectAllocationSinkingPhase::createMaterialize):
113
        (JSC::DFG::ObjectAllocationSinkingPhase::populateMaterialize):
114
        (JSC::DFG::performObjectAllocationSinking):
115
        * dfg/DFGObjectAllocationSinkingPhase.h: Added.
116
        * dfg/DFGObjectMaterializationData.cpp: Added.
117
        (JSC::DFG::PhantomPropertyValue::dump):
118
        (JSC::DFG::ObjectMaterializationData::dump):
119
        (JSC::DFG::ObjectMaterializationData::oneWaySimilarityScore):
120
        (JSC::DFG::ObjectMaterializationData::similarityScore):
121
        * dfg/DFGObjectMaterializationData.h: Added.
122
        (JSC::DFG::PhantomPropertyValue::PhantomPropertyValue):
123
        (JSC::DFG::PhantomPropertyValue::operator==):
124
        * dfg/DFGPhantomCanonicalizationPhase.cpp:
125
        (JSC::DFG::PhantomCanonicalizationPhase::run):
126
        * dfg/DFGPhantomRemovalPhase.cpp:
127
        (JSC::DFG::PhantomRemovalPhase::run):
128
        * dfg/DFGPhiChildren.cpp: Added.
129
        (JSC::DFG::PhiChildren::PhiChildren):
130
        (JSC::DFG::PhiChildren::~PhiChildren):
131
        (JSC::DFG::PhiChildren::childrenOf):
132
        * dfg/DFGPhiChildren.h: Added.
133
        (JSC::DFG::PhiChildren::forAllIncomingValues):
134
        (JSC::DFG::PhiChildren::forAllTransitiveIncomingValues):
135
        * dfg/DFGPlan.cpp:
136
        (JSC::DFG::Plan::compileInThreadImpl):
137
        * dfg/DFGPredictionPropagationPhase.cpp:
138
        (JSC::DFG::PredictionPropagationPhase::propagate):
139
        * dfg/DFGPromotedHeapLocation.cpp: Added.
140
        (JSC::DFG::BaselessPromotedHeapLocation::dump):
141
        (JSC::DFG::PromotedHeapLocation::createHint):
142
        (JSC::DFG::PromotedHeapLocation::dump):
143
        (WTF::printInternal):
144
        * dfg/DFGPromotedHeapLocation.h: Added.
145
        (JSC::DFG::BaselessPromotedHeapLocation::BaselessPromotedHeapLocation):
146
        (JSC::DFG::BaselessPromotedHeapLocation::operator!):
147
        (JSC::DFG::BaselessPromotedHeapLocation::kind):
148
        (JSC::DFG::BaselessPromotedHeapLocation::info):
149
        (JSC::DFG::BaselessPromotedHeapLocation::hash):
150
        (JSC::DFG::BaselessPromotedHeapLocation::operator==):
151
        (JSC::DFG::BaselessPromotedHeapLocation::isHashTableDeletedValue):
152
        (JSC::DFG::PromotedHeapLocation::PromotedHeapLocation):
153
        (JSC::DFG::PromotedHeapLocation::PromotedHeapLocaftion):
154
        (JSC::DFG::PromotedHeapLocation::operator!):
155
        (JSC::DFG::PromotedHeapLocation::kind):
156
        (JSC::DFG::PromotedHeapLocation::base):
157
        (JSC::DFG::PromotedHeapLocation::info):
158
        (JSC::DFG::PromotedHeapLocation::baseless):
159
        (JSC::DFG::PromotedHeapLocation::hash):
160
        (JSC::DFG::PromotedHeapLocation::operator==):
161
        (JSC::DFG::PromotedHeapLocation::isHashTableDeletedValue):
162
        (JSC::DFG::promote):
163
        (JSC::DFG::PromotedHeapLocationHash::hash):
164
        (JSC::DFG::PromotedHeapLocationHash::equal):
165
        * dfg/DFGSSACalculator.cpp:
166
        (JSC::DFG::SSACalculator::reset):
167
        * dfg/DFGSSACalculator.h:
168
        * dfg/DFGSafeToExecute.h:
169
        (JSC::DFG::safeToExecute):
170
        * dfg/DFGSpeculativeJIT32_64.cpp:
171
        (JSC::DFG::SpeculativeJIT::compile):
172
        * dfg/DFGSpeculativeJIT64.cpp:
173
        (JSC::DFG::SpeculativeJIT::compile):
174
        * ftl/FTLCapabilities.cpp:
175
        (JSC::FTL::canCompile):
176
        * ftl/FTLExitPropertyValue.cpp: Added.
177
        (JSC::FTL::ExitPropertyValue::dump):
178
        * ftl/FTLExitPropertyValue.h: Added.
179
        (JSC::FTL::ExitPropertyValue::ExitPropertyValue):
180
        (JSC::FTL::ExitPropertyValue::operator!):
181
        (JSC::FTL::ExitPropertyValue::location):
182
        (JSC::FTL::ExitPropertyValue::value):
183
        * ftl/FTLExitTimeObjectMaterialization.cpp: Added.
184
        (JSC::FTL::ExitTimeObjectMaterialization::ExitTimeObjectMaterialization):
185
        (JSC::FTL::ExitTimeObjectMaterialization::~ExitTimeObjectMaterialization):
186
        (JSC::FTL::ExitTimeObjectMaterialization::add):
187
        (JSC::FTL::ExitTimeObjectMaterialization::get):
188
        (JSC::FTL::ExitTimeObjectMaterialization::dump):
189
        * ftl/FTLExitTimeObjectMaterialization.h: Added.
190
        (JSC::FTL::ExitTimeObjectMaterialization::type):
191
        (JSC::FTL::ExitTimeObjectMaterialization::properties):
192
        * ftl/FTLExitValue.cpp:
193
        (JSC::FTL::ExitValue::materializeNewObject):
194
        (JSC::FTL::ExitValue::dumpInContext):
195
        * ftl/FTLExitValue.h:
196
        (JSC::FTL::ExitValue::isObjectMaterialization):
197
        (JSC::FTL::ExitValue::objectMaterialization):
198
        (JSC::FTL::ExitValue::withVirtualRegister):
199
        (JSC::FTL::ExitValue::valueFormat):
200
        * ftl/FTLLowerDFGToLLVM.cpp:
201
        (JSC::FTL::LowerDFGToLLVM::compileNode):
202
        (JSC::FTL::LowerDFGToLLVM::compileCheckStructure):
203
        (JSC::FTL::LowerDFGToLLVM::compileNewObject):
204
        (JSC::FTL::LowerDFGToLLVM::compileMultiPutByOffset):
205
        (JSC::FTL::LowerDFGToLLVM::compileInvalidationPoint):
206
        (JSC::FTL::LowerDFGToLLVM::compileCheckStructureImmediate):
207
        (JSC::FTL::LowerDFGToLLVM::compileMaterializeNewObject):
208
        (JSC::FTL::LowerDFGToLLVM::checkStructure):
209
        (JSC::FTL::LowerDFGToLLVM::allocatePropertyStorage):
210
        (JSC::FTL::LowerDFGToLLVM::reallocatePropertyStorage):
211
        (JSC::FTL::LowerDFGToLLVM::allocatePropertyStorageWithSizeImpl):
212
        (JSC::FTL::LowerDFGToLLVM::allocateCell):
213
        (JSC::FTL::LowerDFGToLLVM::storeStructure):
214
        (JSC::FTL::LowerDFGToLLVM::allocateObject):
215
        (JSC::FTL::LowerDFGToLLVM::appendOSRExit):
216
        (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
217
        (JSC::FTL::LowerDFGToLLVM::exitValueForAvailability):
218
        (JSC::FTL::LowerDFGToLLVM::exitValueForNode):
219
        (JSC::FTL::LowerDFGToLLVM::availabilityMap):
220
        (JSC::FTL::LowerDFGToLLVM::availability): Deleted.
221
        * ftl/FTLOSRExit.h:
222
        * ftl/FTLOSRExitCompiler.cpp:
223
        (JSC::FTL::compileRecovery):
224
        (JSC::FTL::compileStub):
225
        * ftl/FTLOperations.cpp: Added.
226
        (JSC::FTL::operationNewObjectWithButterfly):
227
        (JSC::FTL::operationMaterializeObjectInOSR):
228
        * ftl/FTLOperations.h: Added.
229
        * runtime/JSObject.h:
230
        (JSC::JSFinalObject::JSFinalObject):
231
        (JSC::JSFinalObject::create):
232
        * runtime/Structure.cpp:
233
        (JSC::Structure::canUseForAllocationsOf):
234
        * runtime/Structure.h:
235
1
2014-09-22  Diego Pino Garcia  <dpino@igalia.com>
236
2014-09-22  Diego Pino Garcia  <dpino@igalia.com>
2
237
3
        Simple ES6 feature: Number constructor extras
238
        Simple ES6 feature: Number constructor extras
- Source/JavaScriptCore/CMakeLists.txt +9 lines
Lines 122-127 set(JavaScriptCore_SOURCES Source/JavaScriptCore/CMakeLists.txt_sec1
122
    dfg/DFGArrayMode.cpp
122
    dfg/DFGArrayMode.cpp
123
    dfg/DFGAtTailAbstractState.cpp
123
    dfg/DFGAtTailAbstractState.cpp
124
    dfg/DFGAvailability.cpp
124
    dfg/DFGAvailability.cpp
125
    dfg/DFGAvailabilityMap.cpp
125
    dfg/DFGBackwardsPropagationPhase.cpp
126
    dfg/DFGBackwardsPropagationPhase.cpp
126
    dfg/DFGBasicBlock.cpp
127
    dfg/DFGBasicBlock.cpp
127
    dfg/DFGBinarySwitch.cpp
128
    dfg/DFGBinarySwitch.cpp
Lines 164-169 set(JavaScriptCore_SOURCES Source/JavaScriptCore/CMakeLists.txt_sec2
164
    dfg/DFGGraphSafepoint.cpp
165
    dfg/DFGGraphSafepoint.cpp
165
    dfg/DFGHeapLocation.cpp
166
    dfg/DFGHeapLocation.cpp
166
    dfg/DFGInPlaceAbstractState.cpp
167
    dfg/DFGInPlaceAbstractState.cpp
168
    dfg/DFGInsertOSRHintsForUpdate.cpp
167
    dfg/DFGIntegerCheckCombiningPhase.cpp
169
    dfg/DFGIntegerCheckCombiningPhase.cpp
168
    dfg/DFGInvalidationPointInjectionPhase.cpp
170
    dfg/DFGInvalidationPointInjectionPhase.cpp
169
    dfg/DFGJITCode.cpp
171
    dfg/DFGJITCode.cpp
Lines 192-204 set(JavaScriptCore_SOURCES Source/JavaScriptCore/CMakeLists.txt_sec3
192
    dfg/DFGOSRExitCompilerCommon.cpp
194
    dfg/DFGOSRExitCompilerCommon.cpp
193
    dfg/DFGOSRExitJumpPlaceholder.cpp
195
    dfg/DFGOSRExitJumpPlaceholder.cpp
194
    dfg/DFGOSRExitPreparation.cpp
196
    dfg/DFGOSRExitPreparation.cpp
197
    dfg/DFGObjectAllocationSinkingPhase.cpp
198
    dfg/DFGObjectMaterializationData.cpp
195
    dfg/DFGOperations.cpp
199
    dfg/DFGOperations.cpp
196
    dfg/DFGPhantomCanonicalizationPhase.cpp
200
    dfg/DFGPhantomCanonicalizationPhase.cpp
197
    dfg/DFGPhantomRemovalPhase.cpp
201
    dfg/DFGPhantomRemovalPhase.cpp
198
    dfg/DFGPhase.cpp
202
    dfg/DFGPhase.cpp
203
    dfg/DFGPhiChildren.cpp
199
    dfg/DFGPlan.cpp
204
    dfg/DFGPlan.cpp
200
    dfg/DFGPredictionInjectionPhase.cpp
205
    dfg/DFGPredictionInjectionPhase.cpp
201
    dfg/DFGPredictionPropagationPhase.cpp
206
    dfg/DFGPredictionPropagationPhase.cpp
207
    dfg/DFGPromotedHeapLocation.cpp
202
    dfg/DFGPureValue.cpp
208
    dfg/DFGPureValue.cpp
203
    dfg/DFGResurrectionForValidationPhase.cpp
209
    dfg/DFGResurrectionForValidationPhase.cpp
204
    dfg/DFGSSACalculator.cpp
210
    dfg/DFGSSACalculator.cpp
Lines 774-780 if (ENABLE_FTL_JIT) Source/JavaScriptCore/CMakeLists.txt_sec4
774
        ftl/FTLDataSection.cpp
780
        ftl/FTLDataSection.cpp
775
        ftl/FTLExitArgument.cpp
781
        ftl/FTLExitArgument.cpp
776
        ftl/FTLExitArgumentForOperand.cpp
782
        ftl/FTLExitArgumentForOperand.cpp
783
        ftl/FTLExitPropertyValue.cpp
777
        ftl/FTLExitThunkGenerator.cpp
784
        ftl/FTLExitThunkGenerator.cpp
785
        ftl/FTLExitTimeObjectMaterialization.cpp
778
        ftl/FTLExitValue.cpp
786
        ftl/FTLExitValue.cpp
779
        ftl/FTLFail.cpp
787
        ftl/FTLFail.cpp
780
        ftl/FTLForOSREntryJITCode.cpp
788
        ftl/FTLForOSREntryJITCode.cpp
Lines 789-794 if (ENABLE_FTL_JIT) Source/JavaScriptCore/CMakeLists.txt_sec5
789
        ftl/FTLOSREntry.cpp
797
        ftl/FTLOSREntry.cpp
790
        ftl/FTLOSRExitCompiler.cpp
798
        ftl/FTLOSRExitCompiler.cpp
791
        ftl/FTLOSRExit.cpp
799
        ftl/FTLOSRExit.cpp
800
        ftl/FTLOperations.cpp
792
        ftl/FTLOutput.cpp
801
        ftl/FTLOutput.cpp
793
        ftl/FTLRecoveryOpcode.cpp
802
        ftl/FTLRecoveryOpcode.cpp
794
        ftl/FTLRegisterAtOffset.cpp
803
        ftl/FTLRegisterAtOffset.cpp
- Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj +19 lines
Lines 368-373 Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj_sec1
368
    <ClCompile Include="..\dfg\DFGArrayMode.cpp" />
368
    <ClCompile Include="..\dfg\DFGArrayMode.cpp" />
369
    <ClCompile Include="..\dfg\DFGAtTailAbstractState.cpp" />
369
    <ClCompile Include="..\dfg\DFGAtTailAbstractState.cpp" />
370
    <ClCompile Include="..\dfg\DFGAvailability.cpp" />
370
    <ClCompile Include="..\dfg\DFGAvailability.cpp" />
371
    <ClCompile Include="..\dfg\DFGAvailabilityMap.cpp" />
371
    <ClCompile Include="..\dfg\DFGBackwardsPropagationPhase.cpp" />
372
    <ClCompile Include="..\dfg\DFGBackwardsPropagationPhase.cpp" />
372
    <ClCompile Include="..\dfg\DFGBasicBlock.cpp" />
373
    <ClCompile Include="..\dfg\DFGBasicBlock.cpp" />
373
    <ClCompile Include="..\dfg\DFGBinarySwitch.cpp" />
374
    <ClCompile Include="..\dfg\DFGBinarySwitch.cpp" />
Lines 410-415 Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj_sec2
410
    <ClCompile Include="..\dfg\DFGGraphSafepoint.cpp" />
411
    <ClCompile Include="..\dfg\DFGGraphSafepoint.cpp" />
411
    <ClCompile Include="..\dfg\DFGHeapLocation.cpp" />
412
    <ClCompile Include="..\dfg\DFGHeapLocation.cpp" />
412
    <ClCompile Include="..\dfg\DFGInPlaceAbstractState.cpp" />
413
    <ClCompile Include="..\dfg\DFGInPlaceAbstractState.cpp" />
414
    <ClCompile Include="..\dfg\DFGInsertOSRHintsForUpdate.cpp" />
413
    <ClCompile Include="..\dfg\DFGIntegerCheckCombiningPhase.cpp" />
415
    <ClCompile Include="..\dfg\DFGIntegerCheckCombiningPhase.cpp" />
414
    <ClCompile Include="..\dfg\DFGInvalidationPointInjectionPhase.cpp" />
416
    <ClCompile Include="..\dfg\DFGInvalidationPointInjectionPhase.cpp" />
415
    <ClCompile Include="..\dfg\DFGJITCode.cpp" />
417
    <ClCompile Include="..\dfg\DFGJITCode.cpp" />
Lines 439-450 Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj_sec3
439
    <ClCompile Include="..\dfg\DFGOSRExitCompilerCommon.cpp" />
441
    <ClCompile Include="..\dfg\DFGOSRExitCompilerCommon.cpp" />
440
    <ClCompile Include="..\dfg\DFGOSRExitJumpPlaceholder.cpp" />
442
    <ClCompile Include="..\dfg\DFGOSRExitJumpPlaceholder.cpp" />
441
    <ClCompile Include="..\dfg\DFGOSRExitPreparation.cpp" />
443
    <ClCompile Include="..\dfg\DFGOSRExitPreparation.cpp" />
444
    <ClCompile Include="..\dfg\DFGObjectAllocationSinkingPhase.cpp" />
445
    <ClCompile Include="..\dfg\DFGObjectMaterializationData.cpp" />
442
    <ClCompile Include="..\dfg\DFGPhantomCanonicalizationPhase.cpp" />
446
    <ClCompile Include="..\dfg\DFGPhantomCanonicalizationPhase.cpp" />
443
    <ClCompile Include="..\dfg\DFGPhantomRemovalPhase.cpp" />
447
    <ClCompile Include="..\dfg\DFGPhantomRemovalPhase.cpp" />
444
    <ClCompile Include="..\dfg\DFGPhase.cpp" />
448
    <ClCompile Include="..\dfg\DFGPhase.cpp" />
449
    <ClCompile Include="..\dfg\DFGPhiChildren.cpp" />
445
    <ClCompile Include="..\dfg\DFGPlan.cpp" />
450
    <ClCompile Include="..\dfg\DFGPlan.cpp" />
446
    <ClCompile Include="..\dfg\DFGPredictionInjectionPhase.cpp" />
451
    <ClCompile Include="..\dfg\DFGPredictionInjectionPhase.cpp" />
447
    <ClCompile Include="..\dfg\DFGPredictionPropagationPhase.cpp" />
452
    <ClCompile Include="..\dfg\DFGPredictionPropagationPhase.cpp" />
453
    <ClCompile Include="..\dfg\DFGPromotedHeapLocation.cpp" />
448
    <ClCompile Include="..\dfg\DFGPureValue.cpp" />
454
    <ClCompile Include="..\dfg\DFGPureValue.cpp" />
449
    <ClCompile Include="..\dfg\DFGResurrectionForValidationPhase.cpp" />
455
    <ClCompile Include="..\dfg\DFGResurrectionForValidationPhase.cpp" />
450
    <ClCompile Include="..\dfg\DFGSafepoint.cpp" />
456
    <ClCompile Include="..\dfg\DFGSafepoint.cpp" />
Lines 493-499 Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj_sec4
493
    <ClCompile Include="..\ftl\FTLDWARFRegister.cpp" />
499
    <ClCompile Include="..\ftl\FTLDWARFRegister.cpp" />
494
    <ClCompile Include="..\ftl\FTLExitArgument.cpp" />
500
    <ClCompile Include="..\ftl\FTLExitArgument.cpp" />
495
    <ClCompile Include="..\ftl\FTLExitArgumentForOperand.cpp" />
501
    <ClCompile Include="..\ftl\FTLExitArgumentForOperand.cpp" />
502
    <ClCompile Include="..\ftl\FTLExitPropertyValue.cpp" />
496
    <ClCompile Include="..\ftl\FTLExitThunkGenerator.cpp" />
503
    <ClCompile Include="..\ftl\FTLExitThunkGenerator.cpp" />
504
    <ClCompile Include="..\ftl\FTLExitTimeObjectMaterialization.cpp" />
497
    <ClCompile Include="..\ftl\FTLExitValue.cpp" />
505
    <ClCompile Include="..\ftl\FTLExitValue.cpp" />
498
    <ClCompile Include="..\ftl\FTLFail.cpp" />
506
    <ClCompile Include="..\ftl\FTLFail.cpp" />
499
    <ClCompile Include="..\ftl\FTLForOSREntryJITCode.cpp" />
507
    <ClCompile Include="..\ftl\FTLForOSREntryJITCode.cpp" />
Lines 508-513 Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj_sec5
508
    <ClCompile Include="..\ftl\FTLOSREntry.cpp" />
516
    <ClCompile Include="..\ftl\FTLOSREntry.cpp" />
509
    <ClCompile Include="..\ftl\FTLOSRExit.cpp" />
517
    <ClCompile Include="..\ftl\FTLOSRExit.cpp" />
510
    <ClCompile Include="..\ftl\FTLOSRExitCompiler.cpp" />
518
    <ClCompile Include="..\ftl\FTLOSRExitCompiler.cpp" />
519
    <ClCompile Include="..\ftl\FTLOperations.cpp" />
511
    <ClCompile Include="..\ftl\FTLOutput.cpp" />
520
    <ClCompile Include="..\ftl\FTLOutput.cpp" />
512
    <ClCompile Include="..\ftl\FTLRecoveryOpcode.cpp" />
521
    <ClCompile Include="..\ftl\FTLRecoveryOpcode.cpp" />
513
    <ClCompile Include="..\ftl\FTLRegisterAtOffset.cpp" />
522
    <ClCompile Include="..\ftl\FTLRegisterAtOffset.cpp" />
Lines 993-998 Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj_sec6
993
    <ClInclude Include="..\dfg\DFGArrayMode.h" />
1002
    <ClInclude Include="..\dfg\DFGArrayMode.h" />
994
    <ClInclude Include="..\dfg\DFGAtTailAbstractState.h" />
1003
    <ClInclude Include="..\dfg\DFGAtTailAbstractState.h" />
995
    <ClInclude Include="..\dfg\DFGAvailability.h" />
1004
    <ClInclude Include="..\dfg\DFGAvailability.h" />
1005
    <ClInclude Include="..\dfg\DFGAvailabilityMap.h" />
996
    <ClInclude Include="..\dfg\DFGBackwardsPropagationPhase.h" />
1006
    <ClInclude Include="..\dfg\DFGBackwardsPropagationPhase.h" />
997
    <ClInclude Include="..\dfg\DFGBasicBlock.h" />
1007
    <ClInclude Include="..\dfg\DFGBasicBlock.h" />
998
    <ClInclude Include="..\dfg\DFGBasicBlockInlines.h" />
1008
    <ClInclude Include="..\dfg\DFGBasicBlockInlines.h" />
Lines 1049-1054 Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj_sec7
1049
    <ClInclude Include="..\dfg\DFGGraphSafepoint.h" />
1059
    <ClInclude Include="..\dfg\DFGGraphSafepoint.h" />
1050
    <ClInclude Include="..\dfg\DFGHeapLocation.h" />
1060
    <ClInclude Include="..\dfg\DFGHeapLocation.h" />
1051
    <ClInclude Include="..\dfg\DFGInPlaceAbstractState.h" />
1061
    <ClInclude Include="..\dfg\DFGInPlaceAbstractState.h" />
1062
    <ClInclude Include="..\dfg\DFGInsertOSRHintsForUpdate.h" />
1052
    <ClInclude Include="..\dfg\DFGInsertionSet.h" />
1063
    <ClInclude Include="..\dfg\DFGInsertionSet.h" />
1053
    <ClInclude Include="..\dfg\DFGIntegerCheckCombiningPhase.h" />
1064
    <ClInclude Include="..\dfg\DFGIntegerCheckCombiningPhase.h" />
1054
    <ClInclude Include="..\dfg\DFGInvalidationPointInjectionPhase.h" />
1065
    <ClInclude Include="..\dfg\DFGInvalidationPointInjectionPhase.h" />
Lines 1073-1078 Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj_sec8
1073
    <ClInclude Include="..\dfg\DFGNodeFlags.h" />
1084
    <ClInclude Include="..\dfg\DFGNodeFlags.h" />
1074
    <ClInclude Include="..\dfg\DFGNodeOrigin.h" />
1085
    <ClInclude Include="..\dfg\DFGNodeOrigin.h" />
1075
    <ClInclude Include="..\dfg\DFGNodeType.h" />
1086
    <ClInclude Include="..\dfg\DFGNodeType.h" />
1087
    <ClInclude Include="..\dfg\DFGObjectAllocationSinkingPhase.h" />
1088
    <ClInclude Include="..\dfg\DFGObjectMaterializationData.h" />
1076
    <ClInclude Include="..\dfg\DFGOperations.h" />
1089
    <ClInclude Include="..\dfg\DFGOperations.h" />
1077
    <ClInclude Include="..\dfg\DFGOSRAvailabilityAnalysisPhase.h" />
1090
    <ClInclude Include="..\dfg\DFGOSRAvailabilityAnalysisPhase.h" />
1078
    <ClInclude Include="..\dfg\DFGOSREntry.h" />
1091
    <ClInclude Include="..\dfg\DFGOSREntry.h" />
Lines 1087-1095 Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj_sec9
1087
    <ClInclude Include="..\dfg\DFGPhantomCanonicalizationPhase.h" />
1100
    <ClInclude Include="..\dfg\DFGPhantomCanonicalizationPhase.h" />
1088
    <ClInclude Include="..\dfg\DFGPhantomRemovalPhase.h" />
1101
    <ClInclude Include="..\dfg\DFGPhantomRemovalPhase.h" />
1089
    <ClInclude Include="..\dfg\DFGPhase.h" />
1102
    <ClInclude Include="..\dfg\DFGPhase.h" />
1103
    <ClInclude Include="..\dfg\DFGPhiChildren.h" />
1090
    <ClInclude Include="..\dfg\DFGPlan.h" />
1104
    <ClInclude Include="..\dfg\DFGPlan.h" />
1091
    <ClInclude Include="..\dfg\DFGPredictionInjectionPhase.h" />
1105
    <ClInclude Include="..\dfg\DFGPredictionInjectionPhase.h" />
1092
    <ClInclude Include="..\dfg\DFGPredictionPropagationPhase.h" />
1106
    <ClInclude Include="..\dfg\DFGPredictionPropagationPhase.h" />
1107
    <ClInclude Include="..\dfg\DFGPromoteHeapAccess.h" />
1108
    <ClInclude Include="..\dfg\DFGPromotedHeapLocation.h" />
1093
    <ClInclude Include="..\dfg\DFGPureValue.h" />
1109
    <ClInclude Include="..\dfg\DFGPureValue.h" />
1094
    <ClInclude Include="..\dfg\DFGRegisterBank.h" />
1110
    <ClInclude Include="..\dfg\DFGRegisterBank.h" />
1095
    <ClInclude Include="..\dfg\DFGRegisterSet.h" />
1111
    <ClInclude Include="..\dfg\DFGRegisterSet.h" />
Lines 1150-1156 Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj_sec10
1150
    <ClInclude Include="..\ftl\FTLExitArgument.h" />
1166
    <ClInclude Include="..\ftl\FTLExitArgument.h" />
1151
    <ClInclude Include="..\ftl\FTLExitArgumentForOperand.h" />
1167
    <ClInclude Include="..\ftl\FTLExitArgumentForOperand.h" />
1152
    <ClInclude Include="..\ftl\FTLExitArgumentList.h" />
1168
    <ClInclude Include="..\ftl\FTLExitArgumentList.h" />
1169
    <ClInclude Include="..\ftl\FTLExitPropertyValue.h" />
1153
    <ClInclude Include="..\ftl\FTLExitThunkGenerator.h" />
1170
    <ClInclude Include="..\ftl\FTLExitThunkGenerator.h" />
1171
    <ClInclude Include="..\ftl\FTLExitTimeObjectMaterialization.h" />
1154
    <ClInclude Include="..\ftl\FTLExitValue.h" />
1172
    <ClInclude Include="..\ftl\FTLExitValue.h" />
1155
    <ClInclude Include="..\ftl\FTLFail.h" />
1173
    <ClInclude Include="..\ftl\FTLFail.h" />
1156
    <ClInclude Include="..\ftl\FTLFormattedValue.h" />
1174
    <ClInclude Include="..\ftl\FTLFormattedValue.h" />
Lines 1170-1175 Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj_sec11
1170
    <ClInclude Include="..\ftl\FTLOSRExit.h" />
1188
    <ClInclude Include="..\ftl\FTLOSRExit.h" />
1171
    <ClInclude Include="..\ftl\FTLOSRExitCompilationInfo.h" />
1189
    <ClInclude Include="..\ftl\FTLOSRExitCompilationInfo.h" />
1172
    <ClInclude Include="..\ftl\FTLOSRExitCompiler.h" />
1190
    <ClInclude Include="..\ftl\FTLOSRExitCompiler.h" />
1191
    <ClInclude Include="..\ftl\FTLOperations.h" />
1173
    <ClInclude Include="..\ftl\FTLOutput.h" />
1192
    <ClInclude Include="..\ftl\FTLOutput.h" />
1174
    <ClInclude Include="..\ftl\FTLRecoveryOpcode.h" />
1193
    <ClInclude Include="..\ftl\FTLRecoveryOpcode.h" />
1175
    <ClInclude Include="..\ftl\FTLRegisterAtOffset.h" />
1194
    <ClInclude Include="..\ftl\FTLRegisterAtOffset.h" />
- Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj +76 lines
Lines 209-214 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec1
209
		0F2B670917B6B5AB00A7AE3F /* TypedArrays.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66DB17B6B5AB00A7AE3F /* TypedArrays.h */; settings = {ATTRIBUTES = (Private, ); }; };
209
		0F2B670917B6B5AB00A7AE3F /* TypedArrays.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66DB17B6B5AB00A7AE3F /* TypedArrays.h */; settings = {ATTRIBUTES = (Private, ); }; };
210
		0F2B670A17B6B5AB00A7AE3F /* TypedArrayType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B66DC17B6B5AB00A7AE3F /* TypedArrayType.cpp */; };
210
		0F2B670A17B6B5AB00A7AE3F /* TypedArrayType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B66DC17B6B5AB00A7AE3F /* TypedArrayType.cpp */; };
211
		0F2B670B17B6B5AB00A7AE3F /* TypedArrayType.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66DD17B6B5AB00A7AE3F /* TypedArrayType.h */; settings = {ATTRIBUTES = (Private, ); }; };
211
		0F2B670B17B6B5AB00A7AE3F /* TypedArrayType.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66DD17B6B5AB00A7AE3F /* TypedArrayType.h */; settings = {ATTRIBUTES = (Private, ); }; };
212
		0F2B9CE219D0BA7D00B1D1B5 /* DFGAvailabilityMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B9CD619D0BA7D00B1D1B5 /* DFGAvailabilityMap.cpp */; };
213
		0F2B9CE319D0BA7D00B1D1B5 /* DFGAvailabilityMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B9CD719D0BA7D00B1D1B5 /* DFGAvailabilityMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
214
		0F2B9CE419D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B9CD819D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.cpp */; };
215
		0F2B9CE519D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B9CD919D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.h */; settings = {ATTRIBUTES = (Private, ); }; };
216
		0F2B9CE619D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B9CDA19D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.cpp */; };
217
		0F2B9CE719D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B9CDB19D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
218
		0F2B9CE819D0BA7D00B1D1B5 /* DFGObjectMaterializationData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B9CDC19D0BA7D00B1D1B5 /* DFGObjectMaterializationData.cpp */; };
219
		0F2B9CE919D0BA7D00B1D1B5 /* DFGObjectMaterializationData.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B9CDD19D0BA7D00B1D1B5 /* DFGObjectMaterializationData.h */; settings = {ATTRIBUTES = (Private, ); }; };
220
		0F2B9CEA19D0BA7D00B1D1B5 /* DFGPhiChildren.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B9CDE19D0BA7D00B1D1B5 /* DFGPhiChildren.cpp */; };
221
		0F2B9CEB19D0BA7D00B1D1B5 /* DFGPhiChildren.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B9CDF19D0BA7D00B1D1B5 /* DFGPhiChildren.h */; settings = {ATTRIBUTES = (Private, ); }; };
222
		0F2B9CEC19D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B9CE019D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.cpp */; };
223
		0F2B9CED19D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B9CE119D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.h */; settings = {ATTRIBUTES = (Private, ); }; };
224
		0F2B9CF419D0BAC100B1D1B5 /* FTLExitPropertyValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B9CEE19D0BAC100B1D1B5 /* FTLExitPropertyValue.cpp */; };
225
		0F2B9CF519D0BAC100B1D1B5 /* FTLExitPropertyValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B9CEF19D0BAC100B1D1B5 /* FTLExitPropertyValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
226
		0F2B9CF619D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B9CF019D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.cpp */; };
227
		0F2B9CF719D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B9CF119D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.h */; settings = {ATTRIBUTES = (Private, ); }; };
228
		0F2B9CF819D0BAC100B1D1B5 /* FTLOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B9CF219D0BAC100B1D1B5 /* FTLOperations.cpp */; };
229
		0F2B9CF919D0BAC100B1D1B5 /* FTLOperations.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B9CF319D0BAC100B1D1B5 /* FTLOperations.h */; settings = {ATTRIBUTES = (Private, ); }; };
212
		0F2BDC15151C5D4D00CD8910 /* DFGFixupPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2BDC12151C5D4A00CD8910 /* DFGFixupPhase.cpp */; };
230
		0F2BDC15151C5D4D00CD8910 /* DFGFixupPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2BDC12151C5D4A00CD8910 /* DFGFixupPhase.cpp */; };
213
		0F2BDC16151C5D4F00CD8910 /* DFGFixupPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2BDC13151C5D4A00CD8910 /* DFGFixupPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
231
		0F2BDC16151C5D4F00CD8910 /* DFGFixupPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2BDC13151C5D4A00CD8910 /* DFGFixupPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
214
		0F2BDC21151E803B00CD8910 /* DFGInsertionSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2BDC1F151E803800CD8910 /* DFGInsertionSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
232
		0F2BDC21151E803B00CD8910 /* DFGInsertionSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2BDC1F151E803800CD8910 /* DFGInsertionSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
Lines 443-448 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec2
443
		0FA7A8EB18B413C80052371D /* Reg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FA7A8E918B413C80052371D /* Reg.cpp */; };
461
		0FA7A8EB18B413C80052371D /* Reg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FA7A8E918B413C80052371D /* Reg.cpp */; };
444
		0FA7A8EC18B413C80052371D /* Reg.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA7A8EA18B413C80052371D /* Reg.h */; settings = {ATTRIBUTES = (Private, ); }; };
462
		0FA7A8EC18B413C80052371D /* Reg.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA7A8EA18B413C80052371D /* Reg.h */; settings = {ATTRIBUTES = (Private, ); }; };
445
		0FA7A8EE18CE4FD80052371D /* ScratchRegisterAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FA7A8ED18CE4FD80052371D /* ScratchRegisterAllocator.cpp */; };
463
		0FA7A8EE18CE4FD80052371D /* ScratchRegisterAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FA7A8ED18CE4FD80052371D /* ScratchRegisterAllocator.cpp */; };
464
		0FAA3E0919D0C2CB00FAC9E2 /* DFGPromoteHeapAccess.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FAA3E0819D0C2CB00FAC9E2 /* DFGPromoteHeapAccess.h */; settings = {ATTRIBUTES = (Private, ); }; };
446
		0FAF7EFD165BA91B000C8455 /* JITDisassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FAF7EFA165BA919000C8455 /* JITDisassembler.cpp */; };
465
		0FAF7EFD165BA91B000C8455 /* JITDisassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FAF7EFA165BA919000C8455 /* JITDisassembler.cpp */; };
447
		0FAF7EFE165BA91F000C8455 /* JITDisassembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FAF7EFB165BA919000C8455 /* JITDisassembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
466
		0FAF7EFE165BA91F000C8455 /* JITDisassembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FAF7EFB165BA919000C8455 /* JITDisassembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
448
		0FB105851675480F00F8AB6E /* ExitKind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB105821675480C00F8AB6E /* ExitKind.cpp */; };
467
		0FB105851675480F00F8AB6E /* ExitKind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB105821675480C00F8AB6E /* ExitKind.cpp */; };
Lines 1831-1836 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec3
1831
		0F2B66DB17B6B5AB00A7AE3F /* TypedArrays.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypedArrays.h; sourceTree = "<group>"; };
1850
		0F2B66DB17B6B5AB00A7AE3F /* TypedArrays.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypedArrays.h; sourceTree = "<group>"; };
1832
		0F2B66DC17B6B5AB00A7AE3F /* TypedArrayType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TypedArrayType.cpp; sourceTree = "<group>"; };
1851
		0F2B66DC17B6B5AB00A7AE3F /* TypedArrayType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TypedArrayType.cpp; sourceTree = "<group>"; };
1833
		0F2B66DD17B6B5AB00A7AE3F /* TypedArrayType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypedArrayType.h; sourceTree = "<group>"; };
1852
		0F2B66DD17B6B5AB00A7AE3F /* TypedArrayType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypedArrayType.h; sourceTree = "<group>"; };
1853
		0F2B9CD619D0BA7D00B1D1B5 /* DFGAvailabilityMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGAvailabilityMap.cpp; path = dfg/DFGAvailabilityMap.cpp; sourceTree = "<group>"; };
1854
		0F2B9CD719D0BA7D00B1D1B5 /* DFGAvailabilityMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAvailabilityMap.h; path = dfg/DFGAvailabilityMap.h; sourceTree = "<group>"; };
1855
		0F2B9CD819D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGInsertOSRHintsForUpdate.cpp; path = dfg/DFGInsertOSRHintsForUpdate.cpp; sourceTree = "<group>"; };
1856
		0F2B9CD919D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGInsertOSRHintsForUpdate.h; path = dfg/DFGInsertOSRHintsForUpdate.h; sourceTree = "<group>"; };
1857
		0F2B9CDA19D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGObjectAllocationSinkingPhase.cpp; path = dfg/DFGObjectAllocationSinkingPhase.cpp; sourceTree = "<group>"; };
1858
		0F2B9CDB19D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGObjectAllocationSinkingPhase.h; path = dfg/DFGObjectAllocationSinkingPhase.h; sourceTree = "<group>"; };
1859
		0F2B9CDC19D0BA7D00B1D1B5 /* DFGObjectMaterializationData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGObjectMaterializationData.cpp; path = dfg/DFGObjectMaterializationData.cpp; sourceTree = "<group>"; };
1860
		0F2B9CDD19D0BA7D00B1D1B5 /* DFGObjectMaterializationData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGObjectMaterializationData.h; path = dfg/DFGObjectMaterializationData.h; sourceTree = "<group>"; };
1861
		0F2B9CDE19D0BA7D00B1D1B5 /* DFGPhiChildren.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGPhiChildren.cpp; path = dfg/DFGPhiChildren.cpp; sourceTree = "<group>"; };
1862
		0F2B9CDF19D0BA7D00B1D1B5 /* DFGPhiChildren.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPhiChildren.h; path = dfg/DFGPhiChildren.h; sourceTree = "<group>"; };
1863
		0F2B9CE019D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGPromotedHeapLocation.cpp; path = dfg/DFGPromotedHeapLocation.cpp; sourceTree = "<group>"; };
1864
		0F2B9CE119D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPromotedHeapLocation.h; path = dfg/DFGPromotedHeapLocation.h; sourceTree = "<group>"; };
1865
		0F2B9CEE19D0BAC100B1D1B5 /* FTLExitPropertyValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLExitPropertyValue.cpp; path = ftl/FTLExitPropertyValue.cpp; sourceTree = "<group>"; };
1866
		0F2B9CEF19D0BAC100B1D1B5 /* FTLExitPropertyValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLExitPropertyValue.h; path = ftl/FTLExitPropertyValue.h; sourceTree = "<group>"; };
1867
		0F2B9CF019D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLExitTimeObjectMaterialization.cpp; path = ftl/FTLExitTimeObjectMaterialization.cpp; sourceTree = "<group>"; };
1868
		0F2B9CF119D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLExitTimeObjectMaterialization.h; path = ftl/FTLExitTimeObjectMaterialization.h; sourceTree = "<group>"; };
1869
		0F2B9CF219D0BAC100B1D1B5 /* FTLOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLOperations.cpp; path = ftl/FTLOperations.cpp; sourceTree = "<group>"; };
1870
		0F2B9CF319D0BAC100B1D1B5 /* FTLOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLOperations.h; path = ftl/FTLOperations.h; sourceTree = "<group>"; };
1834
		0F2BDC12151C5D4A00CD8910 /* DFGFixupPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGFixupPhase.cpp; path = dfg/DFGFixupPhase.cpp; sourceTree = "<group>"; };
1871
		0F2BDC12151C5D4A00CD8910 /* DFGFixupPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGFixupPhase.cpp; path = dfg/DFGFixupPhase.cpp; sourceTree = "<group>"; };
1835
		0F2BDC13151C5D4A00CD8910 /* DFGFixupPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGFixupPhase.h; path = dfg/DFGFixupPhase.h; sourceTree = "<group>"; };
1872
		0F2BDC13151C5D4A00CD8910 /* DFGFixupPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGFixupPhase.h; path = dfg/DFGFixupPhase.h; sourceTree = "<group>"; };
1836
		0F2BDC1F151E803800CD8910 /* DFGInsertionSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGInsertionSet.h; path = dfg/DFGInsertionSet.h; sourceTree = "<group>"; };
1873
		0F2BDC1F151E803800CD8910 /* DFGInsertionSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGInsertionSet.h; path = dfg/DFGInsertionSet.h; sourceTree = "<group>"; };
Lines 2062-2067 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec4
2062
		0FA7A8E918B413C80052371D /* Reg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Reg.cpp; sourceTree = "<group>"; };
2099
		0FA7A8E918B413C80052371D /* Reg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Reg.cpp; sourceTree = "<group>"; };
2063
		0FA7A8EA18B413C80052371D /* Reg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Reg.h; sourceTree = "<group>"; };
2100
		0FA7A8EA18B413C80052371D /* Reg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Reg.h; sourceTree = "<group>"; };
2064
		0FA7A8ED18CE4FD80052371D /* ScratchRegisterAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScratchRegisterAllocator.cpp; sourceTree = "<group>"; };
2101
		0FA7A8ED18CE4FD80052371D /* ScratchRegisterAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScratchRegisterAllocator.cpp; sourceTree = "<group>"; };
2102
		0FAA3E0819D0C2CB00FAC9E2 /* DFGPromoteHeapAccess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPromoteHeapAccess.h; path = dfg/DFGPromoteHeapAccess.h; sourceTree = "<group>"; };
2065
		0FAF7EFA165BA919000C8455 /* JITDisassembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITDisassembler.cpp; sourceTree = "<group>"; };
2103
		0FAF7EFA165BA919000C8455 /* JITDisassembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITDisassembler.cpp; sourceTree = "<group>"; };
2066
		0FAF7EFB165BA919000C8455 /* JITDisassembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITDisassembler.h; sourceTree = "<group>"; };
2104
		0FAF7EFB165BA919000C8455 /* JITDisassembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITDisassembler.h; sourceTree = "<group>"; };
2067
		0FB105821675480C00F8AB6E /* ExitKind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExitKind.cpp; sourceTree = "<group>"; };
2105
		0FB105821675480C00F8AB6E /* ExitKind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExitKind.cpp; sourceTree = "<group>"; };
Lines 3471-3478 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec5
3471
				0F235BBF17178E1C00690C7F /* FTLExitArgumentForOperand.cpp */,
3509
				0F235BBF17178E1C00690C7F /* FTLExitArgumentForOperand.cpp */,
3472
				0F235BC017178E1C00690C7F /* FTLExitArgumentForOperand.h */,
3510
				0F235BC017178E1C00690C7F /* FTLExitArgumentForOperand.h */,
3473
				0F235BC117178E1C00690C7F /* FTLExitArgumentList.h */,
3511
				0F235BC117178E1C00690C7F /* FTLExitArgumentList.h */,
3512
				0F2B9CEE19D0BAC100B1D1B5 /* FTLExitPropertyValue.cpp */,
3513
				0F2B9CEF19D0BAC100B1D1B5 /* FTLExitPropertyValue.h */,
3474
				0F235BC217178E1C00690C7F /* FTLExitThunkGenerator.cpp */,
3514
				0F235BC217178E1C00690C7F /* FTLExitThunkGenerator.cpp */,
3475
				0F235BC317178E1C00690C7F /* FTLExitThunkGenerator.h */,
3515
				0F235BC317178E1C00690C7F /* FTLExitThunkGenerator.h */,
3516
				0F2B9CF019D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.cpp */,
3517
				0F2B9CF119D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.h */,
3476
				0F235BC417178E1C00690C7F /* FTLExitValue.cpp */,
3518
				0F235BC417178E1C00690C7F /* FTLExitValue.cpp */,
3477
				0F235BC517178E1C00690C7F /* FTLExitValue.h */,
3519
				0F235BC517178E1C00690C7F /* FTLExitValue.h */,
3478
				A7F2996917A0BB670010417A /* FTLFail.cpp */,
3520
				A7F2996917A0BB670010417A /* FTLFail.cpp */,
Lines 3499-3504 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec6
3499
				0FEA0A04170513DB00BB722C /* FTLLowerDFGToLLVM.cpp */,
3541
				0FEA0A04170513DB00BB722C /* FTLLowerDFGToLLVM.cpp */,
3500
				0FEA0A05170513DB00BB722C /* FTLLowerDFGToLLVM.h */,
3542
				0FEA0A05170513DB00BB722C /* FTLLowerDFGToLLVM.h */,
3501
				A7D89D0117A0B90400773AD8 /* FTLLoweredNodeValue.h */,
3543
				A7D89D0117A0B90400773AD8 /* FTLLoweredNodeValue.h */,
3544
				0F2B9CF219D0BAC100B1D1B5 /* FTLOperations.cpp */,
3545
				0F2B9CF319D0BAC100B1D1B5 /* FTLOperations.h */,
3502
				0FD8A31717D51F2200CA2C40 /* FTLOSREntry.cpp */,
3546
				0FD8A31717D51F2200CA2C40 /* FTLOSREntry.cpp */,
3503
				0FD8A31817D51F2200CA2C40 /* FTLOSREntry.h */,
3547
				0FD8A31817D51F2200CA2C40 /* FTLOSREntry.h */,
3504
				0F235BC617178E1C00690C7F /* FTLOSRExit.cpp */,
3548
				0F235BC617178E1C00690C7F /* FTLOSRExit.cpp */,
Lines 4528-4533 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec7
4528
				A7D9A29017A0BC7400EE2618 /* DFGAtTailAbstractState.h */,
4572
				A7D9A29017A0BC7400EE2618 /* DFGAtTailAbstractState.h */,
4529
				0F666EC21835672B00D017F1 /* DFGAvailability.cpp */,
4573
				0F666EC21835672B00D017F1 /* DFGAvailability.cpp */,
4530
				0F666EC31835672B00D017F1 /* DFGAvailability.h */,
4574
				0F666EC31835672B00D017F1 /* DFGAvailability.h */,
4575
				0F2B9CD619D0BA7D00B1D1B5 /* DFGAvailabilityMap.cpp */,
4576
				0F2B9CD719D0BA7D00B1D1B5 /* DFGAvailabilityMap.h */,
4531
				0F714CA116EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.cpp */,
4577
				0F714CA116EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.cpp */,
4532
				0F714CA216EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.h */,
4578
				0F714CA216EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.h */,
4533
				A7D89CE317A0B8CC00773AD8 /* DFGBasicBlock.cpp */,
4579
				A7D89CE317A0B8CC00773AD8 /* DFGBasicBlock.cpp */,
Lines 4626-4631 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec8
4626
				A704D90017A0BAA8006BA554 /* DFGInPlaceAbstractState.cpp */,
4672
				A704D90017A0BAA8006BA554 /* DFGInPlaceAbstractState.cpp */,
4627
				A704D90117A0BAA8006BA554 /* DFGInPlaceAbstractState.h */,
4673
				A704D90117A0BAA8006BA554 /* DFGInPlaceAbstractState.h */,
4628
				0F2BDC1F151E803800CD8910 /* DFGInsertionSet.h */,
4674
				0F2BDC1F151E803800CD8910 /* DFGInsertionSet.h */,
4675
				0F2B9CD819D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.cpp */,
4676
				0F2B9CD919D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.h */,
4629
				0F300B7918AB1B1400A6D72E /* DFGIntegerCheckCombiningPhase.cpp */,
4677
				0F300B7918AB1B1400A6D72E /* DFGIntegerCheckCombiningPhase.cpp */,
4630
				0F300B7A18AB1B1400A6D72E /* DFGIntegerCheckCombiningPhase.h */,
4678
				0F300B7A18AB1B1400A6D72E /* DFGIntegerCheckCombiningPhase.h */,
4631
				0FC97F3718202119002C9B26 /* DFGInvalidationPointInjectionPhase.cpp */,
4679
				0FC97F3718202119002C9B26 /* DFGInvalidationPointInjectionPhase.cpp */,
Lines 4666-4671 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec9
4666
				0FA581B8150E952A00B9A2D9 /* DFGNodeFlags.h */,
4714
				0FA581B8150E952A00B9A2D9 /* DFGNodeFlags.h */,
4667
				0F300B7718AB051100A6D72E /* DFGNodeOrigin.h */,
4715
				0F300B7718AB051100A6D72E /* DFGNodeOrigin.h */,
4668
				0FA581B9150E952A00B9A2D9 /* DFGNodeType.h */,
4716
				0FA581B9150E952A00B9A2D9 /* DFGNodeType.h */,
4717
				0F2B9CDA19D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.cpp */,
4718
				0F2B9CDB19D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.h */,
4719
				0F2B9CDC19D0BA7D00B1D1B5 /* DFGObjectMaterializationData.cpp */,
4720
				0F2B9CDD19D0BA7D00B1D1B5 /* DFGObjectMaterializationData.h */,
4669
				86EC9DBF1328DF82002B2AD7 /* DFGOperations.cpp */,
4721
				86EC9DBF1328DF82002B2AD7 /* DFGOperations.cpp */,
4670
				86EC9DC01328DF82002B2AD7 /* DFGOperations.h */,
4722
				86EC9DC01328DF82002B2AD7 /* DFGOperations.h */,
4671
				A7D89CEE17A0B8CC00773AD8 /* DFGOSRAvailabilityAnalysisPhase.cpp */,
4723
				A7D89CEE17A0B8CC00773AD8 /* DFGOSRAvailabilityAnalysisPhase.cpp */,
Lines 4695-4706 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec10
4695
				0FBFDD03196C92BF007A5BFA /* DFGPhantomRemovalPhase.h */,
4747
				0FBFDD03196C92BF007A5BFA /* DFGPhantomRemovalPhase.h */,
4696
				0FFFC94F14EF909500C72532 /* DFGPhase.cpp */,
4748
				0FFFC94F14EF909500C72532 /* DFGPhase.cpp */,
4697
				0FFFC95014EF909500C72532 /* DFGPhase.h */,
4749
				0FFFC95014EF909500C72532 /* DFGPhase.h */,
4750
				0F2B9CDE19D0BA7D00B1D1B5 /* DFGPhiChildren.cpp */,
4751
				0F2B9CDF19D0BA7D00B1D1B5 /* DFGPhiChildren.h */,
4698
				A78A9772179738B8009DF744 /* DFGPlan.cpp */,
4752
				A78A9772179738B8009DF744 /* DFGPlan.cpp */,
4699
				A78A9773179738B8009DF744 /* DFGPlan.h */,
4753
				A78A9773179738B8009DF744 /* DFGPlan.h */,
4700
				0FBE0F6D16C1DB010082C5E8 /* DFGPredictionInjectionPhase.cpp */,
4754
				0FBE0F6D16C1DB010082C5E8 /* DFGPredictionInjectionPhase.cpp */,
4701
				0FBE0F6E16C1DB010082C5E8 /* DFGPredictionInjectionPhase.h */,
4755
				0FBE0F6E16C1DB010082C5E8 /* DFGPredictionInjectionPhase.h */,
4702
				0FFFC95114EF909500C72532 /* DFGPredictionPropagationPhase.cpp */,
4756
				0FFFC95114EF909500C72532 /* DFGPredictionPropagationPhase.cpp */,
4703
				0FFFC95214EF909500C72532 /* DFGPredictionPropagationPhase.h */,
4757
				0FFFC95214EF909500C72532 /* DFGPredictionPropagationPhase.h */,
4758
				0F2B9CE019D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.cpp */,
4759
				0F2B9CE119D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.h */,
4760
				0FAA3E0819D0C2CB00FAC9E2 /* DFGPromoteHeapAccess.h */,
4704
				0FB1765E196B8F9E0091052A /* DFGPureValue.cpp */,
4761
				0FB1765E196B8F9E0091052A /* DFGPureValue.cpp */,
4705
				0FB1765F196B8F9E0091052A /* DFGPureValue.h */,
4762
				0FB1765F196B8F9E0091052A /* DFGPureValue.h */,
4706
				86EC9DC11328DF82002B2AD7 /* DFGRegisterBank.h */,
4763
				86EC9DC11328DF82002B2AD7 /* DFGRegisterBank.h */,
Lines 5281-5286 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec11
5281
				A5D2E665195E174000A518E7 /* JSContextRefInternal.h in Headers */,
5338
				A5D2E665195E174000A518E7 /* JSContextRefInternal.h in Headers */,
5282
				A7D801A51880D66E0026C39B /* BuiltinExecutables.h in Headers */,
5339
				A7D801A51880D66E0026C39B /* BuiltinExecutables.h in Headers */,
5283
				A75EE9B218AAB7E200AAD043 /* BuiltinNames.h in Headers */,
5340
				A75EE9B218AAB7E200AAD043 /* BuiltinNames.h in Headers */,
5341
				0F2B9CF719D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.h in Headers */,
5284
				0FB7F39715ED8E4600F167B2 /* Butterfly.h in Headers */,
5342
				0FB7F39715ED8E4600F167B2 /* Butterfly.h in Headers */,
5285
				0FB7F39815ED8E4600F167B2 /* ButterflyInlines.h in Headers */,
5343
				0FB7F39815ED8E4600F167B2 /* ButterflyInlines.h in Headers */,
5286
				C2FCAE1117A9C24E0034C735 /* BytecodeBasicBlock.h in Headers */,
5344
				C2FCAE1117A9C24E0034C735 /* BytecodeBasicBlock.h in Headers */,
Lines 5339-5344 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec12
5339
				2A68295B1875F80500B6C3E2 /* CopyWriteBarrier.h in Headers */,
5397
				2A68295B1875F80500B6C3E2 /* CopyWriteBarrier.h in Headers */,
5340
				5DE6E5B30E1728EC00180407 /* create_hash_table in Headers */,
5398
				5DE6E5B30E1728EC00180407 /* create_hash_table in Headers */,
5341
				0F426A4B1460CD6E00131F8F /* DataFormat.h in Headers */,
5399
				0F426A4B1460CD6E00131F8F /* DataFormat.h in Headers */,
5400
				0F2B9CE519D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.h in Headers */,
5342
				0F2B66DF17B6B5AB00A7AE3F /* DataView.h in Headers */,
5401
				0F2B66DF17B6B5AB00A7AE3F /* DataView.h in Headers */,
5343
				BCD2034A0E17135E002C7E82 /* DateConstructor.h in Headers */,
5402
				BCD2034A0E17135E002C7E82 /* DateConstructor.h in Headers */,
5344
				41359CF30FDD89AD00206180 /* DateConversion.h in Headers */,
5403
				41359CF30FDD89AD00206180 /* DateConversion.h in Headers */,
Lines 5426-5435 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec13
5426
				A78A9779179738B8009DF744 /* DFGJITFinalizer.h in Headers */,
5485
				A78A9779179738B8009DF744 /* DFGJITFinalizer.h in Headers */,
5427
				0FC97F4018202119002C9B26 /* DFGJumpReplacement.h in Headers */,
5486
				0FC97F4018202119002C9B26 /* DFGJumpReplacement.h in Headers */,
5428
				A73A535B1799CD5D00170C19 /* DFGLazyJSValue.h in Headers */,
5487
				A73A535B1799CD5D00170C19 /* DFGLazyJSValue.h in Headers */,
5488
				0F2B9CE919D0BA7D00B1D1B5 /* DFGObjectMaterializationData.h in Headers */,
5429
				A7D9A29817A0BC7400EE2618 /* DFGLICMPhase.h in Headers */,
5489
				A7D9A29817A0BC7400EE2618 /* DFGLICMPhase.h in Headers */,
5430
				A7D89CFC17A0B8CC00773AD8 /* DFGLivenessAnalysisPhase.h in Headers */,
5490
				A7D89CFC17A0B8CC00773AD8 /* DFGLivenessAnalysisPhase.h in Headers */,
5431
				0FF0F19B16B729FA005DF95B /* DFGLongLivedState.h in Headers */,
5491
				0FF0F19B16B729FA005DF95B /* DFGLongLivedState.h in Headers */,
5432
				A767B5B617A0B9650063D940 /* DFGLoopPreHeaderCreationPhase.h in Headers */,
5492
				A767B5B617A0B9650063D940 /* DFGLoopPreHeaderCreationPhase.h in Headers */,
5493
				0F2B9CED19D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.h in Headers */,
5433
				A704D90717A0BAA8006BA554 /* DFGMergeMode.h in Headers */,
5494
				A704D90717A0BAA8006BA554 /* DFGMergeMode.h in Headers */,
5434
				0FB17663196B8F9E0091052A /* DFGPureValue.h in Headers */,
5495
				0FB17663196B8F9E0091052A /* DFGPureValue.h in Headers */,
5435
				0F2BDC451522801B00CD8910 /* DFGMinifiedGraph.h in Headers */,
5496
				0F2BDC451522801B00CD8910 /* DFGMinifiedGraph.h in Headers */,
Lines 5486-5491 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec14
5486
				0F2BDC471522802500CD8910 /* DFGValueRecoveryOverride.h in Headers */,
5547
				0F2BDC471522802500CD8910 /* DFGValueRecoveryOverride.h in Headers */,
5487
				0F2BDC481522802900CD8910 /* DFGValueSource.h in Headers */,
5548
				0F2BDC481522802900CD8910 /* DFGValueSource.h in Headers */,
5488
				0F620174143FCD330068B77C /* DFGVariableAccessData.h in Headers */,
5549
				0F620174143FCD330068B77C /* DFGVariableAccessData.h in Headers */,
5550
				0FAA3E0919D0C2CB00FAC9E2 /* DFGPromoteHeapAccess.h in Headers */,
5489
				0FDDBFB61666EEDA00C55FEF /* DFGVariableAccessDataDump.h in Headers */,
5551
				0FDDBFB61666EEDA00C55FEF /* DFGVariableAccessDataDump.h in Headers */,
5490
				0F2BDC491522809600CD8910 /* DFGVariableEvent.h in Headers */,
5552
				0F2BDC491522809600CD8910 /* DFGVariableEvent.h in Headers */,
5491
				0F2BDC4B1522809D00CD8910 /* DFGVariableEventStream.h in Headers */,
5553
				0F2BDC4B1522809D00CD8910 /* DFGVariableEventStream.h in Headers */,
Lines 5647-5652 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec15
5647
				1429D77C0ED20D7300B89619 /* Interpreter.h in Headers */,
5709
				1429D77C0ED20D7300B89619 /* Interpreter.h in Headers */,
5648
				860BD801148EA6F200112B2F /* Intrinsic.h in Headers */,
5710
				860BD801148EA6F200112B2F /* Intrinsic.h in Headers */,
5649
				BC18C4130E16F5CD00B34460 /* JavaScript.h in Headers */,
5711
				BC18C4130E16F5CD00B34460 /* JavaScript.h in Headers */,
5712
				0F2B9CF519D0BAC100B1D1B5 /* FTLExitPropertyValue.h in Headers */,
5650
				A503FA1A188E0FB000110F14 /* JavaScriptCallFrame.h in Headers */,
5713
				A503FA1A188E0FB000110F14 /* JavaScriptCallFrame.h in Headers */,
5651
				BC18C4140E16F5CD00B34460 /* JavaScriptCore.h in Headers */,
5714
				BC18C4140E16F5CD00B34460 /* JavaScriptCore.h in Headers */,
5652
				BC18C4150E16F5CD00B34460 /* JavaScriptCorePrefix.h in Headers */,
5715
				BC18C4150E16F5CD00B34460 /* JavaScriptCorePrefix.h in Headers */,
Lines 5690-5695 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec16
5690
				657CF45919BF6662004ACBF2 /* JSCallee.h in Headers */,
5753
				657CF45919BF6662004ACBF2 /* JSCallee.h in Headers */,
5691
				BC18C4190E16F5CD00B34460 /* JSCallbackConstructor.h in Headers */,
5754
				BC18C4190E16F5CD00B34460 /* JSCallbackConstructor.h in Headers */,
5692
				BC18C41A0E16F5CD00B34460 /* JSCallbackFunction.h in Headers */,
5755
				BC18C41A0E16F5CD00B34460 /* JSCallbackFunction.h in Headers */,
5756
				0F2B9CF919D0BAC100B1D1B5 /* FTLOperations.h in Headers */,
5693
				BC18C41B0E16F5CD00B34460 /* JSCallbackObject.h in Headers */,
5757
				BC18C41B0E16F5CD00B34460 /* JSCallbackObject.h in Headers */,
5694
				BC18C41C0E16F5CD00B34460 /* JSCallbackObjectFunctions.h in Headers */,
5758
				BC18C41C0E16F5CD00B34460 /* JSCallbackObjectFunctions.h in Headers */,
5695
				A7D801A91880D6A80026C39B /* JSCBuiltins.h in Headers */,
5759
				A7D801A91880D6A80026C39B /* JSCBuiltins.h in Headers */,
Lines 5790-5795 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec17
5790
				BC18C42D0E16F5CD00B34460 /* JSEnvironmentRecord.h in Headers */,
5854
				BC18C42D0E16F5CD00B34460 /* JSEnvironmentRecord.h in Headers */,
5791
				86E3C615167BABD7006D760A /* JSVirtualMachine.h in Headers */,
5855
				86E3C615167BABD7006D760A /* JSVirtualMachine.h in Headers */,
5792
				86E3C61D167BABEE006D760A /* JSVirtualMachineInternal.h in Headers */,
5856
				86E3C61D167BABEE006D760A /* JSVirtualMachineInternal.h in Headers */,
5857
				0F2B9CE719D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.h in Headers */,
5793
				A7CA3AE817DA41AE006538AF /* JSWeakMap.h in Headers */,
5858
				A7CA3AE817DA41AE006538AF /* JSWeakMap.h in Headers */,
5794
				A7482E93116A7CAD003B0712 /* JSWeakObjectMapRefInternal.h in Headers */,
5859
				A7482E93116A7CAD003B0712 /* JSWeakObjectMapRefInternal.h in Headers */,
5795
				A7482B9311671147003B0712 /* JSWeakObjectMapRefPrivate.h in Headers */,
5860
				A7482B9311671147003B0712 /* JSWeakObjectMapRefPrivate.h in Headers */,
Lines 5904-5909 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec18
5904
				0F13912A16771C36009CCB07 /* ProfilerBytecodeSequence.h in Headers */,
5969
				0F13912A16771C36009CCB07 /* ProfilerBytecodeSequence.h in Headers */,
5905
				0FF729BA166AD360000F5BA3 /* ProfilerCompilation.h in Headers */,
5970
				0FF729BA166AD360000F5BA3 /* ProfilerCompilation.h in Headers */,
5906
				0FF729BB166AD360000F5BA3 /* ProfilerCompilationKind.h in Headers */,
5971
				0FF729BB166AD360000F5BA3 /* ProfilerCompilationKind.h in Headers */,
5972
				0F2B9CE319D0BA7D00B1D1B5 /* DFGAvailabilityMap.h in Headers */,
5907
				0FF729BC166AD360000F5BA3 /* ProfilerCompiledBytecode.h in Headers */,
5973
				0FF729BC166AD360000F5BA3 /* ProfilerCompiledBytecode.h in Headers */,
5908
				0FF729BD166AD360000F5BA3 /* ProfilerDatabase.h in Headers */,
5974
				0FF729BD166AD360000F5BA3 /* ProfilerDatabase.h in Headers */,
5909
				2A05ABD61961DF2400341750 /* JSPropertyNameEnumerator.h in Headers */,
5975
				2A05ABD61961DF2400341750 /* JSPropertyNameEnumerator.h in Headers */,
Lines 6011-6016 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec19
6011
				0FD2C92416D01EE900C7803F /* StructureInlines.h in Headers */,
6077
				0FD2C92416D01EE900C7803F /* StructureInlines.h in Headers */,
6012
				C2FE18A416BAEC4000AF3061 /* StructureRareData.h in Headers */,
6078
				C2FE18A416BAEC4000AF3061 /* StructureRareData.h in Headers */,
6013
				C20BA92D16BB1C1500B3AEA2 /* StructureRareDataInlines.h in Headers */,
6079
				C20BA92D16BB1C1500B3AEA2 /* StructureRareDataInlines.h in Headers */,
6080
				0F2B9CEB19D0BA7D00B1D1B5 /* DFGPhiChildren.h in Headers */,
6014
				0F9332A514CA7DDD0085F3C6 /* StructureSet.h in Headers */,
6081
				0F9332A514CA7DDD0085F3C6 /* StructureSet.h in Headers */,
6015
				0F766D3915AE4A1F008F363E /* StructureStubClearingWatchpoint.h in Headers */,
6082
				0F766D3915AE4A1F008F363E /* StructureStubClearingWatchpoint.h in Headers */,
6016
				BCCF0D080EF0AAB900413C8F /* StructureStubInfo.h in Headers */,
6083
				BCCF0D080EF0AAB900413C8F /* StructureStubInfo.h in Headers */,
Lines 6579-6584 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec20
6579
				1429D8DD0ED2205B00B89619 /* CallFrame.cpp in Sources */,
6646
				1429D8DD0ED2205B00B89619 /* CallFrame.cpp in Sources */,
6580
				0F0B83B014BCF71600885B4F /* CallLinkInfo.cpp in Sources */,
6647
				0F0B83B014BCF71600885B4F /* CallLinkInfo.cpp in Sources */,
6581
				0F93329D14CA7DC30085F3C6 /* CallLinkStatus.cpp in Sources */,
6648
				0F93329D14CA7DC30085F3C6 /* CallLinkStatus.cpp in Sources */,
6649
				0F2B9CE419D0BA7D00B1D1B5 /* DFGInsertOSRHintsForUpdate.cpp in Sources */,
6582
				0F73D7AE165A142D00ACAB71 /* ClosureCallStubRoutine.cpp in Sources */,
6650
				0F73D7AE165A142D00ACAB71 /* ClosureCallStubRoutine.cpp in Sources */,
6583
				969A07960ED1D3AE00F1F681 /* CodeBlock.cpp in Sources */,
6651
				969A07960ED1D3AE00F1F681 /* CodeBlock.cpp in Sources */,
6584
				0F8F94401667633000D61971 /* CodeBlockHash.cpp in Sources */,
6652
				0F8F94401667633000D61971 /* CodeBlockHash.cpp in Sources */,
Lines 6623-6634 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec21
6623
				A7D9A29417A0BC7400EE2618 /* DFGAtTailAbstractState.cpp in Sources */,
6691
				A7D9A29417A0BC7400EE2618 /* DFGAtTailAbstractState.cpp in Sources */,
6624
				0F666EC61835672B00D017F1 /* DFGAvailability.cpp in Sources */,
6692
				0F666EC61835672B00D017F1 /* DFGAvailability.cpp in Sources */,
6625
				0F714CA416EA92F000F3EBEB /* DFGBackwardsPropagationPhase.cpp in Sources */,
6693
				0F714CA416EA92F000F3EBEB /* DFGBackwardsPropagationPhase.cpp in Sources */,
6694
				0F2B9CEC19D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.cpp in Sources */,
6626
				A7D89CF217A0B8CC00773AD8 /* DFGBasicBlock.cpp in Sources */,
6695
				A7D89CF217A0B8CC00773AD8 /* DFGBasicBlock.cpp in Sources */,
6627
				A70B083217A0B79B00DAF14B /* DFGBinarySwitch.cpp in Sources */,
6696
				A70B083217A0B79B00DAF14B /* DFGBinarySwitch.cpp in Sources */,
6628
				2A88067819107D5500CB0BBB /* DFGFunctionWhitelist.cpp in Sources */,
6697
				2A88067819107D5500CB0BBB /* DFGFunctionWhitelist.cpp in Sources */,
6629
				A7D89CF317A0B8CC00773AD8 /* DFGBlockInsertionSet.cpp in Sources */,
6698
				A7D89CF317A0B8CC00773AD8 /* DFGBlockInsertionSet.cpp in Sources */,
6630
				86EC9DC41328DF82002B2AD7 /* DFGByteCodeParser.cpp in Sources */,
6699
				86EC9DC41328DF82002B2AD7 /* DFGByteCodeParser.cpp in Sources */,
6631
				0FD82E2114172CE300179C94 /* DFGCapabilities.cpp in Sources */,
6700
				0FD82E2114172CE300179C94 /* DFGCapabilities.cpp in Sources */,
6701
				0F2B9CE619D0BA7D00B1D1B5 /* DFGObjectAllocationSinkingPhase.cpp in Sources */,
6632
				0FFFC95714EF90A000C72532 /* DFGCFAPhase.cpp in Sources */,
6702
				0FFFC95714EF90A000C72532 /* DFGCFAPhase.cpp in Sources */,
6633
				0F3B3A271544C995003ED0FF /* DFGCFGSimplificationPhase.cpp in Sources */,
6703
				0F3B3A271544C995003ED0FF /* DFGCFGSimplificationPhase.cpp in Sources */,
6634
				A77A423F17A0BBFD00A8DB81 /* DFGClobberize.cpp in Sources */,
6704
				A77A423F17A0BBFD00A8DB81 /* DFGClobberize.cpp in Sources */,
Lines 6651-6656 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec22
6651
				0FCA9113195E66A000426438 /* VariableWatchpointSet.cpp in Sources */,
6721
				0FCA9113195E66A000426438 /* VariableWatchpointSet.cpp in Sources */,
6652
				0FD81AD2154FB4EE00983E72 /* DFGDominators.cpp in Sources */,
6722
				0FD81AD2154FB4EE00983E72 /* DFGDominators.cpp in Sources */,
6653
				0FD3C82614115D4000FD81CB /* DFGDriver.cpp in Sources */,
6723
				0FD3C82614115D4000FD81CB /* DFGDriver.cpp in Sources */,
6724
				0F2B9CE219D0BA7D00B1D1B5 /* DFGAvailabilityMap.cpp in Sources */,
6725
				0F2B9CE819D0BA7D00B1D1B5 /* DFGObjectMaterializationData.cpp in Sources */,
6654
				0FF0F19E16B72A0B005DF95B /* DFGEdge.cpp in Sources */,
6726
				0FF0F19E16B72A0B005DF95B /* DFGEdge.cpp in Sources */,
6655
				0FBC0AE71496C7C400D4FBDD /* DFGExitProfile.cpp in Sources */,
6727
				0FBC0AE71496C7C400D4FBDD /* DFGExitProfile.cpp in Sources */,
6656
				0F0123321944EA1B00843A0C /* DFGValueStrength.cpp in Sources */,
6728
				0F0123321944EA1B00843A0C /* DFGValueStrength.cpp in Sources */,
Lines 6767-6772 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec23
6767
				0FC3CCFF19ADA410006AC72A /* DFGBlockWorklist.cpp in Sources */,
6839
				0FC3CCFF19ADA410006AC72A /* DFGBlockWorklist.cpp in Sources */,
6768
				0FEA0A0D170513DB00BB722C /* FTLJITCode.cpp in Sources */,
6840
				0FEA0A0D170513DB00BB722C /* FTLJITCode.cpp in Sources */,
6769
				A78A9780179738D5009DF744 /* FTLJITFinalizer.cpp in Sources */,
6841
				A78A9780179738D5009DF744 /* FTLJITFinalizer.cpp in Sources */,
6842
				0F2B9CF419D0BAC100B1D1B5 /* FTLExitPropertyValue.cpp in Sources */,
6770
				0F6B1CB5185FC9E900845D97 /* FTLJSCall.cpp in Sources */,
6843
				0F6B1CB5185FC9E900845D97 /* FTLJSCall.cpp in Sources */,
6771
				0F8F2B95172E04A0007DBDA5 /* FTLLink.cpp in Sources */,
6844
				0F8F2B95172E04A0007DBDA5 /* FTLLink.cpp in Sources */,
6772
				0FCEFADF180738C000472CE4 /* FTLLocation.cpp in Sources */,
6845
				0FCEFADF180738C000472CE4 /* FTLLocation.cpp in Sources */,
Lines 6818-6823 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec24
6818
				0F24E55517F0B71C00ABB217 /* InlineCallFrameSet.cpp in Sources */,
6891
				0F24E55517F0B71C00ABB217 /* InlineCallFrameSet.cpp in Sources */,
6819
				A5CEEE14187F3BAD00E55C99 /* InspectorAgent.cpp in Sources */,
6892
				A5CEEE14187F3BAD00E55C99 /* InspectorAgent.cpp in Sources */,
6820
				A593CF86184038CA00BFCE27 /* InspectorAgentRegistry.cpp in Sources */,
6893
				A593CF86184038CA00BFCE27 /* InspectorAgentRegistry.cpp in Sources */,
6894
				0F2B9CF619D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.cpp in Sources */,
6821
				A593CF7C1840360300BFCE27 /* InspectorBackendDispatcher.cpp in Sources */,
6895
				A593CF7C1840360300BFCE27 /* InspectorBackendDispatcher.cpp in Sources */,
6822
				2AF7382C18BBBF92008A5A37 /* StructureIDTable.cpp in Sources */,
6896
				2AF7382C18BBBF92008A5A37 /* StructureIDTable.cpp in Sources */,
6823
				A5FD0081189B191A00633231 /* InspectorConsoleAgent.cpp in Sources */,
6897
				A5FD0081189B191A00633231 /* InspectorConsoleAgent.cpp in Sources */,
Lines 6997-7002 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec25
6997
				0F9FC8C314E1B5FE00D52AE0 /* PolymorphicPutByIdList.cpp in Sources */,
7071
				0F9FC8C314E1B5FE00D52AE0 /* PolymorphicPutByIdList.cpp in Sources */,
6998
				0F98206016BFE38100240D02 /* PreciseJumpTargets.cpp in Sources */,
7072
				0F98206016BFE38100240D02 /* PreciseJumpTargets.cpp in Sources */,
6999
				95742F650DD11F5A000917FB /* Profile.cpp in Sources */,
7073
				95742F650DD11F5A000917FB /* Profile.cpp in Sources */,
7074
				0F2B9CF819D0BAC100B1D1B5 /* FTLOperations.cpp in Sources */,
7000
				95CD45760E1C4FDD0085358E /* ProfileGenerator.cpp in Sources */,
7075
				95CD45760E1C4FDD0085358E /* ProfileGenerator.cpp in Sources */,
7001
				95AB83560DA43C3000BC83F3 /* ProfileNode.cpp in Sources */,
7076
				95AB83560DA43C3000BC83F3 /* ProfileNode.cpp in Sources */,
7002
				0FF729AD166AD35C000F5BA3 /* ProfilerBytecode.cpp in Sources */,
7077
				0FF729AD166AD35C000F5BA3 /* ProfilerBytecode.cpp in Sources */,
Lines 7088-7093 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec26
7088
				0FF42745158EBE91004CB9FF /* udis86_syn-att.c in Sources */,
7163
				0FF42745158EBE91004CB9FF /* udis86_syn-att.c in Sources */,
7089
				0FF42746158EBE91004CB9FF /* udis86_syn-intel.c in Sources */,
7164
				0FF42746158EBE91004CB9FF /* udis86_syn-intel.c in Sources */,
7090
				0FF42747158EBE91004CB9FF /* udis86_syn.c in Sources */,
7165
				0FF42747158EBE91004CB9FF /* udis86_syn.c in Sources */,
7166
				0F2B9CEA19D0BA7D00B1D1B5 /* DFGPhiChildren.cpp in Sources */,
7091
				0FF42732158EBD58004CB9FF /* UDis86Disassembler.cpp in Sources */,
7167
				0FF42732158EBD58004CB9FF /* UDis86Disassembler.cpp in Sources */,
7092
				A76F279415F13C9600517D67 /* UnlinkedCodeBlock.cpp in Sources */,
7168
				A76F279415F13C9600517D67 /* UnlinkedCodeBlock.cpp in Sources */,
7093
				B59F89391891F29F00D5CCDC /* UnlinkedInstructionStream.cpp in Sources */,
7169
				B59F89391891F29F00D5CCDC /* UnlinkedInstructionStream.cpp in Sources */,
- Source/JavaScriptCore/bytecode/StructureSet.h +31 lines
Lines 166-171 public: Source/JavaScriptCore/bytecode/StructureSet.h_sec1
166
        return structureList()->list()[structureList()->m_length - 1];
166
        return structureList()->list()[structureList()->m_length - 1];
167
    }
167
    }
168
    
168
    
169
    class iterator {
170
    public:
171
        iterator()
172
            : m_set(nullptr)
173
            , m_index(0)
174
        {
175
        }
176
        
177
        iterator(const StructureSet* set, size_t index)
178
            : m_set(set)
179
            , m_index(index)
180
        {
181
        }
182
        
183
        Structure* operator*() const { return m_set->at(m_index); }
184
        iterator& operator++()
185
        {
186
            m_index++;
187
            return *this;
188
        }
189
        bool operator==(const iterator& other) const { return m_index == other.m_index; }
190
        bool operator!=(const iterator& other) const { return !(*this == other); }
191
        
192
    private:
193
        const StructureSet* m_set;
194
        size_t m_index;
195
    };
196
    
197
    iterator begin() const { return iterator(this, 0); }
198
    iterator end() const { return iterator(this, size()); }
199
    
169
    bool operator==(const StructureSet& other) const;
200
    bool operator==(const StructureSet& other) const;
170
    
201
    
171
    SpeculatedType speculationFromStructures() const;
202
    SpeculatedType speculationFromStructures() const;
- Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h -8 / +9 lines
Lines 32-37 Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h_sec1
32
#include "DFGBranchDirection.h"
32
#include "DFGBranchDirection.h"
33
#include "DFGGraph.h"
33
#include "DFGGraph.h"
34
#include "DFGNode.h"
34
#include "DFGNode.h"
35
#include "DFGPhiChildren.h"
35
36
36
namespace JSC { namespace DFG {
37
namespace JSC { namespace DFG {
37
38
Lines 80-97 public: Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h_sec2
80
    //
81
    //
81
    // This is guaranteed to be equivalent to doing:
82
    // This is guaranteed to be equivalent to doing:
82
    //
83
    //
83
    // if (state.startExecuting(index)) {
84
    // state.startExecuting()
84
    //     state.executeEdges(index);
85
    // state.executeEdges(index);
85
    //     result = state.executeEffects(index);
86
    // result = state.executeEffects(index);
86
    // } else
87
    //     result = true;
88
    bool execute(unsigned indexInBlock);
87
    bool execute(unsigned indexInBlock);
89
    bool execute(Node*);
88
    bool execute(Node*);
90
    
89
    
91
    // Indicate the start of execution of the node. It resets any state in the node
90
    // Indicate the start of execution of a node. It resets any state in the node
92
    // that is progressively built up by executeEdges() and executeEffects().
91
    // that is progressively built up by executeEdges() and executeEffects().
93
    bool startExecuting(Node*);
92
    void startExecuting();
94
    bool startExecuting(unsigned indexInBlock);
95
    
93
    
96
    // Abstractly execute the edges of the given node. This runs filterEdgeByUse()
94
    // Abstractly execute the edges of the given node. This runs filterEdgeByUse()
97
    // on all edges of the node. You can skip this step, if you have already used
95
    // on all edges of the node. You can skip this step, if you have already used
Lines 146-151 public: Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h_sec3
146
    FiltrationResult filter(AbstractValue&, SpeculatedType);
144
    FiltrationResult filter(AbstractValue&, SpeculatedType);
147
    FiltrationResult filterByValue(AbstractValue&, FrozenValue);
145
    FiltrationResult filterByValue(AbstractValue&, FrozenValue);
148
    
146
    
147
    PhiChildren* phiChildren() { return m_phiChildren.get(); }
148
    
149
private:
149
private:
150
    void clobberWorld(const CodeOrigin&, unsigned indexInBlock);
150
    void clobberWorld(const CodeOrigin&, unsigned indexInBlock);
151
    void clobberCapturedVars(const CodeOrigin&);
151
    void clobberCapturedVars(const CodeOrigin&);
Lines 195-200 private: Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h_sec4
195
    CodeBlock* m_codeBlock;
195
    CodeBlock* m_codeBlock;
196
    Graph& m_graph;
196
    Graph& m_graph;
197
    AbstractStateType& m_state;
197
    AbstractStateType& m_state;
198
    std::unique_ptr<PhiChildren> m_phiChildren;
198
};
199
};
199
200
200
} } // namespace JSC::DFG
201
} } // namespace JSC::DFG
- Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h -18 / +73 lines
Lines 43-48 AbstractInterpreter<AbstractStateType>:: Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h_sec1
43
    , m_graph(graph)
43
    , m_graph(graph)
44
    , m_state(state)
44
    , m_state(state)
45
{
45
{
46
    if (m_graph.m_form == SSA)
47
        m_phiChildren = std::make_unique<PhiChildren>(m_graph);
46
}
48
}
47
49
48
template<typename AbstractStateType>
50
template<typename AbstractStateType>
Lines 81-100 AbstractInterpreter<AbstractStateType>:: Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h_sec2
81
}
83
}
82
84
83
template<typename AbstractStateType>
85
template<typename AbstractStateType>
84
bool AbstractInterpreter<AbstractStateType>::startExecuting(Node* node)
86
void AbstractInterpreter<AbstractStateType>::startExecuting()
85
{
87
{
86
    ASSERT(m_state.block());
88
    ASSERT(m_state.block());
87
    ASSERT(m_state.isValid());
89
    ASSERT(m_state.isValid());
88
    
90
    
89
    m_state.setDidClobber(false);
91
    m_state.setDidClobber(false);
90
    
91
    return node->shouldGenerate();
92
}
93
94
template<typename AbstractStateType>
95
bool AbstractInterpreter<AbstractStateType>::startExecuting(unsigned indexInBlock)
96
{
97
    return startExecuting(m_state.block()->at(indexInBlock));
98
}
92
}
99
93
100
template<typename AbstractStateType>
94
template<typename AbstractStateType>
Lines 1260-1265 bool AbstractInterpreter<AbstractStateTy Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h_sec3
1260
        forNode(node).set(m_graph, node->structure());
1254
        forNode(node).set(m_graph, node->structure());
1261
        break;
1255
        break;
1262
        
1256
        
1257
    case PhantomNewObject:
1258
    case BottomValue:
1259
        m_state.setDidClobber(true); // Prevent constant folding.
1260
        // This claims to return bottom.
1261
        break;
1262
        
1263
    case PutByOffsetHint:
1264
    case PutStructureHint:
1265
        break;
1266
        
1267
    case MaterializeNewObject: {
1268
        StructureSet set;
1269
        
1270
        m_phiChildren->forAllTransitiveIncomingValues(
1271
            m_graph.varArgChild(node, 0).node(),
1272
            [&] (Node* incoming) {
1273
                set.add(incoming->castConstant<Structure*>());
1274
            });
1275
        
1276
        forNode(node).set(m_graph, set);
1277
        break;
1278
    }
1279
        
1263
    case CreateActivation:
1280
    case CreateActivation:
1264
        forNode(node).set(
1281
        forNode(node).set(
1265
            m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->activationStructure());
1282
            m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->activationStructure());
Lines 1459-1465 bool AbstractInterpreter<AbstractStateTy Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h_sec4
1459
        break;
1476
        break;
1460
        
1477
        
1461
    case CheckStructure: {
1478
    case CheckStructure: {
1462
        // FIXME: We should be able to propagate the structure sets of constants (i.e. prototypes).
1463
        AbstractValue& value = forNode(node->child1());
1479
        AbstractValue& value = forNode(node->child1());
1464
        ASSERT(!(value.m_type & ~SpecCell)); // Edge filtering should have already ensured this.
1480
        ASSERT(!(value.m_type & ~SpecCell)); // Edge filtering should have already ensured this.
1465
1481
Lines 1478-1483 bool AbstractInterpreter<AbstractStateTy Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h_sec5
1478
        break;
1494
        break;
1479
    }
1495
    }
1480
        
1496
        
1497
    case CheckStructureImmediate: {
1498
        // FIXME: This currently can only reason about one structure at a time.
1499
        // https://bugs.webkit.org/show_bug.cgi?id=136988
1500
        
1501
        AbstractValue& value = forNode(node->child1());
1502
        StructureSet& set = node->structureSet();
1503
        
1504
        if (value.value()) {
1505
            if (Structure* structure = jsDynamicCast<Structure*>(value.value())) {
1506
                if (set.contains(structure)) {
1507
                    m_state.setFoundConstants(true);
1508
                    break;
1509
                }
1510
            }
1511
            m_state.setIsValid(false);
1512
            break;
1513
        }
1514
        
1515
        if (m_phiChildren) {
1516
            bool allGood = true;
1517
            m_phiChildren->forAllTransitiveIncomingValues(
1518
                node,
1519
                [&] (Node* incoming) {
1520
                    if (Structure* structure = incoming->dynamicCastConstant<Structure*>()) {
1521
                        if (set.contains(structure))
1522
                            return;
1523
                    }
1524
                    allGood = false;
1525
                });
1526
            if (allGood) {
1527
                m_state.setFoundConstants(true);
1528
                break;
1529
            }
1530
        }
1531
            
1532
        if (Structure* structure = set.onlyStructure()) {
1533
            filterByValue(node->child1(), *m_graph.freeze(structure));
1534
            break;
1535
        }
1536
        
1537
        // Aw shucks, we can't do anything!
1538
        break;
1539
    }
1540
        
1481
    case PutStructure:
1541
    case PutStructure:
1482
        if (!forNode(node->child1()).m_structure.isClear()) {
1542
        if (!forNode(node->child1()).m_structure.isClear()) {
1483
            if (forNode(node->child1()).m_structure.onlyStructure() == node->transition()->next)
1543
            if (forNode(node->child1()).m_structure.onlyStructure() == node->transition()->next)
Lines 1957-1971 bool AbstractInterpreter<AbstractStateTy Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h_sec6
1957
2017
1958
    case CheckTierUpAndOSREnter:
2018
    case CheckTierUpAndOSREnter:
1959
    case LoopHint:
2019
    case LoopHint:
1960
        // We pretend that it can exit because it may want to get all state.
2020
    case ZombieHint:
1961
        break;
2021
        break;
1962
2022
1963
    case ZombieHint:
1964
    case Unreachable:
2023
    case Unreachable:
1965
    case LastNodeType:
2024
    case LastNodeType:
1966
    case ArithIMul:
2025
    case ArithIMul:
1967
    case FiatInt52:
2026
    case FiatInt52:
1968
    case BottomValue:
1969
        DFG_CRASH(m_graph, node, "Unexpected node type");
2027
        DFG_CRASH(m_graph, node, "Unexpected node type");
1970
        break;
2028
        break;
1971
    }
2029
    }
Lines 1983-1991 template<typename AbstractStateType> Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h_sec7
1983
bool AbstractInterpreter<AbstractStateType>::execute(unsigned indexInBlock)
2041
bool AbstractInterpreter<AbstractStateType>::execute(unsigned indexInBlock)
1984
{
2042
{
1985
    Node* node = m_state.block()->at(indexInBlock);
2043
    Node* node = m_state.block()->at(indexInBlock);
1986
    if (!startExecuting(node))
1987
        return true;
1988
    
2044
    
2045
    startExecuting();
1989
    executeEdges(node);
2046
    executeEdges(node);
1990
    return executeEffects(indexInBlock, node);
2047
    return executeEffects(indexInBlock, node);
1991
}
2048
}
Lines 1993-2001 bool AbstractInterpreter<AbstractStateTy Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h_sec8
1993
template<typename AbstractStateType>
2050
template<typename AbstractStateType>
1994
bool AbstractInterpreter<AbstractStateType>::execute(Node* node)
2051
bool AbstractInterpreter<AbstractStateType>::execute(Node* node)
1995
{
2052
{
1996
    if (!startExecuting(node))
2053
    startExecuting();
1997
        return true;
1998
    
1999
    executeEdges(node);
2054
    executeEdges(node);
2000
    return executeEffects(UINT_MAX, node);
2055
    return executeEffects(UINT_MAX, node);
2001
}
2056
}
- Source/JavaScriptCore/dfg/DFGAvailability.h +12 lines
Lines 85-90 public: Source/JavaScriptCore/dfg/DFGAvailability.h_sec1
85
    bool nodeIsUnavailable() const { return m_node == unavailableMarker(); }
85
    bool nodeIsUnavailable() const { return m_node == unavailableMarker(); }
86
    
86
    
87
    bool hasNode() const { return !nodeIsUndecided() && !nodeIsUnavailable(); }
87
    bool hasNode() const { return !nodeIsUndecided() && !nodeIsUnavailable(); }
88
    bool shouldUseNode() const { return !isFlushUseful() && hasNode(); }
88
    
89
    
89
    Node* node() const
90
    Node* node() const
90
    {
91
    {
Lines 94-99 public: Source/JavaScriptCore/dfg/DFGAvailability.h_sec2
94
    }
95
    }
95
    
96
    
96
    FlushedAt flushedAt() const { return m_flushedAt; }
97
    FlushedAt flushedAt() const { return m_flushedAt; }
98
    bool isFlushUseful() const
99
    {
100
        return flushedAt().format() != DeadFlush && flushedAt().format() != ConflictingFlush;
101
    }
102
    
103
    bool isDead() const { return !isFlushUseful() && !hasNode(); }
97
    
104
    
98
    bool operator!() const { return nodeIsUnavailable() && flushedAt().format() == ConflictingFlush; }
105
    bool operator!() const { return nodeIsUnavailable() && flushedAt().format() == ConflictingFlush; }
99
106
Lines 103-108 public: Source/JavaScriptCore/dfg/DFGAvailability.h_sec3
103
            && m_flushedAt == other.m_flushedAt;
110
            && m_flushedAt == other.m_flushedAt;
104
    }
111
    }
105
    
112
    
113
    bool operator!=(const Availability& other) const
114
    {
115
        return !(*this == other);
116
    }
117
    
106
    Availability merge(const Availability& other) const
118
    Availability merge(const Availability& other) const
107
    {
119
    {
108
        return Availability(
120
        return Availability(
- Source/JavaScriptCore/dfg/DFGAvailabilityMap.cpp +96 lines
Line 0 Source/JavaScriptCore/dfg/DFGAvailabilityMap.cpp_sec1
1
/*
2
 * Copyright (C) 2014 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 "DFGAvailabilityMap.h"
28
29
#if ENABLE(DFG_JIT)
30
31
#include "OperandsInlines.h"
32
#include <wtf/ListDump.h>
33
34
namespace JSC { namespace DFG {
35
36
void AvailabilityMap::prune()
37
{
38
    if (m_heap.isEmpty())
39
        return;
40
    
41
    HashSet<Node*> possibleNodes;
42
    
43
    for (unsigned i = m_locals.size(); i--;) {
44
        if (m_locals[i].hasNode())
45
            possibleNodes.add(m_locals[i].node());
46
    }
47
48
    int oldPossibleNodesSize;
49
    do {
50
        oldPossibleNodesSize = possibleNodes.size();
51
        for (auto pair : m_heap) {
52
            if (pair.value.hasNode() && possibleNodes.contains(pair.key.base()))
53
                possibleNodes.add(pair.value.node());
54
        }
55
    } while (oldPossibleNodesSize != possibleNodes.size());
56
    
57
    HashMap<PromotedHeapLocation, Availability> newHeap;
58
    for (auto pair : m_heap) {
59
        if (possibleNodes.contains(pair.key.base()))
60
            newHeap.add(pair.key, pair.value);
61
    }
62
    m_heap = newHeap;
63
}
64
65
void AvailabilityMap::clear()
66
{
67
    m_locals.fill(Availability());
68
    m_heap.clear();
69
}
70
71
void AvailabilityMap::dump(PrintStream& out) const
72
{
73
    out.print("{locals = ", m_locals, "; heap = ", mapDump(m_heap), "}");
74
}
75
76
bool AvailabilityMap::operator==(const AvailabilityMap& other) const
77
{
78
    return m_locals == other.m_locals
79
        && m_heap == other.m_heap;
80
}
81
82
void AvailabilityMap::merge(const AvailabilityMap& other)
83
{
84
    for (unsigned i = other.m_locals.size(); i--;)
85
        m_locals[i] = other.m_locals[i].merge(m_locals[i]);
86
    
87
    for (auto pair : other.m_heap) {
88
        auto result = m_heap.add(pair.key, Availability());
89
        result.iterator->value = pair.value.merge(result.iterator->value);
90
    }
91
}
92
93
} } // namespace JSC::DFG
94
95
#endif // ENABLE(DFG_JIT)
96
- Source/JavaScriptCore/dfg/DFGAvailabilityMap.h +64 lines
Line 0 Source/JavaScriptCore/dfg/DFGAvailabilityMap.h_sec1
1
/*
2
 * Copyright (C) 2014 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 DFGAvailabilityMap_h
27
#define DFGAvailabilityMap_h
28
29
#if ENABLE(DFG_JIT)
30
31
#include "DFGAvailability.h"
32
#include "DFGPromotedHeapLocation.h"
33
34
namespace JSC { namespace DFG {
35
36
struct AvailabilityMap {
37
    void prune();
38
    void clear();
39
    
40
    void dump(PrintStream& out) const;
41
    
42
    bool operator==(const AvailabilityMap& other) const;
43
    
44
    void merge(const AvailabilityMap& other);
45
    
46
    template<typename Functor>
47
    void forEachAvailability(const Functor& functor)
48
    {
49
        for (unsigned i = m_locals.size(); i--;)
50
            functor(m_locals[i]);
51
        for (auto pair : m_heap)
52
            functor(pair.value);
53
    }
54
    
55
    Operands<Availability> m_locals;
56
    HashMap<PromotedHeapLocation, Availability> m_heap;
57
};
58
59
} } // namespace JSC::DFG
60
61
#endif // ENABLE(DFG_JIT)
62
63
#endif // DFGAvailabilityMap_h
64
- Source/JavaScriptCore/dfg/DFGBasicBlock.cpp -2 / +2 lines
Lines 118-126 void BasicBlock::dump(PrintStream& out) Source/JavaScriptCore/dfg/DFGBasicBlock.cpp_sec1
118
}
118
}
119
119
120
BasicBlock::SSAData::SSAData(BasicBlock* block)
120
BasicBlock::SSAData::SSAData(BasicBlock* block)
121
    : availabilityAtHead(OperandsLike, block->variablesAtHead)
122
    , availabilityAtTail(OperandsLike, block->variablesAtHead)
123
{
121
{
122
    availabilityAtHead.m_locals = Operands<Availability>(OperandsLike, block->variablesAtHead);
123
    availabilityAtTail.m_locals = Operands<Availability>(OperandsLike, block->variablesAtHead);
124
}
124
}
125
125
126
BasicBlock::SSAData::~SSAData() { }
126
BasicBlock::SSAData::~SSAData() { }
- Source/JavaScriptCore/dfg/DFGBasicBlock.h -3 / +79 lines
Lines 30-35 Source/JavaScriptCore/dfg/DFGBasicBlock.h_sec1
30
30
31
#include "DFGAbstractValue.h"
31
#include "DFGAbstractValue.h"
32
#include "DFGAvailability.h"
32
#include "DFGAvailability.h"
33
#include "DFGAvailabilityMap.h"
33
#include "DFGBranchDirection.h"
34
#include "DFGBranchDirection.h"
34
#include "DFGFlushedAt.h"
35
#include "DFGFlushedAt.h"
35
#include "DFGNode.h"
36
#include "DFGNode.h"
Lines 46-51 class Graph; Source/JavaScriptCore/dfg/DFGBasicBlock.h_sec2
46
class InsertionSet;
47
class InsertionSet;
47
48
48
typedef Vector<BasicBlock*, 2> PredecessorList;
49
typedef Vector<BasicBlock*, 2> PredecessorList;
50
typedef Vector<Node*, 8> BlockNodeList;
49
51
50
struct BasicBlock : RefCounted<BasicBlock> {
52
struct BasicBlock : RefCounted<BasicBlock> {
51
    BasicBlock(
53
    BasicBlock(
Lines 85-90 struct BasicBlock : RefCounted<BasicBloc Source/JavaScriptCore/dfg/DFGBasicBlock.h_sec3
85
    bool isInPhis(Node* node) const;
87
    bool isInPhis(Node* node) const;
86
    bool isInBlock(Node* myNode) const;
88
    bool isInBlock(Node* myNode) const;
87
    
89
    
90
    BlockNodeList::iterator begin() { return m_nodes.begin(); }
91
    BlockNodeList::iterator end() { return m_nodes.end(); }
92
    
88
    unsigned numSuccessors() { return last()->numSuccessors(); }
93
    unsigned numSuccessors() { return last()->numSuccessors(); }
89
    
94
    
90
    BasicBlock*& successor(unsigned index)
95
    BasicBlock*& successor(unsigned index)
Lines 96-101 struct BasicBlock : RefCounted<BasicBloc Source/JavaScriptCore/dfg/DFGBasicBlock.h_sec4
96
        return last()->successorForCondition(condition);
101
        return last()->successorForCondition(condition);
97
    }
102
    }
98
    
103
    
104
    class SuccessorsIterable {
105
    public:
106
        SuccessorsIterable()
107
            : m_block(nullptr)
108
        {
109
        }
110
        
111
        SuccessorsIterable(BasicBlock* block)
112
            : m_block(block)
113
        {
114
        }
115
        
116
        class iterator {
117
        public:
118
            iterator()
119
                : m_block(nullptr)
120
                , m_index(UINT_MAX)
121
            {
122
            }
123
            
124
            iterator(BasicBlock* block, unsigned index)
125
                : m_block(block)
126
                , m_index(index)
127
            {
128
            }
129
            
130
            BasicBlock* operator*()
131
            {
132
                return m_block->successor(m_index);
133
            }
134
            
135
            iterator& operator++()
136
            {
137
                m_index++;
138
                return *this;
139
            }
140
            
141
            bool operator==(const iterator& other) const
142
            {
143
                return m_index == other.m_index;
144
            }
145
            
146
            bool operator!=(const iterator& other) const
147
            {
148
                return !(*this == other);
149
            }
150
        private:
151
            BasicBlock* m_block;
152
            unsigned m_index;
153
        };
154
        
155
        iterator begin()
156
        {
157
            return iterator(m_block, 0);
158
        }
159
        
160
        iterator end()
161
        {
162
            return iterator(m_block, m_block->numSuccessors());
163
        }
164
        
165
    private:
166
        BasicBlock* m_block;
167
    };
168
    
169
    SuccessorsIterable successors()
170
    {
171
        return SuccessorsIterable(this);
172
    }
173
    
99
    void removePredecessor(BasicBlock* block);
174
    void removePredecessor(BasicBlock* block);
100
    void replacePredecessor(BasicBlock* from, BasicBlock* to);
175
    void replacePredecessor(BasicBlock* from, BasicBlock* to);
101
176
Lines 169-176 struct BasicBlock : RefCounted<BasicBloc Source/JavaScriptCore/dfg/DFGBasicBlock.h_sec5
169
    unsigned innerMostLoopIndices[numberOfInnerMostLoopIndices];
244
    unsigned innerMostLoopIndices[numberOfInnerMostLoopIndices];
170
245
171
    struct SSAData {
246
    struct SSAData {
172
        Operands<Availability> availabilityAtHead;
247
        AvailabilityMap availabilityAtHead;
173
        Operands<Availability> availabilityAtTail;
248
        AvailabilityMap availabilityAtTail;
249
        
174
        HashSet<Node*> liveAtHead;
250
        HashSet<Node*> liveAtHead;
175
        HashSet<Node*> liveAtTail;
251
        HashSet<Node*> liveAtTail;
176
        HashMap<Node*, AbstractValue> valuesAtHead;
252
        HashMap<Node*, AbstractValue> valuesAtHead;
Lines 183-189 struct BasicBlock : RefCounted<BasicBloc Source/JavaScriptCore/dfg/DFGBasicBlock.h_sec6
183
    
259
    
184
private:
260
private:
185
    friend class InsertionSet;
261
    friend class InsertionSet;
186
    Vector<Node*, 8> m_nodes;
262
    BlockNodeList m_nodes;
187
};
263
};
188
264
189
typedef Vector<BasicBlock*, 5> BlockList;
265
typedef Vector<BasicBlock*, 5> BlockList;
- Source/JavaScriptCore/dfg/DFGClobberize.h -5 / +6 lines
Lines 109-114 void clobberize(Graph& graph, Node* node Source/JavaScriptCore/dfg/DFGClobberize.h_sec1
109
    case HardPhantom:
109
    case HardPhantom:
110
    case Check:
110
    case Check:
111
    case ExtractOSREntryLocal:
111
    case ExtractOSREntryLocal:
112
    case CheckStructureImmediate:
112
        return;
113
        return;
113
        
114
        
114
    case BitAnd:
115
    case BitAnd:
Lines 273-278 void clobberize(Graph& graph, Node* node Source/JavaScriptCore/dfg/DFGClobberize.h_sec2
273
    case ProfileDidCall:
274
    case ProfileDidCall:
274
    case StoreBarrier:
275
    case StoreBarrier:
275
    case StoreBarrierWithNullCheck:
276
    case StoreBarrierWithNullCheck:
277
    case PutByOffsetHint:
278
    case PutStructureHint:
276
        write(SideState);
279
        write(SideState);
277
        return;
280
        return;
278
        
281
        
Lines 787-803 void clobberize(Graph& graph, Node* node Source/JavaScriptCore/dfg/DFGClobberize.h_sec3
787
    case NewObject:
790
    case NewObject:
788
    case NewRegexp:
791
    case NewRegexp:
789
    case NewStringObject:
792
    case NewStringObject:
790
        read(HeapObjectCount);
793
    case PhantomNewObject:
791
        write(HeapObjectCount);
794
    case MaterializeNewObject:
792
        return;
793
        
794
    case NewFunctionNoCheck:
795
    case NewFunctionNoCheck:
795
    case NewFunction:
796
    case NewFunction:
796
    case NewFunctionExpression:
797
    case NewFunctionExpression:
797
        read(HeapObjectCount);
798
        read(HeapObjectCount);
798
        write(HeapObjectCount);
799
        write(HeapObjectCount);
799
        return;
800
        return;
800
801
        
801
    case RegExpExec:
802
    case RegExpExec:
802
    case RegExpTest:
803
    case RegExpTest:
803
        read(RegExpState);
804
        read(RegExpState);
- Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp +36 lines
Lines 124-129 private: Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp_sec1
124
                break;
124
                break;
125
            }
125
            }
126
                
126
                
127
            case CheckStructureImmediate: {
128
                AbstractValue& value = m_state.forNode(node->child1());
129
                StructureSet& set = node->structureSet();
130
                
131
                if (value.value()) {
132
                    if (Structure* structure = jsDynamicCast<Structure*>(value.value())) {
133
                        if (set.contains(structure)) {
134
                            m_interpreter.execute(indexInBlock);
135
                            node->convertToPhantom();
136
                            eliminated = true;
137
                            break;
138
                        }
139
                    }
140
                }
141
                
142
                if (PhiChildren* phiChildren = m_interpreter.phiChildren()) {
143
                    bool allGood = true;
144
                    phiChildren->forAllTransitiveIncomingValues(
145
                        node,
146
                        [&] (Node* incoming) {
147
                            if (Structure* structure = incoming->dynamicCastConstant<Structure*>()) {
148
                                if (set.contains(structure))
149
                                    return;
150
                            }
151
                            allGood = false;
152
                        });
153
                    if (allGood) {
154
                        m_interpreter.execute(indexInBlock);
155
                        node->convertToPhantom();
156
                        eliminated = true;
157
                        break;
158
                    }
159
                }
160
                break;
161
            }
162
                
127
            case CheckArray:
163
            case CheckArray:
128
            case Arrayify: {
164
            case Arrayify: {
129
                if (!node->arrayMode().alreadyChecked(m_graph, node, m_state.forNode(node->child1())))
165
                if (!node->arrayMode().alreadyChecked(m_graph, node, m_state.forNode(node->child1())))
- Source/JavaScriptCore/dfg/DFGDoesGC.cpp +5 lines
Lines 199-204 bool doesGC(Graph& graph, Node* node) Source/JavaScriptCore/dfg/DFGDoesGC.cpp_sec1
199
    case BooleanToNumber:
199
    case BooleanToNumber:
200
    case CheckBadCell:
200
    case CheckBadCell:
201
    case BottomValue:
201
    case BottomValue:
202
    case PhantomNewObject:
203
    case PutByOffsetHint:
204
    case CheckStructureImmediate:
205
    case PutStructureHint:
202
        return false;
206
        return false;
203
207
204
    case CreateActivation:
208
    case CreateActivation:
Lines 225-230 bool doesGC(Graph& graph, Node* node) Source/JavaScriptCore/dfg/DFGDoesGC.cpp_sec2
225
    case GetGenericPropertyEnumerator:
229
    case GetGenericPropertyEnumerator:
226
    case GetEnumeratorPname:
230
    case GetEnumeratorPname:
227
    case ToIndexString:
231
    case ToIndexString:
232
    case MaterializeNewObject:
228
        return true;
233
        return true;
229
        
234
        
230
    case MultiPutByOffset:
235
    case MultiPutByOffset:
- Source/JavaScriptCore/dfg/DFGFixupPhase.cpp +5 lines
Lines 1013-1018 private: Source/JavaScriptCore/dfg/DFGFixupPhase.cpp_sec1
1013
        case Int52Constant:
1013
        case Int52Constant:
1014
        case Identity: // This should have been cleaned up.
1014
        case Identity: // This should have been cleaned up.
1015
        case BooleanToNumber:
1015
        case BooleanToNumber:
1016
        case PhantomNewObject:
1017
        case PutByOffsetHint:
1018
        case CheckStructureImmediate:
1019
        case PutStructureHint:
1020
        case MaterializeNewObject:
1016
            // These are just nodes that we don't currently expect to see during fixup.
1021
            // These are just nodes that we don't currently expect to see during fixup.
1017
            // If we ever wanted to insert them prior to fixup, then we just have to create
1022
            // If we ever wanted to insert them prior to fixup, then we just have to create
1018
            // fixup rules for them.
1023
            // fixup rules for them.
- Source/JavaScriptCore/dfg/DFGFlushedAt.cpp -1 / +3 lines
Lines 36-43 void FlushedAt::dump(PrintStream& out) c Source/JavaScriptCore/dfg/DFGFlushedAt.cpp_sec1
36
{
36
{
37
    if (m_format == DeadFlush || m_format == ConflictingFlush)
37
    if (m_format == DeadFlush || m_format == ConflictingFlush)
38
        out.print(m_format);
38
        out.print(m_format);
39
    else
39
    else if (m_virtualRegister.isValid())
40
        out.print("r", m_virtualRegister, ":", m_format);
40
        out.print("r", m_virtualRegister, ":", m_format);
41
    else
42
        out.print(m_format);
41
}
43
}
42
44
43
void FlushedAt::dumpInContext(PrintStream& out, DumpContext*) const
45
void FlushedAt::dumpInContext(PrintStream& out, DumpContext*) const
- Source/JavaScriptCore/dfg/DFGFlushedAt.h -2 lines
Lines 52-59 public: Source/JavaScriptCore/dfg/DFGFlushedAt.h_sec1
52
    {
52
    {
53
        if (format == DeadFlush)
53
        if (format == DeadFlush)
54
            ASSERT(!virtualRegister.isValid());
54
            ASSERT(!virtualRegister.isValid());
55
        else
56
            ASSERT(virtualRegister.isValid());
57
    }
55
    }
58
    
56
    
59
    bool operator!() const { return m_format == DeadFlush; }
57
    bool operator!() const { return m_format == DeadFlush; }
- Source/JavaScriptCore/dfg/DFGGraph.cpp +21 lines
Lines 562-567 void Graph::resetReachability() Source/JavaScriptCore/dfg/DFGGraph.cpp_sec1
562
    determineReachability();
562
    determineReachability();
563
}
563
}
564
564
565
void Graph::mergeRelevantToOSR()
566
{
567
    for (BasicBlock* block : blocksInNaturalOrder()) {
568
        for (Node* node : *block) {
569
            switch (node->op()) {
570
            case MovHint:
571
                node->child1()->mergeFlags(NodeRelevantToOSR);
572
                break;
573
                
574
            case PutStructureHint:
575
            case PutByOffsetHint:
576
                node->child2()->mergeFlags(NodeRelevantToOSR);
577
                break;
578
                
579
            default:
580
                break;
581
            }
582
        }
583
    }
584
}
585
565
namespace {
586
namespace {
566
587
567
class RefCountCalculator {
588
class RefCountCalculator {
- Source/JavaScriptCore/dfg/DFGGraph.h -41 / +138 lines
Lines 55-60 class ExecState; Source/JavaScriptCore/dfg/DFGGraph.h_sec1
55
55
56
namespace DFG {
56
namespace DFG {
57
57
58
#define DFG_NODE_DO_TO_CHILDREN(graph, node, thingToDo) do {            \
59
        Node* _node = (node);                                           \
60
        if (_node->flags() & NodeHasVarArgs) {                          \
61
            for (unsigned _childIdx = _node->firstChild();              \
62
                _childIdx < _node->firstChild() + _node->numChildren(); \
63
                _childIdx++) {                                          \
64
                if (!!(graph).m_varArgChildren[_childIdx])              \
65
                    thingToDo(_node, (graph).m_varArgChildren[_childIdx]); \
66
            }                                                           \
67
        } else {                                                        \
68
            if (!_node->child1()) {                                     \
69
                ASSERT(                                                 \
70
                    !_node->child2()                                    \
71
                    && !_node->child3());                               \
72
                break;                                                  \
73
            }                                                           \
74
            thingToDo(_node, _node->child1());                          \
75
                                                                        \
76
            if (!_node->child2()) {                                     \
77
                ASSERT(!_node->child3());                               \
78
                break;                                                  \
79
            }                                                           \
80
            thingToDo(_node, _node->child2());                          \
81
                                                                        \
82
            if (!_node->child3())                                       \
83
                break;                                                  \
84
            thingToDo(_node, _node->child3());                          \
85
        }                                                               \
86
    } while (false)
87
88
#define DFG_ASSERT(graph, node, assertion) do {                         \
89
        if (!!(assertion))                                              \
90
            break;                                                      \
91
        (graph).handleAssertionFailure(                                 \
92
            (node), __FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion); \
93
    } while (false)
94
95
#define DFG_CRASH(graph, node, reason)                                  \
96
    (graph).handleAssertionFailure(                                     \
97
        (node), __FILE__, __LINE__, WTF_PRETTY_FUNCTION, (reason));
98
58
struct InlineVariableData {
99
struct InlineVariableData {
59
    InlineCallFrame* inlineCallFrame;
100
    InlineCallFrame* inlineCallFrame;
60
    unsigned argumentPositionStart;
101
    unsigned argumentPositionStart;
Lines 565-570 public: Source/JavaScriptCore/dfg/DFGGraph.h_sec2
565
    void determineReachability();
606
    void determineReachability();
566
    void resetReachability();
607
    void resetReachability();
567
    
608
    
609
    void mergeRelevantToOSR();
610
    
568
    void computeRefCounts();
611
    void computeRefCounts();
569
    
612
    
570
    unsigned varArgNumChildren(Node* node)
613
    unsigned varArgNumChildren(Node* node)
Lines 676-681 public: Source/JavaScriptCore/dfg/DFGGraph.h_sec3
676
    BlockList blocksInPreOrder();
719
    BlockList blocksInPreOrder();
677
    BlockList blocksInPostOrder();
720
    BlockList blocksInPostOrder();
678
    
721
    
722
    class NaturalBlockIterable {
723
    public:
724
        NaturalBlockIterable()
725
            : m_graph(nullptr)
726
        {
727
        }
728
        
729
        NaturalBlockIterable(Graph& graph)
730
            : m_graph(&graph)
731
        {
732
        }
733
        
734
        class iterator {
735
        public:
736
            iterator()
737
                : m_graph(nullptr)
738
                , m_index(0)
739
            {
740
            }
741
            
742
            iterator(Graph& graph, BlockIndex index)
743
                : m_graph(&graph)
744
                , m_index(findNext(index))
745
            {
746
            }
747
            
748
            BasicBlock *operator*()
749
            {
750
                return m_graph->block(m_index);
751
            }
752
            
753
            iterator& operator++()
754
            {
755
                m_index = findNext(m_index + 1);
756
                return *this;
757
            }
758
            
759
            bool operator==(const iterator& other) const
760
            {
761
                return m_index == other.m_index;
762
            }
763
            
764
            bool operator!=(const iterator& other) const
765
            {
766
                return !(*this == other);
767
            }
768
            
769
        private:
770
            BlockIndex findNext(BlockIndex index)
771
            {
772
                while (index < m_graph->numBlocks() && !m_graph->block(index))
773
                    index++;
774
                return index;
775
            }
776
            
777
            Graph* m_graph;
778
            BlockIndex m_index;
779
        };
780
        
781
        iterator begin()
782
        {
783
            return iterator(*m_graph, 0);
784
        }
785
        
786
        iterator end()
787
        {
788
            return iterator(*m_graph, m_graph->numBlocks());
789
        }
790
        
791
    private:
792
        Graph* m_graph;
793
    };
794
    
795
    NaturalBlockIterable blocksInNaturalOrder()
796
    {
797
        return NaturalBlockIterable(*this);
798
    }
799
    
800
    template<typename ChildFunctor>
801
    void doToChildrenWithNode(Node* node, const ChildFunctor& functor)
802
    {
803
        DFG_NODE_DO_TO_CHILDREN(*this, node, functor);
804
    }
805
    
806
    template<typename ChildFunctor>
807
    void doToChildren(Node* node, const ChildFunctor& functor)
808
    {
809
        doToChildrenWithNode(
810
            node,
811
            [&functor] (Node*, Edge& edge) {
812
                functor(edge);
813
            });
814
    }
815
    
679
    Profiler::Compilation* compilation() { return m_plan.compilation.get(); }
816
    Profiler::Compilation* compilation() { return m_plan.compilation.get(); }
680
    
817
    
681
    DesiredIdentifiers& identifiers() { return m_plan.identifiers; }
818
    DesiredIdentifiers& identifiers() { return m_plan.identifiers; }
Lines 736-741 public: Source/JavaScriptCore/dfg/DFGGraph.h_sec4
736
    Bag<SwitchData> m_switchData;
873
    Bag<SwitchData> m_switchData;
737
    Bag<MultiGetByOffsetData> m_multiGetByOffsetData;
874
    Bag<MultiGetByOffsetData> m_multiGetByOffsetData;
738
    Bag<MultiPutByOffsetData> m_multiPutByOffsetData;
875
    Bag<MultiPutByOffsetData> m_multiPutByOffsetData;
876
    Bag<ObjectMaterializationData> m_objectMaterializationData;
739
    Vector<InlineVariableData, 4> m_inlineVariableData;
877
    Vector<InlineVariableData, 4> m_inlineVariableData;
740
    HashMap<CodeBlock*, std::unique_ptr<FullBytecodeLiveness>> m_bytecodeLiveness;
878
    HashMap<CodeBlock*, std::unique_ptr<FullBytecodeLiveness>> m_bytecodeLiveness;
741
    bool m_hasArguments;
879
    bool m_hasArguments;
Lines 786-832 private: Source/JavaScriptCore/dfg/DFGGraph.h_sec5
786
    }
924
    }
787
};
925
};
788
926
789
#define DFG_NODE_DO_TO_CHILDREN(graph, node, thingToDo) do {            \
790
        Node* _node = (node);                                           \
791
        if (_node->flags() & NodeHasVarArgs) {                          \
792
            for (unsigned _childIdx = _node->firstChild();              \
793
                _childIdx < _node->firstChild() + _node->numChildren(); \
794
                _childIdx++) {                                          \
795
                if (!!(graph).m_varArgChildren[_childIdx])              \
796
                    thingToDo(_node, (graph).m_varArgChildren[_childIdx]); \
797
            }                                                           \
798
        } else {                                                        \
799
            if (!_node->child1()) {                                     \
800
                ASSERT(                                                 \
801
                    !_node->child2()                                    \
802
                    && !_node->child3());                               \
803
                break;                                                  \
804
            }                                                           \
805
            thingToDo(_node, _node->child1());                          \
806
                                                                        \
807
            if (!_node->child2()) {                                     \
808
                ASSERT(!_node->child3());                               \
809
                break;                                                  \
810
            }                                                           \
811
            thingToDo(_node, _node->child2());                          \
812
                                                                        \
813
            if (!_node->child3())                                       \
814
                break;                                                  \
815
            thingToDo(_node, _node->child3());                          \
816
        }                                                               \
817
    } while (false)
818
819
#define DFG_ASSERT(graph, node, assertion) do {                         \
820
        if (!!(assertion))                                              \
821
            break;                                                      \
822
        (graph).handleAssertionFailure(                                 \
823
            (node), __FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion); \
824
    } while (false)
825
826
#define DFG_CRASH(graph, node, reason)                                  \
827
    (graph).handleAssertionFailure(                                     \
828
        (node), __FILE__, __LINE__, WTF_PRETTY_FUNCTION, (reason));
829
830
} } // namespace JSC::DFG
927
} } // namespace JSC::DFG
831
928
832
#endif
929
#endif
- Source/JavaScriptCore/dfg/DFGHeapLocation.cpp +4 lines
Lines 147-152 void printInternal(PrintStream& out, Loc Source/JavaScriptCore/dfg/DFGHeapLocation.cpp_sec1
147
    case AllocationProfileWatchpointLoc:
147
    case AllocationProfileWatchpointLoc:
148
        out.print("AllocationProfileWatchpointLoc");
148
        out.print("AllocationProfileWatchpointLoc");
149
        return;
149
        return;
150
        
151
    case StructureLoc:
152
        out.print("StructureLoc");
153
        return;
150
    }
154
    }
151
    
155
    
152
    RELEASE_ASSERT_NOT_REACHED();
156
    RELEASE_ASSERT_NOT_REACHED();
- Source/JavaScriptCore/dfg/DFGHeapLocation.h +1 lines
Lines 55-60 enum LocationKind { Source/JavaScriptCore/dfg/DFGHeapLocation.h_sec1
55
    MyArgumentsLengthLoc,
55
    MyArgumentsLengthLoc,
56
    NamedPropertyLoc,
56
    NamedPropertyLoc,
57
    SetterLoc,
57
    SetterLoc,
58
    StructureLoc,
58
    TypeOfLoc,
59
    TypeOfLoc,
59
    TypedArrayByteOffsetLoc,
60
    TypedArrayByteOffsetLoc,
60
    VarInjectionWatchpointLoc,
61
    VarInjectionWatchpointLoc,
- Source/JavaScriptCore/dfg/DFGInsertOSRHintsForUpdate.cpp +58 lines
Line 0 Source/JavaScriptCore/dfg/DFGInsertOSRHintsForUpdate.cpp_sec1
1
/*
2
 * Copyright (C) 2014 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 "DFGInsertOSRHintsForUpdate.h"
28
29
#if ENABLE(DFG_JIT)
30
31
namespace JSC { namespace DFG {
32
33
void insertOSRHintsForUpdate(
34
    InsertionSet& insertionSet, unsigned nodeIndex, AvailabilityMap& availability,
35
    Node* originalNode, Node* newNode)
36
{
37
    for (unsigned i = availability.m_locals.size(); i--;) {
38
        int operand = availability.m_locals.operandForIndex(i);
39
        
40
        if (availability.m_locals[i].hasNode() && availability.m_locals[i].node() == originalNode) {
41
            insertionSet.insertNode(
42
                nodeIndex, SpecNone, MovHint, NodeOrigin(), OpInfo(operand),
43
                newNode->defaultEdge());
44
        }
45
    }
46
    
47
    for (auto pair : availability.m_heap) {
48
        if (pair.value.hasNode() && pair.value.node() == originalNode) {
49
            insertionSet.insert(
50
                nodeIndex, pair.key.createHint(insertionSet.graph(), NodeOrigin(), newNode));
51
        }
52
    }
53
}
54
55
} } // namespace JSC::DFG
56
57
#endif // ENABLE(DFG_JIT)
58
- Source/JavaScriptCore/dfg/DFGInsertOSRHintsForUpdate.h +45 lines
Line 0 Source/JavaScriptCore/dfg/DFGInsertOSRHintsForUpdate.h_sec1
1
/*
2
 * Copyright (C) 2014 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 DFGInsertOSRHintsForUpdate_h
27
#define DFGInsertOSRHintsForUpdate_h
28
29
#if ENABLE(DFG_JIT)
30
31
#include "DFGInsertionSet.h"
32
#include "DFGAvailabilityMap.h"
33
34
namespace JSC { namespace DFG {
35
36
void insertOSRHintsForUpdate(
37
    InsertionSet&, unsigned nodeIndex, AvailabilityMap&,
38
    Node* originalNode, Node* newNode);
39
40
} } // namespace JSC::DFG
41
42
#endif // ENABLE(DFG_JIT)
43
44
#endif // DFGInsertOSRHintsForUpdate_h
45
- Source/JavaScriptCore/dfg/DFGInsertionSet.h +2 lines
Lines 43-48 public: Source/JavaScriptCore/dfg/DFGInsertionSet.h_sec1
43
    {
43
    {
44
    }
44
    }
45
    
45
    
46
    Graph& graph() { return m_graph; }
47
    
46
    Node* insert(const Insertion& insertion)
48
    Node* insert(const Insertion& insertion)
47
    {
49
    {
48
        ASSERT(!m_insertions.size() || m_insertions.last().index() <= insertion.index());
50
        ASSERT(!m_insertions.size() || m_insertions.last().index() <= insertion.index());
- Source/JavaScriptCore/dfg/DFGMayExit.cpp +4 lines
Lines 75-80 bool mayExit(Graph& graph, Node* node) Source/JavaScriptCore/dfg/DFGMayExit.cpp_sec1
75
    case Phi:
75
    case Phi:
76
    case Upsilon:
76
    case Upsilon:
77
    case ZombieHint:
77
    case ZombieHint:
78
    case BottomValue:
79
    case PutStructureHint:
80
    case PutByOffsetHint:
81
    case PhantomNewObject:
78
        break;
82
        break;
79
        
83
        
80
    default:
84
    default:
- Source/JavaScriptCore/dfg/DFGNode.h -2 / +69 lines
Lines 38-43 Source/JavaScriptCore/dfg/DFGNode.h_sec1
38
#include "DFGNodeFlags.h"
38
#include "DFGNodeFlags.h"
39
#include "DFGNodeOrigin.h"
39
#include "DFGNodeOrigin.h"
40
#include "DFGNodeType.h"
40
#include "DFGNodeType.h"
41
#include "DFGObjectMaterializationData.h"
41
#include "DFGTransition.h"
42
#include "DFGTransition.h"
42
#include "DFGUseKind.h"
43
#include "DFGUseKind.h"
43
#include "DFGVariableAccessData.h"
44
#include "DFGVariableAccessData.h"
Lines 500-505 struct Node { Source/JavaScriptCore/dfg/DFGNode.h_sec2
500
        m_flags &= ~NodeClobbersWorld;
501
        m_flags &= ~NodeClobbersWorld;
501
    }
502
    }
502
    
503
    
504
    void convertToPutByOffsetHint()
505
    {
506
        ASSERT(m_op == PutByOffset);
507
        m_opInfo = storageAccessData().identifierNumber;
508
        m_op = PutByOffsetHint;
509
        child1() = child2();
510
        child2() = child3();
511
        child3() = Edge();
512
    }
513
    
514
    void convertToPutStructureHint(Node* structure)
515
    {
516
        ASSERT(m_op == PutStructure);
517
        ASSERT(structure->castConstant<Structure*>() == transition()->next);
518
        m_op = PutStructureHint;
519
        m_opInfo = 0;
520
        child2() = Edge(structure, KnownCellUse);
521
    }
522
    
523
    void convertToPhantomNewObject()
524
    {
525
        ASSERT(m_op == NewObject || m_op == MaterializeNewObject);
526
        m_op = PhantomNewObject;
527
        m_flags &= ~NodeHasVarArgs;
528
        m_opInfo = 0;
529
        m_opInfo2 = 0;
530
        children = AdjacencyList();
531
    }
532
    
503
    void convertToPhantomLocal()
533
    void convertToPhantomLocal()
504
    {
534
    {
505
        ASSERT(m_op == Phantom && (child1()->op() == Phi || child1()->op() == SetLocal || child1()->op() == SetArgument));
535
        ASSERT(m_op == Phantom && (child1()->op() == Phi || child1()->op() == SetLocal || child1()->op() == SetArgument));
Lines 580-586 struct Node { Source/JavaScriptCore/dfg/DFGNode.h_sec3
580
     
610
     
581
    bool isCellConstant()
611
    bool isCellConstant()
582
    {
612
    {
583
        return isConstant() && constant()->value().isCell();
613
        return isConstant() && constant()->value() && constant()->value().isCell();
584
    }
614
    }
585
     
615
     
586
    JSCell* asCell()
616
    JSCell* asCell()
Lines 595-600 struct Node { Source/JavaScriptCore/dfg/DFGNode.h_sec4
595
            return nullptr;
625
            return nullptr;
596
        return jsDynamicCast<T>(asCell());
626
        return jsDynamicCast<T>(asCell());
597
    }
627
    }
628
    
629
    template<typename T>
630
    T castConstant()
631
    {
632
        T result = dynamicCastConstant<T>();
633
        RELEASE_ASSERT(result);
634
        return result;
635
    }
598
     
636
     
599
    bool containsMovHint()
637
    bool containsMovHint()
600
    {
638
    {
Lines 704-709 struct Node { Source/JavaScriptCore/dfg/DFGNode.h_sec5
704
        case PutById:
742
        case PutById:
705
        case PutByIdFlush:
743
        case PutByIdFlush:
706
        case PutByIdDirect:
744
        case PutByIdDirect:
745
        case PutByOffsetHint:
707
            return true;
746
            return true;
708
        default:
747
        default:
709
            return false;
748
            return false;
Lines 1105-1110 struct Node { Source/JavaScriptCore/dfg/DFGNode.h_sec6
1105
    {
1144
    {
1106
        switch (op()) {
1145
        switch (op()) {
1107
        case PutStructure:
1146
        case PutStructure:
1147
        case PutStructureHint:
1108
        case AllocatePropertyStorage:
1148
        case AllocatePropertyStorage:
1109
        case ReallocatePropertyStorage:
1149
        case ReallocatePropertyStorage:
1110
            return true;
1150
            return true;
Lines 1155-1161 struct Node { Source/JavaScriptCore/dfg/DFGNode.h_sec7
1155
    
1195
    
1156
    bool hasStorageAccessData()
1196
    bool hasStorageAccessData()
1157
    {
1197
    {
1158
        return op() == GetByOffset || op() == GetGetterSetterByOffset || op() == PutByOffset;
1198
        switch (op()) {
1199
        case GetByOffset:
1200
        case PutByOffset:
1201
        case GetGetterSetterByOffset:
1202
            return true;
1203
        default:
1204
            return false;
1205
        }
1159
    }
1206
    }
1160
    
1207
    
1161
    StorageAccessData& storageAccessData()
1208
    StorageAccessData& storageAccessData()
Lines 1184-1189 struct Node { Source/JavaScriptCore/dfg/DFGNode.h_sec8
1184
        return *reinterpret_cast<MultiPutByOffsetData*>(m_opInfo);
1231
        return *reinterpret_cast<MultiPutByOffsetData*>(m_opInfo);
1185
    }
1232
    }
1186
    
1233
    
1234
    bool hasObjectMaterializationData()
1235
    {
1236
        return op() == MaterializeNewObject;
1237
    }
1238
    
1239
    ObjectMaterializationData& objectMaterializationData()
1240
    {
1241
        return *reinterpret_cast<ObjectMaterializationData*>(m_opInfo);
1242
    }
1243
    
1244
    bool isPhantomObjectAllocation()
1245
    {
1246
        switch (op()) {
1247
        case PhantomNewObject:
1248
            return true;
1249
        default:
1250
            return false;
1251
        }
1252
    }
1253
    
1187
    bool hasFunctionDeclIndex()
1254
    bool hasFunctionDeclIndex()
1188
    {
1255
    {
1189
        return op() == NewFunction
1256
        return op() == NewFunction
- Source/JavaScriptCore/dfg/DFGNodeType.h +7 lines
Lines 228-233 namespace JSC { namespace DFG { Source/JavaScriptCore/dfg/DFGNodeType.h_sec1
228
    macro(NewTypedArray, NodeResultJS | NodeClobbersWorld | NodeMustGenerate) \
228
    macro(NewTypedArray, NodeResultJS | NodeClobbersWorld | NodeMustGenerate) \
229
    macro(NewRegexp, NodeResultJS) \
229
    macro(NewRegexp, NodeResultJS) \
230
    \
230
    \
231
    /* Support for allocation sinking. */\
232
    macro(PhantomNewObject, NodeResultJS) \
233
    macro(PutByOffsetHint, NodeMustGenerate) \
234
    macro(CheckStructureImmediate, NodeMustGenerate) \
235
    macro(PutStructureHint, NodeMustGenerate) \
236
    macro(MaterializeNewObject, NodeResultJS | NodeHasVarArgs) \
237
    \
231
    /* Nodes for misc operations. */\
238
    /* Nodes for misc operations. */\
232
    macro(Breakpoint, NodeMustGenerate) \
239
    macro(Breakpoint, NodeMustGenerate) \
233
    macro(ProfileWillCall, NodeMustGenerate) \
240
    macro(ProfileWillCall, NodeMustGenerate) \
- Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp -17 / +28 lines
Lines 32-37 Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp_sec1
32
#include "DFGGraph.h"
32
#include "DFGGraph.h"
33
#include "DFGInsertionSet.h"
33
#include "DFGInsertionSet.h"
34
#include "DFGPhase.h"
34
#include "DFGPhase.h"
35
#include "DFGPromoteHeapAccess.h"
35
#include "JSCInlines.h"
36
#include "JSCInlines.h"
36
37
37
namespace JSC { namespace DFG {
38
namespace JSC { namespace DFG {
Lines 51-73 public: Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp_sec2
51
            BasicBlock* block = m_graph.block(blockIndex);
52
            BasicBlock* block = m_graph.block(blockIndex);
52
            if (!block)
53
            if (!block)
53
                continue;
54
                continue;
54
            block->ssa->availabilityAtHead.fill(Availability());
55
            block->ssa->availabilityAtHead.clear();
55
            block->ssa->availabilityAtTail.fill(Availability());
56
            block->ssa->availabilityAtTail.clear();
56
        }
57
        }
57
        
58
        
58
        BasicBlock* root = m_graph.block(0);
59
        BasicBlock* root = m_graph.block(0);
59
        for (unsigned argument = root->ssa->availabilityAtHead.numberOfArguments(); argument--;) {
60
        for (unsigned argument = root->ssa->availabilityAtHead.m_locals.numberOfArguments(); argument--;) {
60
            root->ssa->availabilityAtHead.argument(argument) =
61
            root->ssa->availabilityAtHead.m_locals.argument(argument) =
61
                Availability::unavailable().withFlush(
62
                Availability::unavailable().withFlush(
62
                    FlushedAt(FlushedJSValue, virtualRegisterForArgument(argument)));
63
                    FlushedAt(FlushedJSValue, virtualRegisterForArgument(argument)));
63
        }
64
        }
64
65
65
        if (m_graph.m_plan.mode == FTLForOSREntryMode) {
66
        if (m_graph.m_plan.mode == FTLForOSREntryMode) {
66
            for (unsigned local = m_graph.m_profiledBlock->m_numCalleeRegisters; local--;)
67
            for (unsigned local = m_graph.m_profiledBlock->m_numCalleeRegisters; local--;)
67
                root->ssa->availabilityAtHead.local(local) = Availability::unavailable();
68
                root->ssa->availabilityAtHead.m_locals.local(local) = Availability::unavailable();
68
        } else {
69
        } else {
69
            for (unsigned local = root->ssa->availabilityAtHead.numberOfLocals(); local--;)
70
            for (unsigned local = root->ssa->availabilityAtHead.m_locals.numberOfLocals(); local--;)
70
                root->ssa->availabilityAtHead.local(local) = Availability::unavailable();
71
                root->ssa->availabilityAtHead.m_locals.local(local) = Availability::unavailable();
71
        }
72
        }
72
        
73
        
73
        // This could be made more efficient by processing blocks in reverse postorder.
74
        // This could be made more efficient by processing blocks in reverse postorder.
Lines 87-92 public: Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp_sec3
87
                for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex)
88
                for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex)
88
                    calculator.executeNode(block->at(nodeIndex));
89
                    calculator.executeNode(block->at(nodeIndex));
89
                
90
                
91
                calculator.m_availability.prune();
92
                
90
                if (calculator.m_availability == block->ssa->availabilityAtTail)
93
                if (calculator.m_availability == block->ssa->availabilityAtTail)
91
                    continue;
94
                    continue;
92
                
95
                
Lines 95-105 public: Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp_sec4
95
                
98
                
96
                for (unsigned successorIndex = block->numSuccessors(); successorIndex--;) {
99
                for (unsigned successorIndex = block->numSuccessors(); successorIndex--;) {
97
                    BasicBlock* successor = block->successor(successorIndex);
100
                    BasicBlock* successor = block->successor(successorIndex);
98
                    for (unsigned i = calculator.m_availability.size(); i--;) {
101
                    successor->ssa->availabilityAtHead.merge(calculator.m_availability);
99
                        successor->ssa->availabilityAtHead[i] =
100
                            calculator.m_availability[i].merge(
101
                                successor->ssa->availabilityAtHead[i]);
102
                    }
103
                }
102
                }
104
            }
103
            }
105
        } while (changed);
104
        } while (changed);
Lines 127-164 void LocalOSRAvailabilityCalculator::beg Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp_sec5
127
    m_availability = block->ssa->availabilityAtHead;
126
    m_availability = block->ssa->availabilityAtHead;
128
}
127
}
129
128
129
void LocalOSRAvailabilityCalculator::endBlock(BasicBlock* block)
130
{
131
    m_availability = block->ssa->availabilityAtTail;
132
}
133
130
void LocalOSRAvailabilityCalculator::executeNode(Node* node)
134
void LocalOSRAvailabilityCalculator::executeNode(Node* node)
131
{
135
{
132
    switch (node->op()) {
136
    switch (node->op()) {
133
    case SetLocal: {
137
    case SetLocal: {
134
        VariableAccessData* variable = node->variableAccessData();
138
        VariableAccessData* variable = node->variableAccessData();
135
        m_availability.operand(variable->local()) =
139
        m_availability.m_locals.operand(variable->local()) =
136
            Availability(node->child1().node(), variable->flushedAt());
140
            Availability(node->child1().node(), variable->flushedAt());
137
        break;
141
        break;
138
    }
142
    }
139
143
140
    case GetArgument: {
144
    case GetArgument: {
141
        VariableAccessData* variable = node->variableAccessData();
145
        VariableAccessData* variable = node->variableAccessData();
142
        m_availability.operand(variable->local()) =
146
        m_availability.m_locals.operand(variable->local()) =
143
            Availability(node, variable->flushedAt());
147
            Availability(node, variable->flushedAt());
144
        break;
148
        break;
145
    }
149
    }
146
150
147
    case MovHint: {
151
    case MovHint: {
148
        m_availability.operand(node->unlinkedLocal()) =
152
        m_availability.m_locals.operand(node->unlinkedLocal()) =
149
            Availability(node->child1().node());
153
            Availability(node->child1().node());
150
        break;
154
        break;
151
    }
155
    }
152
156
153
    case ZombieHint: {
157
    case ZombieHint: {
154
        m_availability.operand(node->unlinkedLocal()) =
158
        m_availability.m_locals.operand(node->unlinkedLocal()) =
155
            Availability::unavailable();
159
            Availability::unavailable();
156
        break;
160
        break;
157
    }
161
    }
158
162
        
159
    default:
163
    default:
160
        break;
164
        break;
161
    }
165
    }
166
    
167
    promoteHeapAccess(
168
        node,
169
        [&] (PromotedHeapLocation location, Edge value) {
170
            m_availability.m_heap.set(location, Availability(value.node()));
171
        },
172
        [&] (PromotedHeapLocation) { });
162
}
173
}
163
174
164
} } // namespace JSC::DFG
175
} } // namespace JSC::DFG
- Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.h -2 / +5 lines
Lines 37-43 class Graph; Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.h_sec1
37
37
38
// Computes BasicBlock::ssa->availabiltiyAtHead/Tail. This is a forward flow type inference
38
// Computes BasicBlock::ssa->availabiltiyAtHead/Tail. This is a forward flow type inference
39
// over MovHints and SetLocals. This analysis is run directly by the Plan for preparing for
39
// over MovHints and SetLocals. This analysis is run directly by the Plan for preparing for
40
// lowering to LLVM IR, but it can also be used as a utility.
40
// lowering to LLVM IR, but it can also be used as a utility. Note that if you run it before
41
// stack layout, all of the flush availability will omit the virtual register - but it will
42
// tell you the format.
41
43
42
bool performOSRAvailabilityAnalysis(Graph&);
44
bool performOSRAvailabilityAnalysis(Graph&);
43
45
Lines 49-57 public: Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.h_sec2
49
    ~LocalOSRAvailabilityCalculator();
51
    ~LocalOSRAvailabilityCalculator();
50
    
52
    
51
    void beginBlock(BasicBlock*);
53
    void beginBlock(BasicBlock*);
54
    void endBlock(BasicBlock*); // Useful if you want to get data for the end of the block. You don't need to call this if you did beginBlock() and then executeNode() for every node.
52
    void executeNode(Node*);
55
    void executeNode(Node*);
53
    
56
    
54
    Operands<Availability> m_availability;
57
    AvailabilityMap m_availability;
55
};
58
};
56
59
57
} } // namespace JSC::DFG
60
} } // namespace JSC::DFG
- Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp +775 lines
Line 0 Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp_sec1
1
/*
2
 * Copyright (C) 2014 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 "DFGObjectAllocationSinkingPhase.h"
28
29
#if ENABLE(DFG_JIT)
30
31
#include "DFGAbstractHeap.h"
32
#include "DFGBlockMapInlines.h"
33
#include "DFGClobberize.h"
34
#include "DFGGraph.h"
35
#include "DFGInsertOSRHintsForUpdate.h"
36
#include "DFGInsertionSet.h"
37
#include "DFGLivenessAnalysisPhase.h"
38
#include "DFGOSRAvailabilityAnalysisPhase.h"
39
#include "DFGPhase.h"
40
#include "DFGPromoteHeapAccess.h"
41
#include "DFGSSACalculator.h"
42
#include "DFGValidate.h"
43
#include "JSCInlines.h"
44
45
namespace JSC { namespace DFG {
46
47
static bool verbose = true;
48
49
class ObjectAllocationSinkingPhase : public Phase {
50
public:
51
    ObjectAllocationSinkingPhase(Graph& graph)
52
        : Phase(graph, "object allocation sinking")
53
        , m_ssaCalculator(graph)
54
        , m_insertionSet(graph)
55
    {
56
    }
57
    
58
    bool run()
59
    {
60
        ASSERT(m_graph.m_fixpointState == FixpointNotConverged);
61
        
62
        // Logically we wish to consider every NewObject and sink it. However it's definitely not
63
        // profitable to sink a NewObject that will always escape. So, first we do a very simple
64
        // forward flow analysis that determines the set of NewObject nodes that have any chance
65
        // of benefiting from object allocation sinking. Then we fixpoint the following rules:
66
        //
67
        // - For each NewObject, we turn the original NewObject into a PhantomNewObject and then
68
        //   we insert MaterializeNewObject just before each escaping site. Note that Upsilons
69
        //   constitute escaping sites. Then we use forward flow to eliminate unnecessary cases of
70
        //   MaterializeNewObject. We use the SSACalculator to insert these materializations. If a
71
        //   Phi is ever created that has the PhantomNewObject as one of its kids, then we insert
72
        //   a MaterializeNewObject in front of it; this way we never have a Phi that is confused
73
        //   about whether or not it has the real object. We then turn each PutByOffset over a
74
        //   PhantomNewObject into a PutByOffsetHint.
75
        //
76
        // - We perform the same optimization for MaterializeNewObject. This allows us to cover
77
        //   cases where we had MaterializeNewObject flowing into a PutByOffsetHint.
78
        //
79
        // We could also add this rule:
80
        //
81
        // - If all of the Upsilons of a Phi have a MaterializeNewObject that isn't used by anyone
82
        //   else, then replace the Phi with the MaterializeNewObject.
83
        //
84
        //   FIXME: Implement this. Note that this totally doable but it requires some gnarly
85
        //   code, and to be effective the pruner needs to be aware of it. Currently any Upsilon
86
        //   is considered to be an escape even by the pruner, so it's unlikely that we'll see
87
        //   many cases of Phi over Materializations.
88
        //   https://bugs.webkit.org/show_bug.cgi?id=136927
89
        
90
        if (!performSinking())
91
            return false;
92
        
93
        while (performSinking()) { }
94
        
95
        return true;
96
    }
97
98
private:
99
    bool performSinking()
100
    {
101
        m_graph.computeRefCounts();
102
        performLivenessAnalysis(m_graph);
103
        performOSRAvailabilityAnalysis(m_graph);
104
        
105
        CString graphBeforeSinking;
106
        if (Options::verboseValidationFailure() && Options::validateGraphAtEachPhase()) {
107
            StringPrintStream out;
108
            m_graph.dump(out);
109
            graphBeforeSinking = out.toCString();
110
        }
111
        
112
        if (verbose) {
113
            dataLog("Graph before sinking:\n");
114
            m_graph.dump();
115
        }
116
        
117
        // We want to only do sinking for those things that would benefit. We use a rough
118
        // heuristic: if it's possible for an allocation to make it to a return without escaping,
119
        // then we assume that it's worth sinking. It's a simple forward flow problem.
120
        //
121
        // It just so happens that this forward flow problem also tells us where we would
122
        // materialize those nodes that we choose to sink.
123
        pruneSinkingCandidates();
124
        if (m_sinkCandidates.isEmpty())
125
            return false;
126
        
127
        // At this point we are committed to sinking the sinking candidates.
128
        determineMaterializationPoints();
129
        placeMaterializationPoints();
130
        lowerNonReadingOperationsOnPhantomAllocations();
131
        promoteSunkenFields();
132
        
133
        if (Options::validateGraphAtEachPhase())
134
            validate(m_graph, DumpGraph, graphBeforeSinking);
135
        
136
        dataLog("Sinking iteration changed the graph.\n");
137
        return true;
138
    }
139
    
140
    void pruneSinkingCandidates()
141
    {
142
        m_sinkCandidates.clear();
143
        BlockMap<HashSet<Node*>> sinkCandidatesAtHead(m_graph);
144
        BlockMap<HashSet<Node*>> sinkCandidatesAtTail(m_graph);
145
        
146
        bool changed;
147
        do {
148
            changed = false;
149
            for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
150
                HashSet<Node*> sinkCandidates = sinkCandidatesAtHead[block];
151
                for (Node* node : *block) {
152
                    handleNode(
153
                        node,
154
                        [&] () {
155
                            if (verbose)
156
                                dataLog("At ", node, ": it's a sink candidate!\n");
157
                            sinkCandidates.add(node);
158
                        },
159
                        [&] (Node* escapee) {
160
                            if (verbose)
161
                                dataLog("At ", node, ": noticing escape of ", escapee, "\n");
162
                            sinkCandidates.remove(escapee);
163
                        });
164
                }
165
                if (sinkCandidatesAtTail[block] == sinkCandidates)
166
                    continue;
167
                
168
                sinkCandidatesAtTail[block] = sinkCandidates;
169
                changed = true;
170
                
171
                for (BasicBlock* successorBlock : block->successors()) {
172
                    for (Node* sinkCandidate : sinkCandidates) {
173
                        if (!successorBlock->ssa->liveAtHead.contains(sinkCandidate))
174
                            continue;
175
                        sinkCandidatesAtHead[successorBlock].add(sinkCandidate);
176
                    }
177
                }
178
            }
179
        } while (changed);
180
        
181
        // A node is a sink candidate if it is in the sinkCandidatesAtTail of a block but not in
182
        // the liveAtTail of that same block.
183
        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
184
            if (verbose)
185
                dataLog("Sink candidates at tail of ", pointerDump(block), ": ", listDump(sinkCandidatesAtTail[block]), "\n");
186
            for (Node* sinkCandidate : sinkCandidatesAtTail[block]) {
187
                if (!block->ssa->liveAtTail.contains(sinkCandidate))
188
                    m_sinkCandidates.add(sinkCandidate);
189
            }
190
        }
191
    }
192
    
193
    void determineMaterializationPoints()
194
    {
195
        // The premise of this pass is that if there exists a point in the program where some
196
        // path from a phantom allocation site to that point causes materialization, then *all*
197
        // paths cause materialization. This should mean that there are never any redundant
198
        // materializations.
199
        
200
        m_edgeToMaterializationPoint.clear();
201
        
202
        BlockMap<HashSet<Node*>> materializedAtHead(m_graph);
203
        BlockMap<HashSet<Node*>> materializedAtTail(m_graph);
204
        
205
        bool changed;
206
        do {
207
            changed = false;
208
            for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
209
                HashSet<Node*> materialized = materializedAtHead[block];
210
                for (Node* node : *block) {
211
                    handleNode(
212
                        node,
213
                        [&] () { },
214
                        [&] (Node* escapee) {
215
                            if (m_sinkCandidates.contains(escapee))
216
                                materialized.add(escapee);
217
                        });
218
                }
219
                
220
                if (materialized == materializedAtTail[block])
221
                    continue;
222
                
223
                changed = true;
224
                
225
                for (BasicBlock* successorBlock : block->successors()) {
226
                    for (Node* materializee : materialized) {
227
                        if (!successorBlock->ssa->liveAtHead.contains(materializee))
228
                            continue;
229
                        materializedAtHead[successorBlock].add(materializee);
230
                    }
231
                }
232
            }
233
        } while (changed);
234
        
235
        // A materialization edge exists at any point where a node escapes but hasn't been
236
        // materialized yet.
237
        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
238
            HashSet<Node*> materialized = materializedAtHead[block];
239
            for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
240
                Node* node = block->at(nodeIndex);
241
                
242
                handleNode(
243
                    node,
244
                    [&] () { },
245
                    [&] (Node* escapee) {
246
                        if (!m_sinkCandidates.contains(escapee))
247
                            return;
248
                        
249
                        if (!materialized.add(escapee).isNewEntry)
250
                            return;
251
                        
252
                        m_edgeToMaterializationPoint.add(
253
                            std::make_pair(node, escapee),
254
                            createMaterialize(escapee, node->origin));
255
                    });
256
            }
257
        }
258
    }
259
    
260
    void placeMaterializationPoints()
261
    {
262
        m_ssaCalculator.reset();
263
        
264
        HashMap<Node*, SSACalculator::Variable*> nodeToVariable;
265
        Vector<Node*> indexToNode;
266
        
267
        for (Node* node : m_sinkCandidates) {
268
            SSACalculator::Variable* variable = m_ssaCalculator.newVariable();
269
            nodeToVariable.add(node, variable);
270
            ASSERT(indexToNode.size() == variable->index());
271
            indexToNode.append(node);
272
        }
273
        
274
        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
275
            for (Node* node : *block) {
276
                if (SSACalculator::Variable* variable = nodeToVariable.get(node))
277
                    m_ssaCalculator.newDef(variable, block, node);
278
                
279
                m_graph.doToChildren(
280
                    node,
281
                    [&] (Edge edge) {
282
                        Node* materialize =
283
                            m_edgeToMaterializationPoint.get(std::make_pair(node, edge.node()));
284
                        if (!materialize)
285
                            return;
286
                        
287
                        m_ssaCalculator.newDef(
288
                            nodeToVariable.get(edge.node()), block, materialize);
289
                    });
290
            }
291
        }
292
        
293
        m_ssaCalculator.computePhis(
294
            [&] (SSACalculator::Variable* variable, BasicBlock* block) -> Node* {
295
                Node* allocation = indexToNode[variable->index()];
296
                if (!block->ssa->liveAtHead.contains(allocation))
297
                    return nullptr;
298
                
299
                Node* phiNode = m_graph.addNode(allocation->prediction(), Phi, NodeOrigin());
300
                phiNode->mergeFlags(NodeResultJS);
301
                return phiNode;
302
            });
303
        
304
        // Place Phis in the right places. Replace all uses of any allocation with the appropriate
305
        // materialization. Create the appropriate Upsilon nodes.
306
        LocalOSRAvailabilityCalculator availabilityCalculator;
307
        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
308
            HashMap<Node*, Node*> mapping;
309
            
310
            for (Node* candidate : block->ssa->liveAtHead) {
311
                SSACalculator::Variable* variable = nodeToVariable.get(candidate);
312
                if (!variable)
313
                    continue;
314
                
315
                SSACalculator::Def* def = m_ssaCalculator.reachingDefAtHead(block, variable);
316
                if (!def)
317
                    continue;
318
                
319
                mapping.add(indexToNode[variable->index()], def->value());
320
            }
321
            
322
            availabilityCalculator.beginBlock(block);
323
            for (SSACalculator::Def* phiDef : m_ssaCalculator.phisForBlock(block)) {
324
                m_insertionSet.insert(0, phiDef->value());
325
                
326
                Node* originalNode = indexToNode[phiDef->variable()->index()];
327
                insertOSRHintsForUpdate(
328
                    m_insertionSet, 0, availabilityCalculator.m_availability, originalNode,
329
                    phiDef->value());
330
331
                mapping.add(originalNode, phiDef->value());
332
            }
333
            
334
            for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
335
                Node* node = block->at(nodeIndex);
336
337
                m_graph.doToChildren(
338
                    node,
339
                    [&] (Edge edge) {
340
                        Node* materialize = m_edgeToMaterializationPoint.get(
341
                            std::make_pair(node, edge.node()));
342
                        if (materialize) {
343
                            m_insertionSet.insert(nodeIndex, materialize);
344
                            insertOSRHintsForUpdate(
345
                                m_insertionSet, nodeIndex, availabilityCalculator.m_availability,
346
                                edge.node(), materialize);
347
                        }
348
                    });
349
350
                availabilityCalculator.executeNode(node);
351
                
352
                m_graph.doToChildren(
353
                    node,
354
                    [&] (Edge& edge) {
355
                        if (Node* materialize = mapping.get(edge.node()))
356
                            edge.setNode(materialize);
357
                    });
358
            }
359
            
360
            size_t upsilonInsertionPoint = block->size() - 1;
361
            NodeOrigin upsilonOrigin = block->last()->origin;
362
            for (BasicBlock* successorBlock : block->successors()) {
363
                for (SSACalculator::Def* phiDef : m_ssaCalculator.phisForBlock(successorBlock)) {
364
                    Node* phiNode = phiDef->value();
365
                    SSACalculator::Variable* variable = phiDef->variable();
366
                    Node* allocation = indexToNode[variable->index()];
367
                    
368
                    Node* originalIncoming = mapping.get(allocation);
369
                    Node* incoming;
370
                    if (originalIncoming == allocation) {
371
                        // If we have a Phi that combines materializations with the original
372
                        // phantom object, then the path with the phantom object must materialize.
373
                        
374
                        incoming = createMaterialize(allocation, upsilonOrigin);
375
                        m_insertionSet.insert(upsilonInsertionPoint, incoming);
376
                        insertOSRHintsForUpdate(
377
                            m_insertionSet, upsilonInsertionPoint,
378
                            availabilityCalculator.m_availability, originalIncoming, incoming);
379
                    } else
380
                        incoming = originalIncoming;
381
                    
382
                    Node* upsilon = m_insertionSet.insertNode(
383
                        upsilonInsertionPoint, SpecNone, Upsilon, upsilonOrigin,
384
                        OpInfo(phiNode), incoming->defaultEdge());
385
                    
386
                    if (originalIncoming == allocation) {
387
                        m_edgeToMaterializationPoint.add(
388
                            std::make_pair(upsilon, allocation), incoming);
389
                    }
390
                }
391
            }
392
            
393
            m_insertionSet.execute(block);
394
        }
395
        
396
        // At this point we have dummy materialization nodes along with edges to them. This means
397
        // that the part of the control flow graph that prefers to see actual object allocations
398
        // is completely fixed up, except for the materializations themselves.
399
    }
400
    
401
    void lowerNonReadingOperationsOnPhantomAllocations()
402
    {
403
        // Lower everything but reading operations on phantom allocations. We absolutely have to
404
        // lower all writes so as to reveal them to the SSA calculator. We cannot lower reads
405
        // because the whole point is that those go away completely.
406
        
407
        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
408
            for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
409
                Node* node = block->at(nodeIndex);
410
                switch (node->op()) {
411
                case PutByOffset: {
412
                    if (m_sinkCandidates.contains(node->child2().node()))
413
                        node->convertToPutByOffsetHint();
414
                    break;
415
                }
416
                    
417
                case PutStructure: {
418
                    if (m_sinkCandidates.contains(node->child1().node())) {
419
                        Node* structure = m_insertionSet.insertConstant(
420
                            nodeIndex, node->origin, JSValue(node->transition()->next));
421
                        node->convertToPutStructureHint(structure);
422
                    }
423
                    break;
424
                }
425
                    
426
                case NewObject: {
427
                    if (m_sinkCandidates.contains(node)) {
428
                        Node* structure = m_insertionSet.insertConstant(
429
                            nodeIndex + 1, node->origin, JSValue(node->structure()));
430
                        m_insertionSet.insertNode(
431
                            nodeIndex + 1, SpecNone, PutStructureHint, node->origin,
432
                            Edge(node, KnownCellUse), Edge(structure, KnownCellUse));
433
                        node->convertToPhantomNewObject();
434
                    }
435
                    break;
436
                }
437
                    
438
                case MaterializeNewObject: {
439
                    if (m_sinkCandidates.contains(node)) {
440
                        m_insertionSet.insertNode(
441
                            nodeIndex + 1, SpecNone, PutStructureHint, node->origin,
442
                            Edge(node, KnownCellUse), m_graph.varArgChild(node, 0));
443
                        for (unsigned i = 0; i < node->objectMaterializationData().m_properties.size(); ++i) {
444
                            m_insertionSet.insertNode(
445
                                nodeIndex + 1, SpecNone, PutByOffsetHint, node->origin,
446
                                Edge(node, KnownCellUse),m_graph.varArgChild(node, i + 1));
447
                        }
448
                        node->convertToPhantomNewObject();
449
                    }
450
                    break;
451
                }
452
                    
453
                case StoreBarrier:
454
                case StoreBarrierWithNullCheck: {
455
                    if (m_sinkCandidates.contains(node->child1().node()))
456
                        node->convertToPhantom();
457
                    break;
458
                }
459
                    
460
                default:
461
                    break;
462
                }
463
                
464
                m_graph.doToChildren(
465
                    node,
466
                    [&] (Edge& edge) {
467
                        if (m_sinkCandidates.contains(edge.node()))
468
                            edge.setUseKind(KnownCellUse);
469
                    });
470
            }
471
            m_insertionSet.execute(block);
472
        }
473
    }
474
    
475
    void promoteSunkenFields()
476
    {
477
        // Henceforth when we encounter a materialization point, we will want to ask *who* it is
478
        // a materialization for. Invert the map to be able to answer such questions.
479
        m_materializationPointToEscapee.clear();
480
        for (auto pair : m_edgeToMaterializationPoint)
481
            m_materializationPointToEscapee.add(pair.value, pair.key.second);
482
        
483
        // Collect the set of heap locations that we will be operating over.
484
        HashSet<PromotedHeapLocation> locations;
485
        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
486
            for (Node* node : *block) {
487
                promoteHeapAccess(
488
                    node,
489
                    [&] (PromotedHeapLocation location, Edge) {
490
                        locations.add(location);
491
                    },
492
                    [&] (PromotedHeapLocation location) {
493
                        locations.add(location);
494
                    });
495
            }
496
        }
497
        
498
        // Figure out which locations belong to which allocations.
499
        m_locationsForAllocation.clear();
500
        for (PromotedHeapLocation location : locations) {
501
            auto result = m_locationsForAllocation.add(location.base(), Vector<PromotedHeapLocation>());
502
            ASSERT(!result.iterator->value.contains(location));
503
            result.iterator->value.append(location);
504
        }
505
        
506
        // For each sunken thingy, make sure we create Bottom values for all of its fields.
507
        // Note that this has the hilarious slight inefficiency of creating redundant hints for
508
        // things that were previously materializations. This should only impact compile times and
509
        // not code quality, and it's necessary for soundness without some data structure hackage.
510
        // For example, a MaterializeNewObject that we choose to sink may have new fields added to
511
        // it conditionally. That would necessitate Bottoms.
512
        Node* bottom = nullptr;
513
        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
514
            if (block == m_graph.block(0))
515
                bottom = m_insertionSet.insertNode(0, SpecNone, BottomValue, NodeOrigin());
516
            
517
            for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
518
                Node* node = block->at(nodeIndex);
519
                for (PromotedHeapLocation location : m_locationsForAllocation.get(node)) {
520
                    m_insertionSet.insert(
521
                        nodeIndex + 1, location.createHint(m_graph, node->origin, bottom));
522
                }
523
            }
524
            m_insertionSet.execute(block);
525
        }
526
527
        m_ssaCalculator.reset();
528
529
        // Collect the set of "variables" that we will be sinking.
530
        m_locationToVariable.clear();
531
        m_indexToLocation.clear();
532
        for (PromotedHeapLocation location : locations) {
533
            SSACalculator::Variable* variable = m_ssaCalculator.newVariable();
534
            m_locationToVariable.add(location, variable);
535
            ASSERT(m_indexToLocation.size() == variable->index());
536
            m_indexToLocation.append(location);
537
        }
538
        
539
        // Create Defs from the existing hints.
540
        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
541
            for (Node* node : *block) {
542
                promoteHeapAccess(
543
                    node,
544
                    [&] (PromotedHeapLocation location, Edge value) {
545
                        SSACalculator::Variable* variable = m_locationToVariable.get(location);
546
                        m_ssaCalculator.newDef(variable, block, value.node());
547
                    },
548
                    [&] (PromotedHeapLocation) { });
549
            }
550
        }
551
        
552
        // OMG run the SSA calculator to create Phis!
553
        m_ssaCalculator.computePhis(
554
            [&] (SSACalculator::Variable* variable, BasicBlock* block) -> Node* {
555
                PromotedHeapLocation location = m_indexToLocation[variable->index()];
556
                if (!block->ssa->liveAtHead.contains(location.base()))
557
                    return nullptr;
558
                
559
                Node* phiNode = m_graph.addNode(SpecHeapTop, Phi, NodeOrigin());
560
                phiNode->mergeFlags(NodeResultJS);
561
                return phiNode;
562
            });
563
        
564
        // Place Phis in the right places, replace all uses of any load with the appropriate
565
        // value, and create the appropriate Upsilon nodes.
566
        m_graph.clearReplacements();
567
        for (BasicBlock* block : m_graph.blocksInPreOrder()) {
568
            // This mapping table is intended to be lazy. If something is omitted from the table,
569
            // it means that there haven't been any local stores to that promoted heap location.
570
            m_localMapping.clear();
571
            
572
            // Insert the Phi functions that we had previously created.
573
            for (SSACalculator::Def* phiDef : m_ssaCalculator.phisForBlock(block)) {
574
                PromotedHeapLocation location = m_indexToLocation[phiDef->variable()->index()];
575
                
576
                m_insertionSet.insert(
577
                    0, phiDef->value());
578
                m_insertionSet.insert(
579
                    0, location.createHint(m_graph, NodeOrigin(), phiDef->value()));
580
                m_localMapping.add(location, phiDef->value());
581
            }
582
            
583
            // Process the block and replace all uses of loads with the promoted value.
584
            for (Node* node : *block) {
585
                m_graph.performSubstitution(node);
586
                
587
                if (Node* escapee = m_materializationPointToEscapee.get(node))
588
                    populateMaterialize(block, node, escapee);
589
                
590
                promoteHeapAccess(
591
                    node,
592
                    [&] (PromotedHeapLocation location, Edge value) {
593
                        m_localMapping.set(location, value.node());
594
                    },
595
                    [&] (PromotedHeapLocation location) {
596
                        node->replaceWith(resolve(block, location));
597
                    });
598
            }
599
            
600
            // Gotta drop some Upsilons.
601
            size_t upsilonInsertionPoint = block->size() - 1;
602
            NodeOrigin upsilonOrigin = block->last()->origin;
603
            for (BasicBlock* successorBlock : block->successors()) {
604
                for (SSACalculator::Def* phiDef : m_ssaCalculator.phisForBlock(successorBlock)) {
605
                    Node* phiNode = phiDef->value();
606
                    SSACalculator::Variable* variable = phiDef->variable();
607
                    PromotedHeapLocation location = m_indexToLocation[variable->index()];
608
                    Node* incoming = resolve(block, location);
609
                    
610
                    m_insertionSet.insertNode(
611
                        upsilonInsertionPoint, SpecNone, Upsilon, upsilonOrigin,
612
                        OpInfo(phiNode), incoming->defaultEdge());
613
                }
614
            }
615
            
616
            m_insertionSet.execute(block);
617
        }
618
    }
619
    
620
    Node* resolve(BasicBlock* block, PromotedHeapLocation location)
621
    {
622
        if (Node* result = m_localMapping.get(location))
623
            return result;
624
        
625
        // This implies that there is no local mapping. Find a non-local mapping.
626
        SSACalculator::Def* def = m_ssaCalculator.nonLocalReachingDef(
627
            block, m_locationToVariable.get(location));
628
        ASSERT(def);
629
        ASSERT(def->value());
630
        m_localMapping.add(location, def->value());
631
        return def->value();
632
    }
633
634
    template<typename SinkCandidateFunctor, typename EscapeFunctor>
635
    void handleNode(
636
        Node* node,
637
        const SinkCandidateFunctor& sinkCandidate,
638
        const EscapeFunctor& escape)
639
    {
640
        switch (node->op()) {
641
        case NewObject:
642
        case MaterializeNewObject:
643
            sinkCandidate();
644
            break;
645
            
646
        case CheckStructure:
647
        case GetByOffset:
648
        case MultiGetByOffset:
649
        case PutStructure:
650
        case GetGetterSetterByOffset:
651
        case MovHint:
652
        case Phantom:
653
        case Check:
654
        case HardPhantom:
655
        case StoreBarrier:
656
        case StoreBarrierWithNullCheck:
657
            break;
658
            
659
        case PutByOffset:
660
            escape(node->child3().node());
661
            break;
662
            
663
        case MultiPutByOffset:
664
            // FIXME: In the future we should be able to handle this. It's just a matter of
665
            // building the appropriate *Hint variant of this instruction, along with a
666
            // PhantomStructureSelect node - since this transforms the Structure in a conditional
667
            // way.
668
            // https://bugs.webkit.org/show_bug.cgi?id=136924
669
            escape(node->child1().node());
670
            escape(node->child2().node());
671
            break;
672
673
        default:
674
            m_graph.doToChildren(
675
                node,
676
                [&escape] (Edge edge) {
677
                    escape(edge.node());
678
                });
679
            break;
680
        }
681
    }
682
    
683
    Node* createMaterialize(Node* escapee, const NodeOrigin whereOrigin)
684
    {
685
        switch (escapee->op()) {
686
        case NewObject:
687
        case MaterializeNewObject: {
688
            ObjectMaterializationData* data = m_graph.m_objectMaterializationData.add();
689
            
690
            Node* result = m_graph.addNode(
691
                escapee->prediction(), Node::VarArg, MaterializeNewObject,
692
                NodeOrigin(
693
                    escapee->origin.semantic,
694
                    whereOrigin.forExit),
695
                OpInfo(data), OpInfo(), 0, 0);
696
            return result;
697
        }
698
            
699
        default:
700
            DFG_CRASH(m_graph, escapee, "Bad escapee op");
701
            return nullptr;
702
        }
703
    }
704
    
705
    void populateMaterialize(BasicBlock* block, Node* node, Node* escapee)
706
    {
707
        switch (node->op()) {
708
        case MaterializeNewObject: {
709
            ObjectMaterializationData& data = node->objectMaterializationData();
710
            unsigned firstChild = m_graph.m_varArgChildren.size();
711
            
712
            Vector<PromotedHeapLocation> locations = m_locationsForAllocation.get(escapee);
713
            
714
            PromotedHeapLocation structure(StructurePLoc, escapee);
715
            ASSERT(locations.contains(structure));
716
            
717
            m_graph.m_varArgChildren.append(resolve(block, structure));
718
            
719
            for (unsigned i = 0; i < locations.size(); ++i) {
720
                switch (locations[i].kind()) {
721
                case StructurePLoc: {
722
                    ASSERT(locations[i] == structure);
723
                    break;
724
                }
725
                    
726
                case NamedPropertyPLoc: {
727
                    Node* value = resolve(block, locations[i]);
728
                    if (value->op() == BottomValue) {
729
                        // We can skip Bottoms entirely.
730
                        break;
731
                    }
732
                    
733
                    data.m_properties.append(PhantomPropertyValue(locations[i].info()));
734
                    m_graph.m_varArgChildren.append(value);
735
                    break;
736
                }
737
                    
738
                default:
739
                    DFG_CRASH(m_graph, node, "Bad location kind");
740
                }
741
            }
742
            
743
            node->children = AdjacencyList(
744
                AdjacencyList::Variable,
745
                firstChild, m_graph.m_varArgChildren.size() - firstChild);
746
            break;
747
        }
748
            
749
        default:
750
            DFG_CRASH(m_graph, node, "Bad materialize op");
751
            break;
752
        }
753
    }
754
    
755
    SSACalculator m_ssaCalculator;
756
    HashSet<Node*> m_sinkCandidates;
757
    HashMap<std::pair<Node*, Node*>, Node*> m_edgeToMaterializationPoint;
758
    HashMap<Node*, Node*> m_materializationPointToEscapee;
759
    HashMap<Node*, Vector<PromotedHeapLocation>> m_locationsForAllocation;
760
    HashMap<PromotedHeapLocation, SSACalculator::Variable*> m_locationToVariable;
761
    Vector<PromotedHeapLocation> m_indexToLocation;
762
    HashMap<PromotedHeapLocation, Node*> m_localMapping;
763
    InsertionSet m_insertionSet;
764
};
765
    
766
bool performObjectAllocationSinking(Graph& graph)
767
{
768
    SamplingRegion samplingRegion("DFG Object Allocation Sinking Phase");
769
    return runPhase<ObjectAllocationSinkingPhase>(graph);
770
}
771
772
} } // namespace JSC::DFG
773
774
#endif // ENABLE(DFG_JIT)
775
- Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.h +47 lines
Line 0 Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.h_sec1
1
/*
2
 * Copyright (C) 2014 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 DFGObjectAllocationSinkingPhase_h
27
#define DFGObjectAllocationSinkingPhase_h
28
29
#if ENABLE(DFG_JIT)
30
31
namespace JSC { namespace DFG {
32
33
class Graph;
34
35
// Sinks object allocations down to their uses. This will sink the allocations over OSR exits, by
36
// replacing all stores to those objects with store hints so that OSR exit can materialize the
37
// object. This may sink allocations past returns, creating control flow paths along which the
38
// objects are not allocated at all. Replaces all uses of the objects' fields with SSA data flow.
39
40
bool performObjectAllocationSinking(Graph&);
41
42
} } // namespace JSC::DFG
43
44
#endif // ENABLE(DFG_JIT)
45
46
#endif // DFGObjectAllocationSinkingPhase_h
47
- Source/JavaScriptCore/dfg/DFGObjectMaterializationData.cpp +63 lines
Line 0 Source/JavaScriptCore/dfg/DFGObjectMaterializationData.cpp_sec1
1
/*
2
 * Copyright (C) 2014 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 "DFGObjectMaterializationData.h"
28
29
#if ENABLE(DFG_JIT)
30
31
#include <wtf/ListDump.h>
32
33
namespace JSC { namespace DFG {
34
35
void PhantomPropertyValue::dump(PrintStream& out) const
36
{
37
    out.print("id", m_identifierNumber);
38
}
39
40
void ObjectMaterializationData::dump(PrintStream& out) const
41
{
42
    out.print("[", listDump(m_properties), "]");
43
}
44
45
float ObjectMaterializationData::oneWaySimilarityScore(
46
    const ObjectMaterializationData& other) const
47
{
48
    unsigned numHits = 0;
49
    for (PhantomPropertyValue value : m_properties) {
50
        if (other.m_properties.contains(value))
51
            numHits++;
52
    }
53
    return static_cast<float>(numHits) / static_cast<float>(m_properties.size());
54
}
55
56
float ObjectMaterializationData::similarityScore(const ObjectMaterializationData& other) const
57
{
58
    return std::min(oneWaySimilarityScore(other), other.oneWaySimilarityScore(*this));
59
}
60
61
} } // namespace JSC::DFG
62
63
#endif // ENABLE(DFG_JIT)
- Source/JavaScriptCore/dfg/DFGObjectMaterializationData.h +75 lines
Line 0 Source/JavaScriptCore/dfg/DFGObjectMaterializationData.h_sec1
1
/*
2
 * Copyright (C) 2014 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 DFGObjectMaterializationData_h
27
#define DFGObjectMaterializationData_h
28
29
#if ENABLE(DFG_JIT)
30
31
#include <wtf/PrintStream.h>
32
#include <wtf/Vector.h>
33
34
namespace JSC { namespace DFG {
35
36
struct PhantomPropertyValue {
37
    PhantomPropertyValue()
38
        : m_identifierNumber(UINT_MAX)
39
    {
40
    }
41
    
42
    PhantomPropertyValue(unsigned identifierNumber)
43
        : m_identifierNumber(identifierNumber)
44
    {
45
    }
46
    
47
    unsigned m_identifierNumber;
48
    
49
    bool operator==(const PhantomPropertyValue& other) const
50
    {
51
        return m_identifierNumber == other.m_identifierNumber;
52
    }
53
    
54
    void dump(PrintStream&) const;
55
};
56
57
struct ObjectMaterializationData {
58
    // Determines the meaning of the passed nodes.
59
    Vector<PhantomPropertyValue> m_properties;
60
    
61
    void dump(PrintStream&) const;
62
    
63
    // The fraction of my properties that the other data has.
64
    float oneWaySimilarityScore(const ObjectMaterializationData&) const;
65
    
66
    // The minimum of the two possible one-way scores.
67
    float similarityScore(const ObjectMaterializationData&) const;
68
};
69
70
} } // namespace JSC::DFG
71
72
#endif // ENABLE(DFG_JIT)
73
74
#endif // DFGObjectMaterializationData_h
75
- Source/JavaScriptCore/dfg/DFGPhantomCanonicalizationPhase.cpp -12 / +1 lines
Lines 52-69 public: Source/JavaScriptCore/dfg/DFGPhantomCanonicalizationPhase.cpp_sec1
52
        ASSERT(m_graph.m_form == SSA);
52
        ASSERT(m_graph.m_form == SSA);
53
        
53
        
54
        m_graph.clearFlagsOnAllNodes(NodeNeedsPhantom | NodeNeedsHardPhantom | NodeRelevantToOSR);
54
        m_graph.clearFlagsOnAllNodes(NodeNeedsPhantom | NodeNeedsHardPhantom | NodeRelevantToOSR);
55
        
55
        m_graph.mergeRelevantToOSR();
56
        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
57
            BasicBlock* block = m_graph.block(blockIndex);
58
            if (!block)
59
                continue;
60
            
61
            for (unsigned i = block->size(); i--;) {
62
                Node* node = block->at(i);
63
                if (node->op() == MovHint)
64
                    node->child1()->mergeFlags(NodeRelevantToOSR);
65
            }
66
        }
67
        
56
        
68
        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
57
        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
69
            BasicBlock* block = m_graph.block(blockIndex);
58
            BasicBlock* block = m_graph.block(blockIndex);
- Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.cpp -11 / +1 lines
Lines 74-90 public: Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.cpp_sec1
74
            }
74
            }
75
        }
75
        }
76
        
76
        
77
        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
77
        m_graph.mergeRelevantToOSR();
78
            BasicBlock* block = m_graph.block(blockIndex);
79
            if (!block)
80
                continue;
81
            
82
            for (unsigned i = block->size(); i--;) {
83
                Node* node = block->at(i);
84
                if (node->op() == MovHint)
85
                    node->child1()->mergeFlags(NodeRelevantToOSR);
86
            }
87
        }
88
        
78
        
89
        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
79
        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
90
            BasicBlock* block = m_graph.block(blockIndex);
80
            BasicBlock* block = m_graph.block(blockIndex);
- Source/JavaScriptCore/dfg/DFGPhiChildren.cpp +64 lines
Line 0 Source/JavaScriptCore/dfg/DFGPhiChildren.cpp_sec1
1
/*
2
 * Copyright (C) 2014 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 "DFGPhiChildren.h"
28
29
#if ENABLE(DFG_JIT)
30
31
#include "DFGGraph.h"
32
33
namespace JSC { namespace DFG {
34
35
PhiChildren::PhiChildren()
36
{
37
}
38
39
PhiChildren::PhiChildren(Graph& graph)
40
{
41
    for (BasicBlock* block : graph.blocksInNaturalOrder()) {
42
        for (Node* node : *block) {
43
            if (node->op() != Upsilon)
44
                continue;
45
            
46
            m_children.add(node->phi(), List()).iterator->value.append(node);
47
        }
48
    }
49
}
50
51
PhiChildren::~PhiChildren()
52
{
53
}
54
55
const PhiChildren::List& PhiChildren::upsilonsOf(Node* node) const
56
{
57
    ASSERT(node->op() == Phi);
58
    return m_children.find(node)->value;
59
}
60
61
} } // namespace JSC::DFG
62
63
#endif // ENABLE(DFG_JIT)
64
- Source/JavaScriptCore/dfg/DFGPhiChildren.h +92 lines
Line 0 Source/JavaScriptCore/dfg/DFGPhiChildren.h_sec1
1
/*
2
 * Copyright (C) 2014 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 DFGPhiChildren_h
27
#define DFGPhiChildren_h
28
29
#if ENABLE(DFG_JIT)
30
31
#include "DFGNode.h"
32
#include <wtf/HashSet.h>
33
#include <wtf/Vector.h>
34
35
namespace JSC { namespace DFG {
36
37
class Graph;
38
39
class PhiChildren {
40
public:
41
    typedef Vector<Node*, 3> List;
42
    
43
    PhiChildren();
44
    PhiChildren(Graph&);
45
    ~PhiChildren();
46
    
47
    // The list of Upsilons that point to the children of the Phi.
48
    const List& upsilonsOf(Node*) const;
49
    
50
    template<typename Functor>
51
    void forAllIncomingValues(Node* node, const Functor& functor)
52
    {
53
        for (Node* upsilon : upsilonsOf(node))
54
            functor(upsilon->child1().node());
55
    }
56
    
57
    // This walks the Phi graph.
58
    template<typename Functor>
59
    void forAllTransitiveIncomingValues(Node* node, const Functor& functor)
60
    {
61
        if (node->op() != Phi) {
62
            functor(node);
63
            return;
64
        }
65
        HashSet<Node*> seen;
66
        Vector<Node*> worklist;
67
        seen.add(node);
68
        worklist.append(node);
69
        while (!worklist.isEmpty()) {
70
            Node* currentNode = worklist.takeLast();
71
            forAllIncomingValues(
72
                currentNode,
73
                [&] (Node* incomingNode) {
74
                    if (incomingNode->op() == Phi) {
75
                        if (seen.add(incomingNode).isNewEntry)
76
                            worklist.append(incomingNode);
77
                    } else
78
                        functor(incomingNode);
79
                });
80
        }
81
    }
82
    
83
private:
84
    HashMap<Node*, List> m_children;
85
};
86
87
} } // namespace JSC::DFG
88
89
#endif // ENABLE(DFG_JIT)
90
91
#endif // DFGPhiChildren_h
92
- Source/JavaScriptCore/dfg/DFGPlan.cpp -1 / +3 lines
Lines 49-54 Source/JavaScriptCore/dfg/DFGPlan.cpp_sec1
49
#include "DFGLoopPreHeaderCreationPhase.h"
49
#include "DFGLoopPreHeaderCreationPhase.h"
50
#include "DFGOSRAvailabilityAnalysisPhase.h"
50
#include "DFGOSRAvailabilityAnalysisPhase.h"
51
#include "DFGOSREntrypointCreationPhase.h"
51
#include "DFGOSREntrypointCreationPhase.h"
52
#include "DFGObjectAllocationSinkingPhase.h"
52
#include "DFGPhantomCanonicalizationPhase.h"
53
#include "DFGPhantomCanonicalizationPhase.h"
53
#include "DFGPhantomRemovalPhase.h"
54
#include "DFGPhantomRemovalPhase.h"
54
#include "DFGPredictionInjectionPhase.h"
55
#include "DFGPredictionInjectionPhase.h"
Lines 325-335 Plan::CompilationPath Plan::compileInThr Source/JavaScriptCore/dfg/DFGPlan.cpp_sec2
325
        performCFA(dfg);
326
        performCFA(dfg);
326
        performConstantFolding(dfg);
327
        performConstantFolding(dfg);
327
        performPhantomCanonicalization(dfg); // Reduce the graph size a lot.
328
        performPhantomCanonicalization(dfg); // Reduce the graph size a lot.
328
        if (performStrengthReduction(dfg)) {
329
        if (performStrengthReduction(dfg) | performObjectAllocationSinking(dfg)) {
329
            // State-at-tail and state-at-head will be invalid if we did strength reduction since
330
            // State-at-tail and state-at-head will be invalid if we did strength reduction since
330
            // it might increase live ranges.
331
            // it might increase live ranges.
331
            performLivenessAnalysis(dfg);
332
            performLivenessAnalysis(dfg);
332
            performCFA(dfg);
333
            performCFA(dfg);
334
            performConstantFolding(dfg);
333
        }
335
        }
334
        performLICM(dfg);
336
        performLICM(dfg);
335
        performPhantomCanonicalization(dfg);
337
        performPhantomCanonicalization(dfg);
- Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp -1 / +6 lines
Lines 560-566 private: Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp_sec1
560
        case DoubleConstant:
560
        case DoubleConstant:
561
        case Int52Constant:
561
        case Int52Constant:
562
        case Identity:
562
        case Identity:
563
        case BooleanToNumber: {
563
        case BooleanToNumber:
564
        case PhantomNewObject:
565
        case PutByOffsetHint:
566
        case CheckStructureImmediate:
567
        case PutStructureHint:
568
        case MaterializeNewObject: {
564
            // This node should never be visible at this stage of compilation. It is
569
            // This node should never be visible at this stage of compilation. It is
565
            // inserted by fixup(), which follows this phase.
570
            // inserted by fixup(), which follows this phase.
566
            RELEASE_ASSERT_NOT_REACHED();
571
            RELEASE_ASSERT_NOT_REACHED();
- Source/JavaScriptCore/dfg/DFGPromoteHeapAccess.h +90 lines
Line 0 Source/JavaScriptCore/dfg/DFGPromoteHeapAccess.h_sec1
1
/*
2
 * Copyright (C) 2014 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 DFGPromoteHeapAccess_h
27
#define DFGPromoteHeapAccess_h
28
29
#if ENABLE(DFG_JIT)
30
31
#include "DFGNode.h"
32
#include "DFGPromotedHeapLocation.h"
33
34
namespace JSC { namespace DFG {
35
36
// Note that the write functor is really the useful thing here. The read functor is only useful
37
// for the object allocation sinking phase.
38
template<typename WriteFunctor, typename ReadFunctor>
39
void promoteHeapAccess(Node* node, const WriteFunctor& write, const ReadFunctor& read)
40
{
41
    switch (node->op()) {
42
    case CheckStructure: {
43
        if (node->child1()->isPhantomObjectAllocation())
44
            read(PromotedHeapLocation(StructurePLoc, node->child1()));
45
        break;
46
    }
47
            
48
    case GetByOffset:
49
    case GetGetterSetterByOffset: {
50
        if (node->child2()->isPhantomObjectAllocation()) {
51
            unsigned identifierNumber = node->storageAccessData().identifierNumber;
52
            read(PromotedHeapLocation(NamedPropertyPLoc, node->child2(), identifierNumber));
53
        }
54
        break;
55
    }
56
                                  
57
    case MultiGetByOffset: {
58
        if (node->child1()->isPhantomObjectAllocation()) {
59
            unsigned identifierNumber = node->multiGetByOffsetData().identifierNumber;
60
            read(PromotedHeapLocation(NamedPropertyPLoc, node->child1(), identifierNumber));
61
        }
62
        break;
63
    }
64
            
65
    case PutStructureHint: {
66
        ASSERT(node->child1()->isPhantomObjectAllocation());
67
        write(PromotedHeapLocation(StructurePLoc, node->child1()), node->child2());
68
        break;
69
    }
70
            
71
    case PutByOffsetHint: {
72
        ASSERT(node->child1()->isPhantomObjectAllocation());
73
        unsigned identifierNumber = node->identifierNumber();
74
        write(
75
            PromotedHeapLocation(NamedPropertyPLoc, node->child1(), identifierNumber),
76
            node->child2());
77
        break;
78
    }
79
80
    default:
81
        break;
82
    }
83
}
84
85
} } // namespace JSC::DFG
86
87
#endif // ENABLE(DFG_JIT)
88
89
#endif // DFGPromoteHeapAccess_h
90
- Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.cpp +93 lines
Line 0 Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.cpp_sec1
1
/*
2
 * Copyright (C) 2014 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 "DFGPromotedHeapLocation.h"
28
29
#if ENABLE(DFG_JIT)
30
31
#include "DFGGraph.h"
32
33
namespace JSC { namespace DFG {
34
35
void PromotedLocationDescriptor::dump(PrintStream& out) const
36
{
37
    out.print(m_kind, "(", m_info, ")");
38
}
39
40
Node* PromotedHeapLocation::createHint(Graph& graph, NodeOrigin origin, Node* value)
41
{
42
    switch (kind()) {
43
    case StructurePLoc:
44
        return graph.addNode(
45
            SpecNone, PutStructureHint, origin,
46
            Edge(base(), KnownCellUse), Edge(value, KnownCellUse));
47
        
48
    case NamedPropertyPLoc:
49
        return graph.addNode(
50
            SpecNone, PutByOffsetHint, origin,
51
            OpInfo(info()), Edge(base(), KnownCellUse), Edge(value, UntypedUse));
52
        
53
    case InvalidPromotedLocationKind:
54
        return nullptr;
55
    }
56
    
57
    RELEASE_ASSERT_NOT_REACHED();
58
}
59
60
void PromotedHeapLocation::dump(PrintStream& out) const
61
{
62
    out.print(kind(), "(", m_base, ", ", info(), ")");
63
}
64
65
} } // namespace JSC::DFG
66
67
namespace WTF {
68
69
using namespace JSC::DFG;
70
71
void printInternal(PrintStream& out, PromotedLocationKind kind)
72
{
73
    switch (kind) {
74
    case InvalidPromotedLocationKind:
75
        out.print("InvalidPromotedLocationKind");
76
        return;
77
        
78
    case StructurePLoc:
79
        out.print("StructurePLoc");
80
        return;
81
        
82
    case NamedPropertyPLoc:
83
        out.print("NamedPropertyPLoc");
84
        return;
85
    }
86
    
87
    RELEASE_ASSERT_NOT_REACHED();
88
}
89
90
} // namespace WTF;
91
92
#endif // ENABLE(DFG_JIT)
93
- Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.h +172 lines
Line 0 Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.h_sec1
1
/*
2
 * Copyright (C) 2014 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 DFGPromotedHeapLocation_h
27
#define DFGPromotedHeapLocation_h
28
29
#if ENABLE(DFG_JIT)
30
31
#include "DFGNode.h"
32
#include <wtf/PrintStream.h>
33
34
namespace JSC { namespace DFG {
35
36
enum PromotedLocationKind {
37
    InvalidPromotedLocationKind,
38
    
39
    StructurePLoc,
40
    NamedPropertyPLoc
41
};
42
43
class PromotedLocationDescriptor {
44
public:
45
    PromotedLocationDescriptor(
46
        PromotedLocationKind kind = InvalidPromotedLocationKind, unsigned info = 0)
47
        : m_kind(kind)
48
        , m_info(info)
49
    {
50
    }
51
    
52
    bool operator!() const { return m_kind == InvalidPromotedLocationKind; }
53
    
54
    PromotedLocationKind kind() const { return m_kind; }
55
    unsigned info() const { return m_info; }
56
    
57
    unsigned hash() const
58
    {
59
        return m_kind + m_info;
60
    }
61
    
62
    bool operator==(const PromotedLocationDescriptor& other) const
63
    {
64
        return m_kind == other.m_kind
65
            && m_info == other.m_info;
66
    }
67
    
68
    bool operator!=(const PromotedLocationDescriptor& other) const
69
    {
70
        return !(*this == other);
71
    }
72
73
    bool isHashTableDeletedValue() const
74
    {
75
        return m_kind == InvalidPromotedLocationKind && m_info;
76
    }
77
    
78
    void dump(PrintStream& out) const;
79
80
private:
81
    PromotedLocationKind m_kind;
82
    unsigned m_info;
83
};
84
85
class PromotedHeapLocation {
86
public:
87
    PromotedHeapLocation(
88
        PromotedLocationKind kind = InvalidPromotedLocationKind,
89
        Node* base = nullptr, unsigned info = 0)
90
        : m_base(base)
91
        , m_meta(kind, info)
92
    {
93
    }
94
    
95
    PromotedHeapLocation(
96
        PromotedLocationKind kind, Edge base, unsigned info = 0)
97
        : PromotedHeapLocation(kind, base.node(), info)
98
    {
99
    }
100
    
101
    PromotedHeapLocation(Node* base, PromotedLocationDescriptor meta)
102
        : m_base(base)
103
        , m_meta(meta)
104
    {
105
    }
106
    
107
    PromotedHeapLocation(WTF::HashTableDeletedValueType)
108
        : m_base(nullptr)
109
        , m_meta(InvalidPromotedLocationKind, 1)
110
    {
111
    }
112
    
113
    Node* createHint(Graph&, NodeOrigin, Node* value);
114
    
115
    bool operator!() const { return kind() == InvalidPromotedLocationKind; }
116
    
117
    PromotedLocationKind kind() const { return m_meta.kind(); }
118
    Node* base() const { return m_base; }
119
    unsigned info() const { return m_meta.info(); }
120
    PromotedLocationDescriptor descriptor() const { return m_meta; }
121
    
122
    unsigned hash() const
123
    {
124
        return m_meta.hash() + WTF::PtrHash<Node*>::hash(m_base);
125
    }
126
    
127
    bool operator==(const PromotedHeapLocation& other) const
128
    {
129
        return m_base == other.m_base
130
            && m_meta == other.m_meta;
131
    }
132
    
133
    bool isHashTableDeletedValue() const
134
    {
135
        return m_meta.isHashTableDeletedValue();
136
    }
137
    
138
    void dump(PrintStream& out) const;
139
    
140
private:
141
    Node* m_base;
142
    PromotedLocationDescriptor m_meta;
143
};
144
145
struct PromotedHeapLocationHash {
146
    static unsigned hash(const PromotedHeapLocation& key) { return key.hash(); }
147
    static bool equal(const PromotedHeapLocation& a, const PromotedHeapLocation& b) { return a == b; }
148
    static const bool safeToCompareToEmptyOrDeleted = true;
149
};
150
151
} } // namespace JSC::DFG
152
153
namespace WTF {
154
155
void printInternal(PrintStream&, JSC::DFG::PromotedLocationKind);
156
157
template<typename T> struct DefaultHash;
158
template<> struct DefaultHash<JSC::DFG::PromotedHeapLocation> {
159
    typedef JSC::DFG::PromotedHeapLocationHash Hash;
160
};
161
162
template<typename T> struct HashTraits;
163
template<> struct HashTraits<JSC::DFG::PromotedHeapLocation> : SimpleClassHashTraits<JSC::DFG::PromotedHeapLocation> {
164
    static const bool emptyValueIsZero = false;
165
};
166
167
} // namespace WTF
168
169
#endif // ENABLE(DFG_JIT)
170
171
#endif // DFGPromotedHeapLocation_h
172
- Source/JavaScriptCore/dfg/DFGSSACalculator.cpp +11 lines
Lines 66-71 SSACalculator::~SSACalculator() Source/JavaScriptCore/dfg/DFGSSACalculator.cpp_sec1
66
{
66
{
67
}
67
}
68
68
69
void SSACalculator::reset()
70
{
71
    m_variables.clear();
72
    m_defs.clear();
73
    m_phis.clear();
74
    for (BlockIndex blockIndex = m_data.size(); blockIndex--;) {
75
        m_data[blockIndex].m_defs.clear();
76
        m_data[blockIndex].m_phis.clear();
77
    }
78
}
79
69
SSACalculator::Variable* SSACalculator::newVariable()
80
SSACalculator::Variable* SSACalculator::newVariable()
70
{
81
{
71
    return &m_variables.alloc(Variable(m_variables.size()));
82
    return &m_variables.alloc(Variable(m_variables.size()));
- Source/JavaScriptCore/dfg/DFGSSACalculator.h +2 lines
Lines 105-110 public: Source/JavaScriptCore/dfg/DFGSSACalculator.h_sec1
105
    SSACalculator(Graph&);
105
    SSACalculator(Graph&);
106
    ~SSACalculator();
106
    ~SSACalculator();
107
    
107
    
108
    void reset();
109
    
108
    class Variable {
110
    class Variable {
109
    public:
111
    public:
110
        unsigned index() const { return m_index; }
112
        unsigned index() const { return m_index; }
- Source/JavaScriptCore/dfg/DFGSafeToExecute.h +5 lines
Lines 270-275 bool safeToExecute(AbstractStateType& st Source/JavaScriptCore/dfg/DFGSafeToExecute.h_sec1
270
    case GetGenericPropertyEnumerator:
270
    case GetGenericPropertyEnumerator:
271
    case GetEnumeratorPname:
271
    case GetEnumeratorPname:
272
    case ToIndexString:
272
    case ToIndexString:
273
    case PhantomNewObject:
274
    case PutByOffsetHint:
275
    case CheckStructureImmediate:
276
    case PutStructureHint:
277
    case MaterializeNewObject:
273
        return true;
278
        return true;
274
279
275
    case NativeCall:
280
    case NativeCall:
- Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp +5 lines
Lines 4912-4917 void SpeculativeJIT::compile(Node* node) Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp_sec1
4912
    case NativeConstruct:
4912
    case NativeConstruct:
4913
    case CheckBadCell:
4913
    case CheckBadCell:
4914
    case BottomValue:
4914
    case BottomValue:
4915
    case PhantomNewObject:
4916
    case PutByOffsetHint:
4917
    case CheckStructureImmediate:
4918
    case PutStructureHint:
4919
    case MaterializeNewObject:
4915
        RELEASE_ASSERT_NOT_REACHED();
4920
        RELEASE_ASSERT_NOT_REACHED();
4916
        break;
4921
        break;
4917
    }
4922
    }
- Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp +5 lines
Lines 4982-4987 void SpeculativeJIT::compile(Node* node) Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp_sec1
4982
    case FiatInt52:
4982
    case FiatInt52:
4983
    case CheckBadCell:
4983
    case CheckBadCell:
4984
    case BottomValue:
4984
    case BottomValue:
4985
    case PhantomNewObject:
4986
    case PutByOffsetHint:
4987
    case CheckStructureImmediate:
4988
    case PutStructureHint:
4989
    case MaterializeNewObject:
4985
        DFG_CRASH(m_jit.graph(), node, "Unexpected node");
4990
        DFG_CRASH(m_jit.graph(), node, "Unexpected node");
4986
        break;
4991
        break;
4987
    }
4992
    }
- Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp -3 / +2 lines
Lines 1415-1421 void SpeculativeJIT::compileCurrentBlock Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp_sec1
1415
        else
1415
        else
1416
            m_canExit = mayExit(m_jit.graph(), m_currentNode);
1416
            m_canExit = mayExit(m_jit.graph(), m_currentNode);
1417
        
1417
        
1418
        bool shouldExecuteEffects = m_interpreter.startExecuting(m_currentNode);
1418
        m_interpreter.startExecuting();
1419
        m_jit.setForNode(m_currentNode);
1419
        m_jit.setForNode(m_currentNode);
1420
        m_codeOriginForExitTarget = m_currentNode->origin.forExit;
1420
        m_codeOriginForExitTarget = m_currentNode->origin.forExit;
1421
        m_codeOriginForExitProfile = m_currentNode->origin.semantic;
1421
        m_codeOriginForExitProfile = m_currentNode->origin.semantic;
Lines 1472-1479 void SpeculativeJIT::compileCurrentBlock Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp_sec2
1472
        }
1472
        }
1473
        
1473
        
1474
        // Make sure that the abstract state is rematerialized for the next node.
1474
        // Make sure that the abstract state is rematerialized for the next node.
1475
        if (shouldExecuteEffects)
1475
        m_interpreter.executeEffects(m_indexInBlock);
1476
            m_interpreter.executeEffects(m_indexInBlock);
1477
    }
1476
    }
1478
    
1477
    
1479
    // Perform the most basic verification that children have been used correctly.
1478
    // Perform the most basic verification that children have been used correctly.
- Source/JavaScriptCore/dfg/DFGValidate.cpp -2 lines
Lines 187-194 public: Source/JavaScriptCore/dfg/DFGValidate.cpp_sec1
187
                Node* node = block->node(i);
187
                Node* node = block->node(i);
188
                if (m_graph.m_refCountState == ExactRefCount)
188
                if (m_graph.m_refCountState == ExactRefCount)
189
                    V_EQUAL((node), m_myRefCounts.get(node), node->adjustedRefCount());
189
                    V_EQUAL((node), m_myRefCounts.get(node), node->adjustedRefCount());
190
                else
191
                    V_EQUAL((node), node->refCount(), 1);
192
            }
190
            }
193
            
191
            
194
            for (size_t i = 0 ; i < block->size() - 1; ++i) {
192
            for (size_t i = 0 ; i < block->size() - 1; ++i) {
- Source/JavaScriptCore/ftl/FTLCapabilities.cpp +5 lines
Lines 168-173 inline CapabilityLevel canCompile(Node* Source/JavaScriptCore/ftl/FTLCapabilities.cpp_sec1
168
    case GetEnumeratorPname:
168
    case GetEnumeratorPname:
169
    case ToIndexString:
169
    case ToIndexString:
170
    case BottomValue:
170
    case BottomValue:
171
    case PhantomNewObject:
172
    case PutByOffsetHint:
173
    case CheckStructureImmediate:
174
    case PutStructureHint:
175
    case MaterializeNewObject:
171
        // These are OK.
176
        // These are OK.
172
        break;
177
        break;
173
    case ProfiledCall:
178
    case ProfiledCall:
- Source/JavaScriptCore/ftl/FTLExitPropertyValue.cpp +41 lines
Line 0 Source/JavaScriptCore/ftl/FTLExitPropertyValue.cpp_sec1
1
/*
2
 * Copyright (C) 2014 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 "FTLExitPropertyValue.h"
28
29
#if ENABLE(FTL_JIT)
30
31
namespace JSC { namespace FTL {
32
33
void ExitPropertyValue::dump(PrintStream& out) const
34
{
35
    out.print(m_location, " => ", m_value);
36
}
37
38
} } // namespace JSC::FTL
39
40
#endif // ENABLE(FTL_JIT)
41
- Source/JavaScriptCore/ftl/FTLExitPropertyValue.h +66 lines
Line 0 Source/JavaScriptCore/ftl/FTLExitPropertyValue.h_sec1
1
/*
2
 * Copyright (C) 2014 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 FTLExitPropertyValue_h
27
#define FTLExitPropertyValue_h
28
29
#if ENABLE(FTL_JIT)
30
31
#include "DFGPromotedHeapLocation.h"
32
#include "FTLExitValue.h"
33
34
namespace JSC { namespace FTL {
35
36
class ExitPropertyValue {
37
public:
38
    ExitPropertyValue()
39
    {
40
    }
41
    
42
    ExitPropertyValue(DFG::PromotedLocationDescriptor location, const ExitValue& value)
43
        : m_location(location)
44
        , m_value(value)
45
    {
46
        ASSERT(!!location == !!value);
47
    }
48
    
49
    bool operator!() const { return !m_location; }
50
    
51
    DFG::PromotedLocationDescriptor location() const { return m_location; }
52
    const ExitValue& value() const { return m_value; }
53
    
54
    void dump(PrintStream& out) const;
55
56
private:
57
    DFG::PromotedLocationDescriptor m_location;
58
    ExitValue m_value;
59
};
60
61
} } // namespace JSC::FTL
62
63
#endif // ENABLE(FTL_JIT)
64
65
#endif // FTLExitPropertyValue_h
66
- Source/JavaScriptCore/ftl/FTLExitTimeObjectMaterialization.cpp +69 lines
Line 0 Source/JavaScriptCore/ftl/FTLExitTimeObjectMaterialization.cpp_sec1
1
/*
2
 * Copyright (C) 2014 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 "FTLExitTimeObjectMaterialization.h"
28
29
#if ENABLE(FTL_JIT)
30
31
#include "DFGGraph.h"
32
33
namespace JSC { namespace FTL {
34
35
using namespace JSC::DFG;
36
37
ExitTimeObjectMaterialization::ExitTimeObjectMaterialization(NodeType type)
38
    : m_type(type)
39
{
40
}
41
42
ExitTimeObjectMaterialization::~ExitTimeObjectMaterialization()
43
{
44
}
45
46
void ExitTimeObjectMaterialization::add(
47
    PromotedLocationDescriptor location, const ExitValue& value)
48
{
49
    m_properties.append(ExitPropertyValue(location, value));
50
}
51
52
ExitValue ExitTimeObjectMaterialization::get(PromotedLocationDescriptor location) const
53
{
54
    for (ExitPropertyValue value : m_properties) {
55
        if (value.location() == location)
56
            return value.value();
57
    }
58
    return ExitValue();
59
}
60
61
void ExitTimeObjectMaterialization::dump(PrintStream& out) const
62
{
63
    out.print(RawPointer(this), ":", Graph::opName(m_type), "(", listDump(m_properties), ")");
64
}
65
66
} } // namespace JSC::FTL
67
68
#endif // ENABLE(FTL_JIT)
69
- Source/JavaScriptCore/ftl/FTLExitTimeObjectMaterialization.h +63 lines
Line 0 Source/JavaScriptCore/ftl/FTLExitTimeObjectMaterialization.h_sec1
1
/*
2
 * Copyright (C) 2014 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 FTLExitTimeObjectMaterialization_h
27
#define FTLExitTimeObjectMaterialization_h
28
29
#if ENABLE(FTL_JIT)
30
31
#include "DFGNodeType.h"
32
#include "FTLExitPropertyValue.h"
33
#include "FTLExitValue.h"
34
#include <wtf/Noncopyable.h>
35
36
namespace JSC { namespace FTL {
37
38
class ExitTimeObjectMaterialization {
39
    WTF_MAKE_NONCOPYABLE(ExitTimeObjectMaterialization)
40
public:
41
    ExitTimeObjectMaterialization(DFG::NodeType);
42
    ~ExitTimeObjectMaterialization();
43
    
44
    void add(DFG::PromotedLocationDescriptor, const ExitValue&);
45
    
46
    DFG::NodeType type() const { return m_type; }
47
    
48
    ExitValue get(DFG::PromotedLocationDescriptor) const;
49
    const Vector<ExitPropertyValue>& properties() const { return m_properties; }
50
    
51
    void dump(PrintStream& out) const;
52
    
53
private:
54
    DFG::NodeType m_type;
55
    Vector<ExitPropertyValue> m_properties;
56
};
57
58
} } // namespace JSC::FTL
59
60
#endif // ENABLE(FTL_JIT)
61
62
#endif // FTLExitTimeObjectMaterialization_h
63
- Source/JavaScriptCore/ftl/FTLExitValue.cpp +12 lines
Lines 28-37 Source/JavaScriptCore/ftl/FTLExitValue.cpp_sec1
28
28
29
#if ENABLE(FTL_JIT)
29
#if ENABLE(FTL_JIT)
30
30
31
#include "FTLExitTimeObjectMaterialization.h"
31
#include "JSCInlines.h"
32
#include "JSCInlines.h"
32
33
33
namespace JSC { namespace FTL {
34
namespace JSC { namespace FTL {
34
35
36
ExitValue ExitValue::materializeNewObject(ExitTimeObjectMaterialization* data)
37
{
38
    ExitValue result;
39
    result.m_kind = ExitValueMaterializeNewObject;
40
    result.u.newObjectMaterializationData = data;
41
    return result;
42
}
43
35
void ExitValue::dumpInContext(PrintStream& out, DumpContext* context) const
44
void ExitValue::dumpInContext(PrintStream& out, DumpContext* context) const
36
{
45
{
37
    switch (kind()) {
46
    switch (kind()) {
Lines 65-70 void ExitValue::dumpInContext(PrintStrea Source/JavaScriptCore/ftl/FTLExitValue.cpp_sec2
65
    case ExitValueRecovery:
74
    case ExitValueRecovery:
66
        out.print("Recovery(", recoveryOpcode(), ", arg", leftRecoveryArgument(), ", arg", rightRecoveryArgument(), ", ", recoveryFormat(), ")");
75
        out.print("Recovery(", recoveryOpcode(), ", arg", leftRecoveryArgument(), ", arg", rightRecoveryArgument(), ", ", recoveryFormat(), ")");
67
        return;
76
        return;
77
    case ExitValueMaterializeNewObject:
78
        out.print("Materialize(", pointerDump(objectMaterialization()), ")");
79
        return;
68
    }
80
    }
69
    
81
    
70
    RELEASE_ASSERT_NOT_REACHED();
82
    RELEASE_ASSERT_NOT_REACHED();
- Source/JavaScriptCore/ftl/FTLExitValue.h -3 / +17 lines
Lines 52-60 enum ExitValueKind { Source/JavaScriptCore/ftl/FTLExitValue.h_sec1
52
    ExitValueInJSStackAsInt52,
52
    ExitValueInJSStackAsInt52,
53
    ExitValueInJSStackAsDouble,
53
    ExitValueInJSStackAsDouble,
54
    ExitValueArgumentsObjectThatWasNotCreated,
54
    ExitValueArgumentsObjectThatWasNotCreated,
55
    ExitValueRecovery
55
    ExitValueRecovery,
56
    ExitValueMaterializeNewObject
56
};
57
};
57
58
59
class ExitTimeObjectMaterialization;
60
58
class ExitValue {
61
class ExitValue {
59
public:
62
public:
60
    ExitValue()
63
    ExitValue()
Lines 137-142 public: Source/JavaScriptCore/ftl/FTLExitValue.h_sec2
137
        return result;
140
        return result;
138
    }
141
    }
139
    
142
    
143
    static ExitValue materializeNewObject(ExitTimeObjectMaterialization*);
144
    
140
    ExitValueKind kind() const { return m_kind; }
145
    ExitValueKind kind() const { return m_kind; }
141
    
146
    
142
    bool isDead() const { return kind() == ExitValueDead; }
147
    bool isDead() const { return kind() == ExitValueDead; }
Lines 156-161 public: Source/JavaScriptCore/ftl/FTLExitValue.h_sec3
156
    bool isArgument() const { return kind() == ExitValueArgument; }
161
    bool isArgument() const { return kind() == ExitValueArgument; }
157
    bool isArgumentsObjectThatWasNotCreated() const { return kind() == ExitValueArgumentsObjectThatWasNotCreated; }
162
    bool isArgumentsObjectThatWasNotCreated() const { return kind() == ExitValueArgumentsObjectThatWasNotCreated; }
158
    bool isRecovery() const { return kind() == ExitValueRecovery; }
163
    bool isRecovery() const { return kind() == ExitValueRecovery; }
164
    bool isObjectMaterialization() const { return kind() == ExitValueMaterializeNewObject; }
159
    
165
    
160
    ExitArgument exitArgument() const
166
    ExitArgument exitArgument() const
161
    {
167
    {
Lines 199-205 public: Source/JavaScriptCore/ftl/FTLExitValue.h_sec4
199
        return VirtualRegister(u.virtualRegister);
205
        return VirtualRegister(u.virtualRegister);
200
    }
206
    }
201
    
207
    
202
    ExitValue withVirtualRegister(VirtualRegister virtualRegister)
208
    ExitTimeObjectMaterialization* objectMaterialization() const
209
    {
210
        ASSERT(isObjectMaterialization());
211
        return u.newObjectMaterializationData;
212
    }
213
214
    ExitValue withVirtualRegister(VirtualRegister virtualRegister) const
203
    {
215
    {
204
        ASSERT(isInJSStackSomehow());
216
        ASSERT(isInJSStackSomehow());
205
        ExitValue result;
217
        ExitValue result;
Lines 207-213 public: Source/JavaScriptCore/ftl/FTLExitValue.h_sec5
207
        result.u.virtualRegister = virtualRegister.offset();
219
        result.u.virtualRegister = virtualRegister.offset();
208
        return result;
220
        return result;
209
    }
221
    }
210
222
    
211
    // If it's in the JSStack somehow, this will tell you what format it's in, in a manner
223
    // If it's in the JSStack somehow, this will tell you what format it's in, in a manner
212
    // that is compatible with exitArgument().format(). If it's a constant or it's dead, it
224
    // that is compatible with exitArgument().format(). If it's a constant or it's dead, it
213
    // will claim to be a JSValue. If it's an argument then it will tell you the argument's
225
    // will claim to be a JSValue. If it's an argument then it will tell you the argument's
Lines 223-228 public: Source/JavaScriptCore/ftl/FTLExitValue.h_sec6
223
        case ExitValueConstant:
235
        case ExitValueConstant:
224
        case ExitValueInJSStack:
236
        case ExitValueInJSStack:
225
        case ExitValueArgumentsObjectThatWasNotCreated:
237
        case ExitValueArgumentsObjectThatWasNotCreated:
238
        case ExitValueMaterializeNewObject:
226
            return ValueFormatJSValue;
239
            return ValueFormatJSValue;
227
            
240
            
228
        case ExitValueArgument:
241
        case ExitValueArgument:
Lines 260-265 private: Source/JavaScriptCore/ftl/FTLExitValue.h_sec7
260
            uint16_t opcode;
273
            uint16_t opcode;
261
            uint16_t format;
274
            uint16_t format;
262
        } recovery;
275
        } recovery;
276
        ExitTimeObjectMaterialization* newObjectMaterializationData;
263
    } u;
277
    } u;
264
};
278
};
265
279
- Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp -158 / +336 lines
Lines 38-43 Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec1
38
#include "FTLFormattedValue.h"
38
#include "FTLFormattedValue.h"
39
#include "FTLInlineCacheSize.h"
39
#include "FTLInlineCacheSize.h"
40
#include "FTLLoweredNodeValue.h"
40
#include "FTLLoweredNodeValue.h"
41
#include "FTLOperations.h"
41
#include "FTLOutput.h"
42
#include "FTLOutput.h"
42
#include "FTLThunks.h"
43
#include "FTLThunks.h"
43
#include "FTLWeightedTarget.h"
44
#include "FTLWeightedTarget.h"
Lines 341-347 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec2
341
        
342
        
342
        m_availableRecoveries.resize(0);
343
        m_availableRecoveries.resize(0);
343
        
344
        
344
        bool shouldExecuteEffects = m_interpreter.startExecuting(m_node);
345
        m_interpreter.startExecuting();
345
        
346
        
346
        switch (m_node->op()) {
347
        switch (m_node->op()) {
347
        case Upsilon:
348
        case Upsilon:
Lines 725-730 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec3
725
        case ToIndexString:
726
        case ToIndexString:
726
            compileToIndexString();
727
            compileToIndexString();
727
            break;
728
            break;
729
        case CheckStructureImmediate:
730
            compileCheckStructureImmediate();
731
            break;
732
        case MaterializeNewObject:
733
            compileMaterializeNewObject();
734
            break;
728
735
729
        case PhantomLocal:
736
        case PhantomLocal:
730
        case SetArgument:
737
        case SetArgument:
Lines 735-740 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec4
735
        case AllocationProfileWatchpoint:
742
        case AllocationProfileWatchpoint:
736
        case MovHint:
743
        case MovHint:
737
        case ZombieHint:
744
        case ZombieHint:
745
        case PhantomNewObject:
746
        case PutByOffsetHint:
747
        case PutStructureHint:
748
        case BottomValue:
738
            break;
749
            break;
739
        default:
750
        default:
740
            DFG_CRASH(m_graph, m_node, "Unrecognized node in FTL backend");
751
            DFG_CRASH(m_graph, m_node, "Unrecognized node in FTL backend");
Lines 742-750 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec5
742
        }
753
        }
743
        
754
        
744
        m_availabilityCalculator.executeNode(m_node);
755
        m_availabilityCalculator.executeNode(m_node);
745
        
756
        m_interpreter.executeEffects(nodeIndex);
746
        if (shouldExecuteEffects)
747
            m_interpreter.executeEffects(nodeIndex);
748
        
757
        
749
        return true;
758
        return true;
750
    }
759
    }
Lines 1704-1733 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec6
1704
        
1713
        
1705
        LValue structureID = m_out.load32(cell, m_heaps.JSCell_structureID);
1714
        LValue structureID = m_out.load32(cell, m_heaps.JSCell_structureID);
1706
        
1715
        
1707
        if (m_node->structureSet().size() == 1) {
1716
        checkStructure(structureID, jsValueValue(cell), exitKind, m_node->structureSet());
1708
            speculate(
1709
                exitKind, jsValueValue(cell), 0,
1710
                m_out.notEqual(structureID, weakStructure(m_node->structureSet()[0])));
1711
            return;
1712
        }
1713
        
1714
        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("CheckStructure continuation"));
1715
        
1716
        LBasicBlock lastNext = m_out.insertNewBlocksBefore(continuation);
1717
        for (unsigned i = 0; i < m_node->structureSet().size() - 1; ++i) {
1718
            LBasicBlock nextStructure = FTL_NEW_BLOCK(m_out, ("CheckStructure nextStructure"));
1719
            m_out.branch(
1720
                m_out.equal(structureID, weakStructure(m_node->structureSet()[i])),
1721
                unsure(continuation), unsure(nextStructure));
1722
            m_out.appendTo(nextStructure);
1723
        }
1724
        
1725
        speculate(
1726
            exitKind, jsValueValue(cell), 0,
1727
            m_out.notEqual(structureID, weakStructure(m_node->structureSet().last())));
1728
        
1729
        m_out.jump(continuation);
1730
        m_out.appendTo(continuation, lastNext);
1731
    }
1717
    }
1732
    
1718
    
1733
    void compileCheckCell()
1719
    void compileCheckCell()
Lines 2649-2676 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec7
2649
    
2635
    
2650
    void compileNewObject()
2636
    void compileNewObject()
2651
    {
2637
    {
2652
        Structure* structure = m_node->structure();
2638
        setJSValue(allocateObject(m_node->structure()));
2653
        size_t allocationSize = JSFinalObject::allocationSize(structure->inlineCapacity());
2654
        MarkedAllocator* allocator = &vm().heap.allocatorForObjectWithoutDestructor(allocationSize);
2655
        
2656
        LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("NewObject slow path"));
2657
        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("NewObject continuation"));
2658
        
2659
        LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
2660
        
2661
        ValueFromBlock fastResult = m_out.anchor(allocateObject(
2662
            m_out.constIntPtr(allocator), structure, m_out.intPtrZero, slowPath));
2663
        
2664
        m_out.jump(continuation);
2665
        
2666
        m_out.appendTo(slowPath, continuation);
2667
        
2668
        ValueFromBlock slowResult = m_out.anchor(vmCall(
2669
            m_out.operation(operationNewObject), m_callFrame, m_out.constIntPtr(structure)));
2670
        m_out.jump(continuation);
2671
        
2672
        m_out.appendTo(continuation, lastNext);
2673
        setJSValue(m_out.phi(m_out.intPtr, fastResult, slowResult));
2674
    }
2639
    }
2675
    
2640
    
2676
    void compileNewArray()
2641
    void compileNewArray()
Lines 3370-3376 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec8
3370
        LBasicBlock lastNext = m_out.m_nextBlock;
3335
        LBasicBlock lastNext = m_out.m_nextBlock;
3371
        
3336
        
3372
        for (unsigned i = data.variants.size(); i--;) {
3337
        for (unsigned i = data.variants.size(); i--;) {
3373
            m_out.appendTo(blocks[i], i  + 1 < data.variants.size() ? blocks[i + 1] : exit);
3338
            m_out.appendTo(blocks[i], i + 1 < data.variants.size() ? blocks[i + 1] : exit);
3374
            
3339
            
3375
            PutByIdVariant variant = data.variants[i];
3340
            PutByIdVariant variant = data.variants[i];
3376
            
3341
            
Lines 3953-3964 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec9
3953
    void compileInvalidationPoint()
3918
    void compileInvalidationPoint()
3954
    {
3919
    {
3955
        if (verboseCompilationEnabled())
3920
        if (verboseCompilationEnabled())
3956
            dataLog("    Invalidation point with availability: ", availability(), "\n");
3921
            dataLog("    Invalidation point with availability: ", availabilityMap(), "\n");
3957
        
3922
        
3958
        m_ftlState.jitCode->osrExit.append(OSRExit(
3923
        m_ftlState.jitCode->osrExit.append(OSRExit(
3959
            UncountableInvalidation, InvalidValueFormat, MethodOfGettingAValueProfile(),
3924
            UncountableInvalidation, InvalidValueFormat, MethodOfGettingAValueProfile(),
3960
            m_codeOriginForExitTarget, m_codeOriginForExitProfile,
3925
            m_codeOriginForExitTarget, m_codeOriginForExitProfile,
3961
            availability().numberOfArguments(), availability().numberOfLocals()));
3926
            availabilityMap().m_locals.numberOfArguments(),
3927
            availabilityMap().m_locals.numberOfLocals()));
3962
        m_ftlState.finalizer->osrExit.append(OSRExitCompilationInfo());
3928
        m_ftlState.finalizer->osrExit.append(OSRExitCompilationInfo());
3963
        
3929
        
3964
        OSRExit& exit = m_ftlState.jitCode->osrExit.last();
3930
        OSRExit& exit = m_ftlState.jitCode->osrExit.last();
Lines 4360-4365 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec10
4360
        LValue index = lowInt32(m_node->child1());
4326
        LValue index = lowInt32(m_node->child1());
4361
        setJSValue(vmCall(m_out.operation(operationToIndexString), m_callFrame, index));
4327
        setJSValue(vmCall(m_out.operation(operationToIndexString), m_callFrame, index));
4362
    }
4328
    }
4329
    
4330
    void compileCheckStructureImmediate()
4331
    {
4332
        LValue structureID = lowCell(m_node->child1());
4333
        checkStructure(structureID, noValue(), BadCache, m_node->structureSet());
4334
    }
4335
    
4336
    void compileMaterializeNewObject()
4337
    {
4338
        ObjectMaterializationData& data = m_node->objectMaterializationData();
4339
        
4340
        // Lower the values first, to avoid creating values inside a control flow diamond.
4341
        
4342
        Vector<LValue, 8> values;
4343
        for (unsigned i = 0; i < data.m_properties.size(); ++i)
4344
            values.append(lowJSValue(m_graph.varArgChild(m_node, 1 + i)));
4345
        
4346
        StructureSet set;
4347
        m_interpreter.phiChildren()->forAllTransitiveIncomingValues(
4348
            m_node,
4349
            [&] (Node* incoming) {
4350
                set.add(incoming->castConstant<Structure*>());
4351
            });
4352
        
4353
        Vector<LBasicBlock, 1> blocks(set.size());
4354
        for (unsigned i = set.size(); i--;)
4355
            blocks[i] = FTL_NEW_BLOCK(m_out, ("MaterializeNewObject case ", i));
4356
        LBasicBlock dummyDefault = FTL_NEW_BLOCK(m_out, ("MaterializeNewObject default case"));
4357
        LBasicBlock outerContinuation = FTL_NEW_BLOCK(m_out, ("MaterializeNewObject continuation"));
4358
        
4359
        Vector<SwitchCase, 1> cases(set.size());
4360
        for (unsigned i = set.size(); i--;)
4361
            cases[i] = SwitchCase(weakStructure(set[i]), blocks[i], Weight(1));
4362
        m_out.switchInstruction(
4363
            lowCell(m_graph.varArgChild(m_node, 0)), cases, dummyDefault, Weight(0));
4364
        
4365
        LBasicBlock outerLastNext = m_out.m_nextBlock;
4366
        
4367
        Vector<ValueFromBlock, 1> results;
4368
        
4369
        for (unsigned i = set.size(); i--;) {
4370
            m_out.appendTo(blocks[i], i + 1 < set.size() ? blocks[i + 1] : dummyDefault);
4371
            
4372
            Structure* structure = set[i];
4373
            
4374
            LValue object;
4375
            LValue butterfly;
4376
            
4377
            if (structure->outOfLineCapacity()) {
4378
                size_t allocationSize = JSFinalObject::allocationSize(structure->inlineCapacity());
4379
                MarkedAllocator* allocator = &vm().heap.allocatorForObjectWithoutDestructor(allocationSize);
4380
                
4381
                LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("MaterializeNewObject complex object allocation slow path"));
4382
                LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("MaterializeNewObject complex object allocation continuation"));
4383
                
4384
                LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
4385
                
4386
                LValue endOfStorage = allocateBasicStorageAndGetEnd(
4387
                    m_out.constIntPtr(structure->outOfLineCapacity() * sizeof(JSValue)),
4388
                    slowPath);
4389
                
4390
                LValue fastButterflyValue = m_out.add(
4391
                    m_out.constIntPtr(sizeof(IndexingHeader)), endOfStorage);
4392
                
4393
                LValue fastObjectValue = allocateObject(
4394
                    m_out.constIntPtr(allocator), structure, fastButterflyValue, slowPath);
4395
4396
                ValueFromBlock fastObject = m_out.anchor(fastObjectValue);
4397
                ValueFromBlock fastButterfly = m_out.anchor(fastButterflyValue);
4398
                m_out.jump(continuation);
4399
                
4400
                m_out.appendTo(slowPath, continuation);
4401
                
4402
                ValueFromBlock slowObject = m_out.anchor(vmCall(
4403
                    m_out.operation(operationNewObjectWithButterfly),
4404
                    m_callFrame, m_out.constIntPtr(structure)));
4405
                ValueFromBlock slowButterfly = m_out.anchor(
4406
                    m_out.loadPtr(slowObject.value(), m_heaps.JSObject_butterfly));
4407
                
4408
                m_out.jump(continuation);
4409
                
4410
                m_out.appendTo(continuation, lastNext);
4411
                
4412
                object = m_out.phi(m_out.intPtr, fastObject, slowObject);
4413
                butterfly = m_out.phi(m_out.intPtr, fastButterfly, slowButterfly);
4414
            } else {
4415
                // In the easy case where we can do a one-shot allocation, we simply allocate the
4416
                // object to directly have the desired structure.
4417
                object = allocateObject(structure);
4418
                butterfly = nullptr; // Don't have one, don't need one.
4419
            }
4420
            
4421
            for (PropertyMapEntry entry : structure->getPropertiesConcurrently()) {
4422
                for (unsigned i = data.m_properties.size(); i--;) {
4423
                    PhantomPropertyValue value = data.m_properties[i];
4424
                    if (m_graph.identifiers()[value.m_identifierNumber] != entry.key)
4425
                        continue;
4426
                    
4427
                    LValue base = isInlineOffset(entry.offset) ? object : butterfly;
4428
                    storeProperty(values[i], base, value.m_identifierNumber, entry.offset);
4429
                    break;
4430
                }
4431
            }
4432
            
4433
            results.append(m_out.anchor(object));
4434
            m_out.jump(outerContinuation);
4435
        }
4436
        
4437
        m_out.appendTo(dummyDefault, outerContinuation);
4438
        m_out.unreachable();
4439
        
4440
        m_out.appendTo(outerContinuation, outerLastNext);
4441
        setJSValue(m_out.phi(m_out.intPtr, results));
4442
    }
4363
4443
4364
#if ENABLE(FTL_NATIVE_CALL_INLINING)
4444
#if ENABLE(FTL_NATIVE_CALL_INLINING)
4365
    LValue getFunctionBySymbol(const CString symbol)
4445
    LValue getFunctionBySymbol(const CString symbol)
Lines 4525-4530 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec11
4525
        return m_out.booleanFalse;
4605
        return m_out.booleanFalse;
4526
    }
4606
    }
4527
    
4607
    
4608
    void checkStructure(
4609
        LValue structureID, const FormattedValue& formattedValue, ExitKind exitKind,
4610
        const StructureSet& set)
4611
    {
4612
        if (set.size() == 1) {
4613
            speculate(
4614
                exitKind, formattedValue, 0,
4615
                m_out.notEqual(structureID, weakStructure(set[0])));
4616
            return;
4617
        }
4618
        
4619
        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("checkStructure continuation"));
4620
        
4621
        LBasicBlock lastNext = m_out.insertNewBlocksBefore(continuation);
4622
        for (unsigned i = 0; i < set.size() - 1; ++i) {
4623
            LBasicBlock nextStructure = FTL_NEW_BLOCK(m_out, ("checkStructure nextStructure"));
4624
            m_out.branch(
4625
                m_out.equal(structureID, weakStructure(set[i])),
4626
                unsure(continuation), unsure(nextStructure));
4627
            m_out.appendTo(nextStructure);
4628
        }
4629
        
4630
        speculate(
4631
            exitKind, formattedValue, 0,
4632
            m_out.notEqual(structureID, weakStructure(set.last())));
4633
        
4634
        m_out.jump(continuation);
4635
        m_out.appendTo(continuation, lastNext);
4636
    }
4637
    
4528
    LValue numberOrNotCellToInt32(Edge edge, LValue value)
4638
    LValue numberOrNotCellToInt32(Edge edge, LValue value)
4529
    {
4639
    {
4530
        LBasicBlock intCase = FTL_NEW_BLOCK(m_out, ("ValueToInt32 int case"));
4640
        LBasicBlock intCase = FTL_NEW_BLOCK(m_out, ("ValueToInt32 int case"));
Lines 4624-4707 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec12
4624
                m_callFrame, object);
4734
                m_callFrame, object);
4625
        }
4735
        }
4626
        
4736
        
4627
        LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("allocatePropertyStorage slow path"));
4737
        LValue result = allocatePropertyStorageWithSizeImpl(initialOutOfLineCapacity);
4628
        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("allocatePropertyStorage continuation"));
4629
        
4630
        LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
4631
        
4632
        LValue endOfStorage = allocateBasicStorageAndGetEnd(
4633
            m_out.constIntPtr(initialOutOfLineCapacity * sizeof(JSValue)), slowPath);
4634
        
4635
        ValueFromBlock fastButterfly = m_out.anchor(
4636
            m_out.add(m_out.constIntPtr(sizeof(IndexingHeader)), endOfStorage));
4637
        
4638
        m_out.jump(continuation);
4639
        
4640
        m_out.appendTo(slowPath, continuation);
4641
        
4642
        ValueFromBlock slowButterfly = m_out.anchor(vmCall(
4643
            m_out.operation(operationAllocatePropertyStorageWithInitialCapacity), m_callFrame));
4644
        
4645
        m_out.jump(continuation);
4646
        
4647
        m_out.appendTo(continuation, lastNext);
4648
        
4649
        LValue result = m_out.phi(m_out.intPtr, fastButterfly, slowButterfly);
4650
        m_out.storePtr(result, object, m_heaps.JSObject_butterfly);
4738
        m_out.storePtr(result, object, m_heaps.JSObject_butterfly);
4651
        
4652
        return result;
4739
        return result;
4653
    }
4740
    }
4654
    
4741
    
4655
    LValue reallocatePropertyStorage(
4742
    LValue reallocatePropertyStorage(
4656
        LValue object, LValue oldStorage, Structure* previous, Structure* next)
4743
        LValue object, LValue oldStorage, Structure* previous, Structure* next)
4657
    {
4744
    {
4658
        size_t oldSize = previous->outOfLineCapacity() * sizeof(JSValue);
4745
        size_t oldSize = previous->outOfLineCapacity();
4659
        size_t newSize = oldSize * outOfLineGrowthFactor; 
4746
        size_t newSize = oldSize * outOfLineGrowthFactor; 
4660
4747
4661
        ASSERT_UNUSED(next, newSize == next->outOfLineCapacity() * sizeof(JSValue));
4748
        ASSERT_UNUSED(next, newSize == next->outOfLineCapacity());
4662
        
4749
        
4663
        if (previous->couldHaveIndexingHeader()) {
4750
        if (previous->couldHaveIndexingHeader()) {
4664
            LValue newAllocSize = m_out.constInt64(newSize / sizeof(JSValue));                    
4751
            LValue newAllocSize = m_out.constIntPtr(newSize);                    
4665
            return vmCall(m_out.operation(operationReallocateButterflyToGrowPropertyStorage), m_callFrame, object, newAllocSize);
4752
            return vmCall(m_out.operation(operationReallocateButterflyToGrowPropertyStorage), m_callFrame, object, newAllocSize);
4666
        }
4753
        }
4667
        
4754
        
4668
        LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("reallocatePropertyStorage slow path"));
4755
        LValue result = allocatePropertyStorageWithSizeImpl(newSize);
4669
        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("reallocatePropertyStorage continuation"));
4756
4757
        ptrdiff_t headerSize = -sizeof(IndexingHeader) - sizeof(void*);
4758
        ptrdiff_t endStorage = headerSize - static_cast<ptrdiff_t>(oldSize * sizeof(JSValue));
4759
4760
        for (ptrdiff_t offset = headerSize; offset > endStorage; offset -= sizeof(void*)) {
4761
            LValue loaded = 
4762
                m_out.loadPtr(m_out.address(m_heaps.properties.atAnyNumber(), oldStorage, offset));
4763
            m_out.storePtr(loaded, m_out.address(m_heaps.properties.atAnyNumber(), result, offset));
4764
        }
4765
        
4766
        m_out.storePtr(result, m_out.address(object, m_heaps.JSObject_butterfly));
4767
        
4768
        return result;
4769
    }
4770
    
4771
    LValue allocatePropertyStorageWithSizeImpl(size_t sizeInValues)
4772
    {
4773
        LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("allocatePropertyStorageWithSizeImpl slow path"));
4774
        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("allocatePropertyStorageWithSizeImpl continuation"));
4775
        
4670
        LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
4776
        LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
4671
        
4777
        
4672
        LValue endOfStorage = 
4778
        LValue endOfStorage = allocateBasicStorageAndGetEnd(
4673
            allocateBasicStorageAndGetEnd(m_out.constIntPtr(newSize), slowPath);
4779
            m_out.constIntPtr(sizeInValues * sizeof(JSValue)), slowPath);
4674
        
4780
        
4675
        ValueFromBlock fastButterfly = m_out.anchor(m_out.add(m_out.constIntPtr(sizeof(IndexingHeader)), endOfStorage));
4781
        ValueFromBlock fastButterfly = m_out.anchor(
4782
            m_out.add(m_out.constIntPtr(sizeof(IndexingHeader)), endOfStorage));
4676
        
4783
        
4677
        m_out.jump(continuation);
4784
        m_out.jump(continuation);
4678
        
4785
        
4679
        m_out.appendTo(slowPath, continuation);
4786
        m_out.appendTo(slowPath, continuation);
4680
        
4787
        
4681
        LValue newAllocSize = m_out.constInt64(newSize / sizeof(JSValue));       
4788
        LValue slowButterflyValue;
4682
        
4789
        if (sizeInValues == initialOutOfLineCapacity) {
4683
        LValue storageLocation = vmCall(m_out.operation(operationAllocatePropertyStorage), m_callFrame, newAllocSize);
4790
            slowButterflyValue = vmCall(
4684
        
4791
                m_out.operation(operationAllocatePropertyStorageWithInitialCapacity),
4685
        ValueFromBlock slowButterfly = m_out.anchor(storageLocation);
4792
                m_callFrame);
4793
        } else {
4794
            slowButterflyValue = vmCall(
4795
                m_out.operation(operationAllocatePropertyStorage),
4796
                m_callFrame, m_out.constIntPtr(sizeInValues));
4797
        }
4798
        ValueFromBlock slowButterfly = m_out.anchor(slowButterflyValue);
4686
        
4799
        
4687
        m_out.jump(continuation);
4800
        m_out.jump(continuation);
4688
        
4801
        
4689
        m_out.appendTo(continuation, lastNext);
4802
        m_out.appendTo(continuation, lastNext);
4690
        
4803
        
4691
        LValue result = m_out.phi(m_out.intPtr, fastButterfly, slowButterfly);
4804
        return m_out.phi(m_out.intPtr, fastButterfly, slowButterfly);
4692
4693
        ptrdiff_t headerSize = -sizeof(JSValue) - sizeof(void *);
4694
        ptrdiff_t endStorage = headerSize - static_cast<ptrdiff_t>(oldSize);
4695
4696
        for (ptrdiff_t offset = headerSize; offset > endStorage; offset -= sizeof(void*)) {
4697
            LValue loaded = 
4698
                m_out.loadPtr(m_out.address(m_heaps.properties.atAnyNumber(), oldStorage, offset));
4699
            m_out.storePtr(loaded, m_out.address(m_heaps.properties.atAnyNumber(), result, offset));
4700
        }
4701
        
4702
        m_out.storePtr(result, m_out.address(object, m_heaps.JSObject_butterfly));
4703
        
4704
        return result;
4705
    }
4805
    }
4706
    
4806
    
4707
    LValue getById(LValue base)
4807
    LValue getById(LValue base)
Lines 4841-4847 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec13
4841
        setBoolean(m_out.phi(m_out.boolean, fastResult, slowResult));
4941
        setBoolean(m_out.phi(m_out.boolean, fastResult, slowResult));
4842
    }
4942
    }
4843
4943
4844
    LValue allocateCell(LValue allocator, Structure* structure, LBasicBlock slowPath)
4944
    LValue allocateCell(LValue allocator, LBasicBlock slowPath)
4845
    {
4945
    {
4846
        LBasicBlock success = FTL_NEW_BLOCK(m_out, ("object allocation success"));
4946
        LBasicBlock success = FTL_NEW_BLOCK(m_out, ("object allocation success"));
4847
        
4947
        
Lines 4856-4867 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec14
4856
            m_out.loadPtr(result, m_heaps.JSCell_freeListNext),
4956
            m_out.loadPtr(result, m_heaps.JSCell_freeListNext),
4857
            allocator, m_heaps.MarkedAllocator_freeListHead);
4957
            allocator, m_heaps.MarkedAllocator_freeListHead);
4858
        
4958
        
4859
        m_out.store32(m_out.constInt32(structure->id()), result, m_heaps.JSCell_structureID);
4959
        return result;
4860
        
4960
    }
4961
    
4962
    void storeStructure(LValue object, Structure* structure)
4963
    {
4964
        m_out.store32(m_out.constInt32(structure->id()), object, m_heaps.JSCell_structureID);
4861
        m_out.store32(
4965
        m_out.store32(
4862
            m_out.constInt32(structure->objectInitializationBlob()),
4966
            m_out.constInt32(structure->objectInitializationBlob()),
4863
            result, m_heaps.JSCell_usefulBytes);
4967
            object, m_heaps.JSCell_usefulBytes);
4864
        
4968
    }
4969
4970
    LValue allocateCell(LValue allocator, Structure* structure, LBasicBlock slowPath)
4971
    {
4972
        LValue result = allocateCell(allocator, slowPath);
4973
        storeStructure(result, structure);
4865
        return result;
4974
        return result;
4866
    }
4975
    }
4867
4976
Lines 4908-4913 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec15
4908
            m_out.loadPtr(m_out.absolute(&allocator.m_currentPayloadEnd)), newRemaining);
5017
            m_out.loadPtr(m_out.absolute(&allocator.m_currentPayloadEnd)), newRemaining);
4909
    }
5018
    }
4910
    
5019
    
5020
    LValue allocateObject(Structure* structure)
5021
    {
5022
        size_t allocationSize = JSFinalObject::allocationSize(structure->inlineCapacity());
5023
        MarkedAllocator* allocator = &vm().heap.allocatorForObjectWithoutDestructor(allocationSize);
5024
        
5025
        LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("allocateObject slow path"));
5026
        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("allocateObject continuation"));
5027
        
5028
        LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
5029
        
5030
        ValueFromBlock fastResult = m_out.anchor(allocateObject(
5031
            m_out.constIntPtr(allocator), structure, m_out.intPtrZero, slowPath));
5032
        
5033
        m_out.jump(continuation);
5034
        
5035
        m_out.appendTo(slowPath, continuation);
5036
        
5037
        ValueFromBlock slowResult = m_out.anchor(vmCall(
5038
            m_out.operation(operationNewObject), m_callFrame, m_out.constIntPtr(structure)));
5039
        m_out.jump(continuation);
5040
        
5041
        m_out.appendTo(continuation, lastNext);
5042
        return m_out.phi(m_out.intPtr, fastResult, slowResult);
5043
    }
5044
    
4911
    struct ArrayValues {
5045
    struct ArrayValues {
4912
        ArrayValues()
5046
        ArrayValues()
4913
            : array(0)
5047
            : array(0)
Lines 6344-6350 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec16
6344
        ExitKind kind, FormattedValue lowValue, Node* highValue, LValue failCondition)
6478
        ExitKind kind, FormattedValue lowValue, Node* highValue, LValue failCondition)
6345
    {
6479
    {
6346
        if (verboseCompilationEnabled()) {
6480
        if (verboseCompilationEnabled()) {
6347
            dataLog("    OSR exit #", m_ftlState.jitCode->osrExit.size(), " with availability: ", availability(), "\n");
6481
            dataLog("    OSR exit #", m_ftlState.jitCode->osrExit.size(), " with availability: ", availabilityMap(), "\n");
6348
            if (!m_availableRecoveries.isEmpty())
6482
            if (!m_availableRecoveries.isEmpty())
6349
                dataLog("        Available recoveries: ", listDump(m_availableRecoveries), "\n");
6483
                dataLog("        Available recoveries: ", listDump(m_availableRecoveries), "\n");
6350
        }
6484
        }
Lines 6354-6360 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec17
6354
        m_ftlState.jitCode->osrExit.append(OSRExit(
6488
        m_ftlState.jitCode->osrExit.append(OSRExit(
6355
            kind, lowValue.format(), m_graph.methodOfGettingAValueProfileFor(highValue),
6489
            kind, lowValue.format(), m_graph.methodOfGettingAValueProfileFor(highValue),
6356
            m_codeOriginForExitTarget, m_codeOriginForExitProfile,
6490
            m_codeOriginForExitTarget, m_codeOriginForExitProfile,
6357
            availability().numberOfArguments(), availability().numberOfLocals()));
6491
            availabilityMap().m_locals.numberOfArguments(),
6492
            availabilityMap().m_locals.numberOfLocals()));
6358
        m_ftlState.finalizer->osrExit.append(OSRExitCompilationInfo());
6493
        m_ftlState.finalizer->osrExit.append(OSRExitCompilationInfo());
6359
        
6494
        
6360
        OSRExit& exit = m_ftlState.jitCode->osrExit.last();
6495
        OSRExit& exit = m_ftlState.jitCode->osrExit.last();
Lines 6394-6449 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec18
6394
        if (!!lowValue)
6529
        if (!!lowValue)
6395
            arguments.append(lowValue.value());
6530
            arguments.append(lowValue.value());
6396
        
6531
        
6532
        AvailabilityMap availabilityMap = this->availabilityMap();
6533
        
6397
        for (unsigned i = 0; i < exit.m_values.size(); ++i) {
6534
        for (unsigned i = 0; i < exit.m_values.size(); ++i) {
6398
            int operand = exit.m_values.operandForIndex(i);
6535
            int operand = exit.m_values.operandForIndex(i);
6399
            bool isLive = m_graph.isLiveInBytecode(VirtualRegister(operand), codeOrigin);
6536
            if (!m_graph.isLiveInBytecode(VirtualRegister(operand), codeOrigin))
6400
            if (!isLive) {
6537
                availabilityMap.m_locals[i] = Availability();
6401
                exit.m_values[i] = ExitValue::dead();
6538
        }
6402
                continue;
6539
        
6403
            }
6540
        availabilityMap.prune();
6404
            
6541
        
6405
            Availability availability = this->availability()[i];
6542
        HashMap<Node*, ExitTimeObjectMaterialization*> map;
6406
            FlushedAt flush = availability.flushedAt();
6543
        availabilityMap.forEachAvailability(
6407
            switch (flush.format()) {
6544
            [&] (Availability availability) {
6408
            case DeadFlush:
6545
                if (!availability.shouldUseNode())
6409
            case ConflictingFlush:
6546
                    return;
6410
                if (availability.hasNode()) {
6411
                    exit.m_values[i] = exitValueForNode(arguments, availability.node());
6412
                    break;
6413
                }
6414
                
6415
                if (Options::validateFTLOSRExitLiveness())
6416
                    DFG_CRASH(m_graph, m_node, toCString("Expected r", operand, " to be available but it wasn't.").data());
6417
                
6418
                // This means that the DFG's DCE proved that the value is dead in bytecode
6419
                // even though the bytecode liveness analysis thinks it's live. This is
6420
                // acceptable since the DFG's DCE is by design more aggressive while still
6421
                // being sound.
6422
                exit.m_values[i] = ExitValue::dead();
6423
                break;
6424
6425
            case FlushedJSValue:
6426
            case FlushedCell:
6427
            case FlushedBoolean:
6428
                exit.m_values[i] = ExitValue::inJSStack(flush.virtualRegister());
6429
                break;
6430
                
6431
            case FlushedInt32:
6432
                exit.m_values[i] = ExitValue::inJSStackAsInt32(flush.virtualRegister());
6433
                break;
6434
                
6435
            case FlushedInt52:
6436
                exit.m_values[i] = ExitValue::inJSStackAsInt52(flush.virtualRegister());
6437
                break;
6438
                
6547
                
6439
            case FlushedDouble:
6548
                Node* node = availability.node();
6440
                exit.m_values[i] = ExitValue::inJSStackAsDouble(flush.virtualRegister());
6549
                if (!node->isPhantomObjectAllocation())
6441
                break;
6550
                    return;
6442
                
6551
                
6443
            case FlushedArguments:
6552
                auto result = map.add(node, nullptr);
6444
                exit.m_values[i] = ExitValue::argumentsObjectThatWasNotCreated();
6553
                if (result.isNewEntry)
6445
                break;
6554
                    result.iterator->value = exit.m_materializations.add(node->op());
6555
            });
6556
        
6557
        for (unsigned i = 0; i < exit.m_values.size(); ++i) {
6558
            int operand = exit.m_values.operandForIndex(i);
6559
            
6560
            Availability availability = this->availabilityMap().m_locals[i];
6561
            
6562
            if (Options::validateFTLOSRExitLiveness()) {
6563
                DFG_ASSERT(
6564
                    m_graph, m_node,
6565
                    m_graph.isLiveInBytecode(VirtualRegister(operand), codeOrigin)
6566
                    == availability.isDead());
6446
            }
6567
            }
6568
            
6569
            exit.m_values[i] = exitValueForAvailability(arguments, map, availability);
6570
        }
6571
        
6572
        for (auto heapPair : availabilityMap.m_heap) {
6573
            Node* node = heapPair.key.base();
6574
            ExitTimeObjectMaterialization* materialization = map.get(node);
6575
            materialization->add(
6576
                heapPair.key.descriptor(),
6577
                exitValueForAvailability(arguments, map, heapPair.value));
6447
        }
6578
        }
6448
        
6579
        
6449
        if (verboseCompilationEnabled())
6580
        if (verboseCompilationEnabled())
Lines 6459-6471 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec19
6459
        m_out.call(m_out.stackmapIntrinsic(), arguments);
6590
        m_out.call(m_out.stackmapIntrinsic(), arguments);
6460
    }
6591
    }
6461
    
6592
    
6462
    ExitValue exitValueForNode(ExitArgumentList& arguments, Node* node)
6593
    ExitValue exitValueForAvailability(
6594
        ExitArgumentList& arguments, const HashMap<Node*, ExitTimeObjectMaterialization*>& map,
6595
        Availability availability)
6596
    {
6597
        FlushedAt flush = availability.flushedAt();
6598
        switch (flush.format()) {
6599
        case DeadFlush:
6600
        case ConflictingFlush:
6601
            if (availability.hasNode())
6602
                return exitValueForNode(arguments, map, availability.node());
6603
            
6604
            // This means that the value is dead. It could be dead in bytecode or it could have
6605
            // been killed by our DCE, which can sometimes kill things even if they were live in
6606
            // bytecode.
6607
            return ExitValue::dead();
6608
6609
        case FlushedJSValue:
6610
        case FlushedCell:
6611
        case FlushedBoolean:
6612
            return ExitValue::inJSStack(flush.virtualRegister());
6613
                
6614
        case FlushedInt32:
6615
            return ExitValue::inJSStackAsInt32(flush.virtualRegister());
6616
                
6617
        case FlushedInt52:
6618
            return ExitValue::inJSStackAsInt52(flush.virtualRegister());
6619
                
6620
        case FlushedDouble:
6621
            return ExitValue::inJSStackAsDouble(flush.virtualRegister());
6622
                
6623
        case FlushedArguments:
6624
            return ExitValue::argumentsObjectThatWasNotCreated();
6625
        }
6626
        
6627
        DFG_CRASH(m_graph, m_node, "Invalid flush format");
6628
    }
6629
    
6630
    ExitValue exitValueForNode(
6631
        ExitArgumentList& arguments, const HashMap<Node*, ExitTimeObjectMaterialization*>& map,
6632
        Node* node)
6463
    {
6633
    {
6464
        ASSERT(node->shouldGenerate());
6634
        ASSERT(node->shouldGenerate());
6465
        ASSERT(node->hasResult());
6635
        ASSERT(node->hasResult());
6466
6636
6467
        if (node) {
6637
        if (node) {
6468
            switch (node->op()) {
6638
            switch (node->op()) {
6639
            case BottomValue:
6640
                // This might arise in object materializations. I actually doubt that it would,
6641
                // but it seems worthwhile to be conservative.
6642
                return ExitValue::dead();
6643
                
6469
            case JSConstant:
6644
            case JSConstant:
6470
            case Int52Constant:
6645
            case Int52Constant:
6471
            case DoubleConstant:
6646
            case DoubleConstant:
Lines 6474-6479 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec20
6474
            case PhantomArguments:
6649
            case PhantomArguments:
6475
                return ExitValue::argumentsObjectThatWasNotCreated();
6650
                return ExitValue::argumentsObjectThatWasNotCreated();
6476
                
6651
                
6652
            case PhantomNewObject:
6653
                return ExitValue::materializeNewObject(map.get(node));
6654
                
6477
            default:
6655
            default:
6478
                break;
6656
                break;
6479
            }
6657
            }
Lines 6721-6727 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec21
6721
        m_out.unreachable();
6899
        m_out.unreachable();
6722
    }
6900
    }
6723
    
6901
    
6724
    Operands<Availability>& availability() { return m_availabilityCalculator.m_availability; }
6902
    AvailabilityMap& availabilityMap() { return m_availabilityCalculator.m_availability; }
6725
    
6903
    
6726
    VM& vm() { return m_graph.m_vm; }
6904
    VM& vm() { return m_graph.m_vm; }
6727
    CodeBlock* codeBlock() { return m_graph.m_codeBlock; }
6905
    CodeBlock* codeBlock() { return m_graph.m_codeBlock; }
- Source/JavaScriptCore/ftl/FTLOSRExit.h -1 / +3 lines
Lines 1-5 Source/JavaScriptCore/ftl/FTLOSRExit.h_sec1
1
/*
1
/*
2
 * Copyright (C) 2013 Apple Inc. All rights reserved.
2
 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
3
 *
3
 *
4
 * Redistribution and use in source and binary forms, with or without
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
5
 * modification, are permitted provided that the following conditions
Lines 33-38 Source/JavaScriptCore/ftl/FTLOSRExit.h_sec2
33
#include "DFGOSRExitBase.h"
33
#include "DFGOSRExitBase.h"
34
#include "FTLAbbreviations.h"
34
#include "FTLAbbreviations.h"
35
#include "FTLExitArgumentList.h"
35
#include "FTLExitArgumentList.h"
36
#include "FTLExitTimeObjectMaterialization.h"
36
#include "FTLExitValue.h"
37
#include "FTLExitValue.h"
37
#include "FTLFormattedValue.h"
38
#include "FTLFormattedValue.h"
38
#include "MethodOfGettingAValueProfile.h"
39
#include "MethodOfGettingAValueProfile.h"
Lines 160-165 struct OSRExit : public DFG::OSRExitBase Source/JavaScriptCore/ftl/FTLOSRExit.h_sec3
160
    unsigned m_patchableCodeOffset;
161
    unsigned m_patchableCodeOffset;
161
    
162
    
162
    Operands<ExitValue> m_values;
163
    Operands<ExitValue> m_values;
164
    Bag<ExitTimeObjectMaterialization> m_materializations;
163
    
165
    
164
    uint32_t m_stackmapID;
166
    uint32_t m_stackmapID;
165
    
167
    
- Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp -76 / +169 lines
Lines 33-38 Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp_sec1
33
#include "FTLExitArgumentForOperand.h"
33
#include "FTLExitArgumentForOperand.h"
34
#include "FTLJITCode.h"
34
#include "FTLJITCode.h"
35
#include "FTLOSRExit.h"
35
#include "FTLOSRExit.h"
36
#include "FTLOperations.h"
36
#include "FTLState.h"
37
#include "FTLState.h"
37
#include "FTLSaveRestore.h"
38
#include "FTLSaveRestore.h"
38
#include "LinkBuffer.h"
39
#include "LinkBuffer.h"
Lines 46-51 namespace JSC { namespace FTL { Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp_sec2
46
47
47
using namespace DFG;
48
using namespace DFG;
48
49
50
static void compileRecovery(
51
    CCallHelpers& jit, const ExitValue& value, StackMaps::Record* record, StackMaps& stackmaps,
52
    char *registerScratch,
53
    const HashMap<ExitTimeObjectMaterialization*, EncodedJSValue*>& materializationToPointer)
54
{
55
    switch (value.kind()) {
56
    case ExitValueDead:
57
        jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsUndefined())), GPRInfo::regT0);
58
        break;
59
            
60
    case ExitValueConstant:
61
        jit.move(MacroAssembler::TrustedImm64(JSValue::encode(value.constant())), GPRInfo::regT0);
62
        break;
63
            
64
    case ExitValueArgument:
65
        record->locations[value.exitArgument().argument()].restoreInto(
66
            jit, stackmaps, registerScratch, GPRInfo::regT0);
67
        break;
68
            
69
    case ExitValueInJSStack:
70
    case ExitValueInJSStackAsInt32:
71
    case ExitValueInJSStackAsInt52:
72
    case ExitValueInJSStackAsDouble:
73
        jit.load64(AssemblyHelpers::addressFor(value.virtualRegister()), GPRInfo::regT0);
74
        break;
75
            
76
    case ExitValueArgumentsObjectThatWasNotCreated:
77
        // We can't actually recover this yet, but we can make the stack look sane. This is
78
        // a prerequisite to running the actual arguments recovery.
79
        jit.move(MacroAssembler::TrustedImm64(JSValue::encode(JSValue())), GPRInfo::regT0);
80
        break;
81
            
82
    case ExitValueRecovery:
83
        record->locations[value.rightRecoveryArgument()].restoreInto(
84
            jit, stackmaps, registerScratch, GPRInfo::regT1);
85
        record->locations[value.leftRecoveryArgument()].restoreInto(
86
            jit, stackmaps, registerScratch, GPRInfo::regT0);
87
        switch (value.recoveryOpcode()) {
88
        case AddRecovery:
89
            switch (value.recoveryFormat()) {
90
            case ValueFormatInt32:
91
                jit.add32(GPRInfo::regT1, GPRInfo::regT0);
92
                break;
93
            case ValueFormatInt52:
94
                jit.add64(GPRInfo::regT1, GPRInfo::regT0);
95
                break;
96
            default:
97
                RELEASE_ASSERT_NOT_REACHED();
98
                break;
99
            }
100
            break;
101
        case SubRecovery:
102
            switch (value.recoveryFormat()) {
103
            case ValueFormatInt32:
104
                jit.sub32(GPRInfo::regT1, GPRInfo::regT0);
105
                break;
106
            case ValueFormatInt52:
107
                jit.sub64(GPRInfo::regT1, GPRInfo::regT0);
108
                break;
109
            default:
110
                RELEASE_ASSERT_NOT_REACHED();
111
                break;
112
            }
113
            break;
114
        default:
115
            RELEASE_ASSERT_NOT_REACHED();
116
            break;
117
        }
118
        break;
119
        
120
    case ExitValueMaterializeNewObject:
121
        jit.loadPtr(materializationToPointer.get(value.objectMaterialization()), GPRInfo::regT0);
122
        break;
123
            
124
    default:
125
        RELEASE_ASSERT_NOT_REACHED();
126
        break;
127
    }
128
        
129
    reboxAccordingToFormat(
130
        value.valueFormat(), jit, GPRInfo::regT0, GPRInfo::regT1, GPRInfo::regT2);
131
}
132
49
static void compileStub(
133
static void compileStub(
50
    unsigned exitID, JITCode* jitCode, OSRExit& exit, VM* vm, CodeBlock* codeBlock)
134
    unsigned exitID, JITCode* jitCode, OSRExit& exit, VM* vm, CodeBlock* codeBlock)
51
{
135
{
Lines 64-76 static void compileStub( Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp_sec3
64
148
65
    CCallHelpers jit(vm, codeBlock);
149
    CCallHelpers jit(vm, codeBlock);
66
    
150
    
67
    // We need scratch space to save all registers and to build up the JSStack.
151
    // We need scratch space to save all registers, to build up the JS stack, to deal with unwind
68
    // Use a scratch buffer to transfer all values.
152
    // fixup, pointers to all of the objects we materialize, and the elements inside those objects
69
    ScratchBuffer* scratchBuffer = vm->scratchBufferForSize(sizeof(EncodedJSValue) * exit.m_values.size() + requiredScratchMemorySizeInBytes() + jitCode->unwindInfo.m_registers.size() * sizeof(uint64_t));
153
    // that we materialize.
154
    
155
    // Figure out how much space we need for those object allocations.
156
    unsigned numMaterializations = 0;
157
    size_t maxMaterializationNumArguments = 0;
158
    for (ExitTimeObjectMaterialization* materialization : exit.m_materializations) {
159
        numMaterializations++;
160
        
161
        maxMaterializationNumArguments = std::max(
162
            maxMaterializationNumArguments,
163
            materialization->properties().size());
164
    }
165
    
166
    ScratchBuffer* scratchBuffer = vm->scratchBufferForSize(
167
        sizeof(EncodedJSValue) * (
168
            exit.m_values.size() + numMaterializations + maxMaterializationNumArguments) +
169
        requiredScratchMemorySizeInBytes() +
170
        jitCode->unwindInfo.m_registers.size() * sizeof(uint64_t));
70
    EncodedJSValue* scratch = scratchBuffer ? static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) : 0;
171
    EncodedJSValue* scratch = scratchBuffer ? static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) : 0;
71
    char* registerScratch = bitwise_cast<char*>(scratch + exit.m_values.size());
172
    EncodedJSValue* materializationPointers = scratch + exit.m_values.size();
173
    EncodedJSValue* materializationArguments = materializationPointers + numMaterializations;
174
    char* registerScratch = bitwise_cast<char*>(materializationArguments + maxMaterializationNumArguments);
72
    uint64_t* unwindScratch = bitwise_cast<uint64_t*>(registerScratch + requiredScratchMemorySizeInBytes());
175
    uint64_t* unwindScratch = bitwise_cast<uint64_t*>(registerScratch + requiredScratchMemorySizeInBytes());
73
    
176
    
177
    HashMap<ExitTimeObjectMaterialization*, EncodedJSValue*> materializationToPointer;
178
    unsigned materializationCount = 0;
179
    for (ExitTimeObjectMaterialization* materialization : exit.m_materializations) {
180
        materializationToPointer.add(
181
            materialization, materializationPointers + materializationCount++);
182
    }
183
    
74
    // Note that we come in here, the stack used to be as LLVM left it except that someone called pushToSave().
184
    // Note that we come in here, the stack used to be as LLVM left it except that someone called pushToSave().
75
    // We don't care about the value they saved. But, we do appreciate the fact that they did it, because we use
185
    // We don't care about the value they saved. But, we do appreciate the fact that they did it, because we use
76
    // that slot for saveAllRegisters().
186
    // that slot for saveAllRegisters().
Lines 120-205 static void compileStub( Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp_sec4
120
        if (!!exit.m_valueProfile)
230
        if (!!exit.m_valueProfile)
121
            jit.store64(GPRInfo::regT0, exit.m_valueProfile.getSpecFailBucket(0));
231
            jit.store64(GPRInfo::regT0, exit.m_valueProfile.getSpecFailBucket(0));
122
    }
232
    }
123
124
    // Save all state from wherever the exit data tells us it was, into the appropriate place in
125
    // the scratch buffer. This also does the reboxing.
126
    
233
    
127
    for (unsigned index = exit.m_values.size(); index--;) {
234
    // Materialize all objects. Don't materialize an object until all of the objects it needs
128
        ExitValue value = exit.m_values[index];
235
    // have been materialized.
236
    HashSet<ExitTimeObjectMaterialization*> toMaterialize;
237
    for (ExitTimeObjectMaterialization* materialization : exit.m_materializations)
238
        toMaterialize.add(materialization);
239
    
240
    while (!toMaterialize.isEmpty()) {
241
        int previousToMaterializeSize = toMaterialize.size();
129
        
242
        
130
        switch (value.kind()) {
243
        Vector<ExitTimeObjectMaterialization*> worklist;
131
        case ExitValueDead:
244
        worklist.appendRange(toMaterialize.begin(), toMaterialize.end());
132
            jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsUndefined())), GPRInfo::regT0);
245
        for (ExitTimeObjectMaterialization* materialization : worklist) {
133
            break;
246
            // Check if we can do anything about this right now.
134
            
247
            bool allGood = true;
135
        case ExitValueConstant:
248
            for (ExitPropertyValue value : materialization->properties()) {
136
            jit.move(MacroAssembler::TrustedImm64(JSValue::encode(value.constant())), GPRInfo::regT0);
249
                if (!value.value().isObjectMaterialization())
137
            break;
250
                    continue;
138
            
251
                if (toMaterialize.contains(value.value().objectMaterialization())) {
139
        case ExitValueArgument:
252
                    // Gotta skip this one, since one of its fields points to a materialization
140
            record->locations[value.exitArgument().argument()].restoreInto(
253
                    // that hasn't been materialized.
141
                jit, jitCode->stackmaps, registerScratch, GPRInfo::regT0);
254
                    allGood = false;
142
            break;
143
            
144
        case ExitValueInJSStack:
145
        case ExitValueInJSStackAsInt32:
146
        case ExitValueInJSStackAsInt52:
147
        case ExitValueInJSStackAsDouble:
148
            jit.load64(AssemblyHelpers::addressFor(value.virtualRegister()), GPRInfo::regT0);
149
            break;
150
            
151
        case ExitValueArgumentsObjectThatWasNotCreated:
152
            // We can't actually recover this yet, but we can make the stack look sane. This is
153
            // a prerequisite to running the actual arguments recovery.
154
            jit.move(MacroAssembler::TrustedImm64(JSValue::encode(JSValue())), GPRInfo::regT0);
155
            break;
156
            
157
        case ExitValueRecovery:
158
            record->locations[value.rightRecoveryArgument()].restoreInto(
159
                jit, jitCode->stackmaps, registerScratch, GPRInfo::regT1);
160
            record->locations[value.leftRecoveryArgument()].restoreInto(
161
                jit, jitCode->stackmaps, registerScratch, GPRInfo::regT0);
162
            switch (value.recoveryOpcode()) {
163
            case AddRecovery:
164
                switch (value.recoveryFormat()) {
165
                case ValueFormatInt32:
166
                    jit.add32(GPRInfo::regT1, GPRInfo::regT0);
167
                    break;
168
                case ValueFormatInt52:
169
                    jit.add64(GPRInfo::regT1, GPRInfo::regT0);
170
                    break;
171
                default:
172
                    RELEASE_ASSERT_NOT_REACHED();
173
                    break;
174
                }
175
                break;
176
            case SubRecovery:
177
                switch (value.recoveryFormat()) {
178
                case ValueFormatInt32:
179
                    jit.sub32(GPRInfo::regT1, GPRInfo::regT0);
180
                    break;
181
                case ValueFormatInt52:
182
                    jit.sub64(GPRInfo::regT1, GPRInfo::regT0);
183
                    break;
184
                default:
185
                    RELEASE_ASSERT_NOT_REACHED();
186
                    break;
255
                    break;
187
                }
256
                }
188
                break;
189
            default:
190
                RELEASE_ASSERT_NOT_REACHED();
191
                break;
192
            }
257
            }
193
            break;
258
            if (!allGood)
259
                continue;
194
            
260
            
195
        default:
261
            // All systems go for materializing the object. First we recover the values of all of
196
            RELEASE_ASSERT_NOT_REACHED();
262
            // its fields and then we call a function to actually allocate the beast.
197
            break;
263
            for (unsigned propertyIndex = materialization->properties().size(); propertyIndex--;) {
264
                const ExitValue& value = materialization->properties()[propertyIndex].value();
265
                compileRecovery(
266
                    jit, value, record, jitCode->stackmaps, registerScratch,
267
                    materializationToPointer);
268
                jit.storePtr(GPRInfo::regT0, materializationArguments + propertyIndex);
269
            }
270
            
271
            // This call assumes that we don't pass arguments on the stack.
272
            jit.setupArgumentsWithExecState(
273
                CCallHelpers::TrustedImmPtr(materialization),
274
                CCallHelpers::TrustedImmPtr(materializationArguments));
275
            jit.move(CCallHelpers::TrustedImmPtr(bitwise_cast<void*>(operationMaterializeObjectInOSR)), GPRInfo::nonArgGPR0);
276
            jit.call(GPRInfo::nonArgGPR0);
277
            jit.storePtr(GPRInfo::returnValueGPR, materializationToPointer.get(materialization));
278
            
279
            // Let everyone know that we're done.
280
            toMaterialize.remove(materialization);
198
        }
281
        }
199
        
282
        
200
        reboxAccordingToFormat(
283
        // We expect progress! This ensures that we crash rather than looping infinitely if there
201
            value.valueFormat(), jit, GPRInfo::regT0, GPRInfo::regT1, GPRInfo::regT2);
284
        // is something broken about this fixpoint. Or, this could happen if we ever violate the
202
        
285
        // "materializations form a DAG" rule.
286
        RELEASE_ASSERT(toMaterialize.size() < previousToMaterializeSize);
287
    }
288
289
    // Save all state from wherever the exit data tells us it was, into the appropriate place in
290
    // the scratch buffer. This also does the reboxing.
291
    
292
    for (unsigned index = exit.m_values.size(); index--;) {
293
        compileRecovery(
294
            jit, exit.m_values[index], record, jitCode->stackmaps, registerScratch,
295
            materializationToPointer);
203
        jit.store64(GPRInfo::regT0, scratch + index);
296
        jit.store64(GPRInfo::regT0, scratch + index);
204
    }
297
    }
205
    
298
    
- Source/JavaScriptCore/ftl/FTLOperations.cpp +96 lines
Line 0 Source/JavaScriptCore/ftl/FTLOperations.cpp_sec1
1
/*
2
 * Copyright (C) 2014 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 "FTLOperations.h"
28
29
#if ENABLE(FTL_JIT)
30
31
namespace JSC { namespace FTL {
32
33
using namespace JSC::DFG;
34
35
extern "C" JSCell* JIT_OPERATION operationNewObjectWithButterfly(ExecState* exec, Structure* structure)
36
{
37
    VM& vm = exec->vm();
38
    NativeCallFrameTracer tracer(&vm, exec);
39
    
40
    Butterfly* butterfly = Butterfly::create(
41
        vm, nullptr, 0, structure->outOfLineCapacity(), false, IndexingHeader(), 0);
42
    
43
    return JSFinalObject::create(exec, structure, butterfly);
44
}
45
46
extern "C" JSCell* JIT_OPERATION operationMaterializeObjectInOSR(
47
    ExecState* exec, ExitTimeObjectMaterialization* materialization, EncodedJSValue* values)
48
{
49
    VM& vm = exec->vm();
50
    CodeBlock* codeBlock = exec->codeBlock();
51
52
    // We cannot GC. We've got pointers in evil places.
53
    DeferGCForAWhile deferGC(vm.heap);
54
    
55
    // In the future, we may have many different kinds of materializations. For now we just
56
    // materialize NewObject.
57
    RELEASE_ASSERT(materialization->type() == PhantomNewObject);
58
    
59
    // First figure out what the structure is.
60
    Structure* structure = nullptr;
61
    for (unsigned i = materialization->properties().size(); i--;) {
62
        const ExitPropertyValue& property = materialization->properties()[i];
63
        if (property.location() != PromotedLocationDescriptor(StructurePLoc))
64
            continue;
65
        
66
        structure = jsCast<Structure*>(JSValue::decode(values[i]));
67
    }
68
    RELEASE_ASSERT(structure);
69
    
70
    // Let's create that object!
71
    JSFinalObject* result = JSFinalObject::create(vm, structure);
72
    
73
    // Now figure out what the heck to populate the object with. Use getPropertiesConcurrently()
74
    // because that happens to be lower-level and more convenient. It doesn't change the
75
    // materialization of the property table. We want to have minimal visible effects on the
76
    // system. Also, don't mind that this is O(n^2). It doesn't matter. We only get here from OSR
77
    // exit.
78
    for (PropertyMapEntry entry : structure->getPropertiesConcurrently()) {
79
        for (unsigned i = materialization->properties().size(); i--;) {
80
            const ExitPropertyValue& property = materialization->properties()[i];
81
            if (property.location().kind() != NamedPropertyPLoc)
82
                continue;
83
            if (codeBlock->identifier(property.location().info()).impl() != entry.key)
84
                continue;
85
            
86
            result->putDirect(vm, entry.offset, JSValue::decode(values[i]));
87
        }
88
    }
89
    
90
    return result;
91
}
92
93
} } // namespace JSC::FTL
94
95
#endif // ENABLE(FTL_JIT)
96
- Source/JavaScriptCore/ftl/FTLOperations.h +50 lines
Line 0 Source/JavaScriptCore/ftl/FTLOperations.h_sec1
1
/*
2
 * Copyright (C) 2014 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 FTLOperations_h
27
#define FTLOperations_h
28
29
#if ENABLE(FTL_JIT)
30
31
#include "DFGOperations.h"
32
#include "FTLExitTimeObjectMaterialization.h"
33
34
namespace JSC { namespace FTL {
35
36
extern "C" {
37
38
JSCell* JIT_OPERATION operationNewObjectWithButterfly(ExecState*, Structure* structure) WTF_INTERNAL;
39
40
JSCell* JIT_OPERATION operationMaterializeObjectInOSR(
41
    ExecState*, ExitTimeObjectMaterialization*, EncodedJSValue*) WTF_INTERNAL;
42
43
} // extern "C"
44
45
} } // namespace JSC::DFG
46
47
#endif // ENABLE(FTL_JIT)
48
49
#endif // FTLOperations_h
50
- Source/JavaScriptCore/ftl/FTLSwitchCase.h +6 lines
Lines 35-40 namespace JSC { namespace FTL { Source/JavaScriptCore/ftl/FTLSwitchCase.h_sec1
35
35
36
class SwitchCase {
36
class SwitchCase {
37
public:
37
public:
38
    SwitchCase()
39
        : m_value(nullptr)
40
        , m_target(nullptr)
41
    {
42
    }
43
38
    SwitchCase(LValue value, LBasicBlock target, Weight weight)
44
    SwitchCase(LValue value, LBasicBlock target, Weight weight)
39
        : m_value(value)
45
        : m_value(value)
40
        , m_target(target)
46
        , m_target(target)
- Source/JavaScriptCore/runtime/JSObject.h -5 / +6 lines
Lines 1052-1058 public: Source/JavaScriptCore/runtime/JSObject.h_sec1
1052
        return (maxSize - allocationSize(0)) / sizeof(WriteBarrier<Unknown>);
1052
        return (maxSize - allocationSize(0)) / sizeof(WriteBarrier<Unknown>);
1053
    }
1053
    }
1054
1054
1055
    static JSFinalObject* create(ExecState*, Structure*);
1055
    static JSFinalObject* create(ExecState*, Structure*, Butterfly* = nullptr);
1056
    static JSFinalObject* create(VM&, Structure*);
1056
    static JSFinalObject* create(VM&, Structure*);
1057
    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype, unsigned inlineCapacity)
1057
    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype, unsigned inlineCapacity)
1058
    {
1058
    {
Lines 1076-1090 protected: Source/JavaScriptCore/runtime/JSObject.h_sec2
1076
private:
1076
private:
1077
    friend class LLIntOffsetsExtractor;
1077
    friend class LLIntOffsetsExtractor;
1078
1078
1079
    explicit JSFinalObject(VM& vm, Structure* structure)
1079
    explicit JSFinalObject(VM& vm, Structure* structure, Butterfly* butterfly = nullptr)
1080
        : JSObject(vm, structure)
1080
        : JSObject(vm, structure, butterfly)
1081
    {
1081
    {
1082
    }
1082
    }
1083
1083
1084
    static const unsigned StructureFlags = JSObject::StructureFlags;
1084
    static const unsigned StructureFlags = JSObject::StructureFlags;
1085
};
1085
};
1086
1086
1087
inline JSFinalObject* JSFinalObject::create(ExecState* exec, Structure* structure)
1087
inline JSFinalObject* JSFinalObject::create(
1088
    ExecState* exec, Structure* structure, Butterfly* butterfly)
1088
{
1089
{
1089
    JSFinalObject* finalObject = new (
1090
    JSFinalObject* finalObject = new (
1090
        NotNull, 
1091
        NotNull, 
Lines 1092-1098 inline JSFinalObject* JSFinalObject::cre Source/JavaScriptCore/runtime/JSObject.h_sec3
1092
            *exec->heap(),
1093
            *exec->heap(),
1093
            allocationSize(structure->inlineCapacity())
1094
            allocationSize(structure->inlineCapacity())
1094
        )
1095
        )
1095
    ) JSFinalObject(exec->vm(), structure);
1096
    ) JSFinalObject(exec->vm(), structure, butterfly);
1096
    finalObject->finishCreation(exec->vm());
1097
    finalObject->finishCreation(exec->vm());
1097
    return finalObject;
1098
    return finalObject;
1098
}
1099
}
- Source/JavaScriptCore/runtime/Structure.cpp +7 lines
Lines 1105-1110 PassRefPtr<StructureShape> Structure::to Source/JavaScriptCore/runtime/Structure.cpp_sec1
1105
    return baseShape.release();
1105
    return baseShape.release();
1106
}
1106
}
1107
1107
1108
bool Structure::canUseForAllocationsOf(Structure* other)
1109
{
1110
    return inlineCapacity() == other->inlineCapacity()
1111
        && storedPrototype() == other->storedPrototype()
1112
        && objectInitializationBlob() == other->objectInitializationBlob();
1113
}
1114
1108
void Structure::dump(PrintStream& out) const
1115
void Structure::dump(PrintStream& out) const
1109
{
1116
{
1110
    out.print(RawPointer(this), ":[", classInfo()->className, ", {");
1117
    out.print(RawPointer(this), ":[", classInfo()->className, ", {");
- Source/JavaScriptCore/runtime/Structure.h +4 lines
Lines 433-438 public: Source/JavaScriptCore/runtime/Structure.h_sec1
433
433
434
    PassRefPtr<StructureShape> toStructureShape(JSValue);
434
    PassRefPtr<StructureShape> toStructureShape(JSValue);
435
    
435
    
436
    // Determines if the two structures match enough that this one could be used for allocations
437
    // of the other one.
438
    bool canUseForAllocationsOf(Structure*);
439
    
436
    void dump(PrintStream&) const;
440
    void dump(PrintStream&) const;
437
    void dumpInContext(PrintStream&, DumpContext*) const;
441
    void dumpInContext(PrintStream&, DumpContext*) const;
438
    void dumpBrief(PrintStream&, const CString&) const;
442
    void dumpBrief(PrintStream&, const CString&) const;
- Source/WTF/ChangeLog +14 lines
Lines 1-3 Source/WTF/ChangeLog_sec1
1
2014-09-22  Filip Pizlo  <fpizlo@apple.com>
2
3
        FTL should sink object allocations
4
        https://bugs.webkit.org/show_bug.cgi?id=136330
5
6
        Reviewed by NOBODY (OOPS!).
7
        
8
        Make it possible to reset a Bag.
9
10
        * wtf/Bag.h:
11
        (WTF::Bag::Bag):
12
        (WTF::Bag::~Bag):
13
        (WTF::Bag::clear):
14
1
2014-09-22  Sam Weinig  <sam@webkit.org>
15
2014-09-22  Sam Weinig  <sam@webkit.org>
2
16
3
        Eliminate redundant PtrHash specializations
17
        Eliminate redundant PtrHash specializations
- Source/WTF/wtf/Bag.h -1 / +7 lines
Lines 46-62 private: Source/WTF/wtf/Bag.h_sec1
46
    
46
    
47
public:
47
public:
48
    Bag()
48
    Bag()
49
        : m_head(0)
49
        : m_head(nullptr)
50
    {
50
    {
51
    }
51
    }
52
    
52
    
53
    ~Bag()
53
    ~Bag()
54
    {
54
    {
55
        clear();
56
    }
57
    
58
    void clear()
59
    {
55
        while (m_head) {
60
        while (m_head) {
56
            Node* current = m_head;
61
            Node* current = m_head;
57
            m_head = current->m_next;
62
            m_head = current->m_next;
58
            delete current;
63
            delete current;
59
        }
64
        }
65
        m_head = nullptr;
60
    }
66
    }
61
    
67
    
62
    template<typename... Args>
68
    template<typename... Args>
- LayoutTests/js/math-denorm.html +10 lines
Line 0 LayoutTests/js/math-denorm.html_sec1
1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
2
<html>
3
<head>
4
<script src="resources/js-test-pre.js"></script>
5
</head>
6
<body>
7
<script src="script-tests/math-denorm.js"></script>
8
<script src="resources/js-test-post.js"></script>
9
</body>
10
</html>
- LayoutTests/js/regress/obviously-elidable-new-object-expected.txt +10 lines
Line 0 LayoutTests/js/regress/obviously-elidable-new-object-expected.txt_sec1
1
JSRegress/obviously-elidable-new-object
2
3
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
4
5
6
PASS no exception thrown
7
PASS successfullyParsed is true
8
9
TEST COMPLETE
10
- LayoutTests/js/regress/obviously-elidable-new-object.html +12 lines
Line 0 LayoutTests/js/regress/obviously-elidable-new-object.html_sec1
1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
2
<html>
3
<head>
4
<script src="../../resources/js-test-pre.js"></script>
5
</head>
6
<body>
7
<script src="../../resources/regress-pre.js"></script>
8
<script src="script-tests/obviously-elidable-new-object.js"></script>
9
<script src="../../resources/regress-post.js"></script>
10
<script src="../../resources/js-test-post.js"></script>
11
</body>
12
</html>
- LayoutTests/js/regress/script-tests/obviously-elidable-new-object.js +19 lines
Line 0 LayoutTests/js/regress/script-tests/obviously-elidable-new-object.js_sec1
1
function sumOfArithSeries(limit) {
2
    return limit * (limit + 1) / 2;
3
}
4
5
var n = 100000000;
6
7
function foo() {
8
    var result = 0;
9
    for (var i = 0; i < n; ++i) {
10
        var o = {f: i};
11
        var p = {f: i + 1};
12
        result += o.f + p.f;
13
    }
14
    return result;
15
}
16
17
var result = foo();
18
if (result != sumOfArithSeries(n - 1) + sumOfArithSeries(n))
19
    throw "Error: bad result: " + result;

Return to Bug 136330