| 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 +4 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 146-151 public: Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h_sec2
146
    FiltrationResult filter(AbstractValue&, SpeculatedType);
147
    FiltrationResult filter(AbstractValue&, SpeculatedType);
147
    FiltrationResult filterByValue(AbstractValue&, FrozenValue);
148
    FiltrationResult filterByValue(AbstractValue&, FrozenValue);
148
    
149
    
150
    PhiChildren* phiChildren() { return m_phiChildren.get(); }
151
    
149
private:
152
private:
150
    void clobberWorld(const CodeOrigin&, unsigned indexInBlock);
153
    void clobberWorld(const CodeOrigin&, unsigned indexInBlock);
151
    void clobberCapturedVars(const CodeOrigin&);
154
    void clobberCapturedVars(const CodeOrigin&);
Lines 195-200 private: Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h_sec3
195
    CodeBlock* m_codeBlock;
198
    CodeBlock* m_codeBlock;
196
    Graph& m_graph;
199
    Graph& m_graph;
197
    AbstractStateType& m_state;
200
    AbstractStateType& m_state;
201
    std::unique_ptr<PhiChildren> m_phiChildren;
198
};
202
};
199
203
200
} } // namespace JSC::DFG
204
} } // namespace JSC::DFG
- Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h -1 / +69 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 1260-1265 bool AbstractInterpreter<AbstractStateTy Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h_sec2
1260
        forNode(node).set(m_graph, node->structure());
1262
        forNode(node).set(m_graph, node->structure());
1261
        break;
1263
        break;
1262
        
1264
        
1265
    case PhantomNewObject:
1266
        m_state.setDidClobber(true); // Prevent constant folding.
1267
        break;
1268
        
1269
    case PutByOffsetHint:
1270
    case PutStructureHint:
1271
        break;
1272
        
1273
    case MaterializeNewObject: {
1274
        StructureSet set;
1275
        
1276
        m_phiChildren->forAllTransitiveIncomingValues(
1277
            m_graph.varArgChild(node, 0).node(),
1278
            [&] (Node* incoming) {
1279
                Structure* structure = incoming->dynamicCastConstant<Structure*>();
1280
                DFG_ASSERT(m_graph, node, structure);
1281
                set.add(structure);
1282
            });
1283
        
1284
        forNode(node).set(m_graph, set);
1285
        break;
1286
    }
1287
        
1263
    case CreateActivation:
1288
    case CreateActivation:
1264
        forNode(node).set(
1289
        forNode(node).set(
1265
            m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->activationStructure());
1290
            m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->activationStructure());
Lines 1459-1465 bool AbstractInterpreter<AbstractStateTy Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h_sec3
1459
        break;
1484
        break;
1460
        
1485
        
1461
    case CheckStructure: {
1486
    case CheckStructure: {
1462
        // FIXME: We should be able to propagate the structure sets of constants (i.e. prototypes).
1463
        AbstractValue& value = forNode(node->child1());
1487
        AbstractValue& value = forNode(node->child1());
1464
        ASSERT(!(value.m_type & ~SpecCell)); // Edge filtering should have already ensured this.
1488
        ASSERT(!(value.m_type & ~SpecCell)); // Edge filtering should have already ensured this.
1465
1489
Lines 1478-1483 bool AbstractInterpreter<AbstractStateTy Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h_sec4
1478
        break;
1502
        break;
1479
    }
1503
    }
1480
        
1504
        
1505
    case CheckStructureImmediate: {
1506
        // FIXME: This currently can only reason about one structure at a time.
1507
        // https://bugs.webkit.org/show_bug.cgi?id=136988
1508
        
1509
        AbstractValue& value = forNode(node->child1());
1510
        StructureSet& set = node->structureSet();
1511
        
1512
        if (value.value()) {
1513
            if (Structure* structure = jsDynamicCast<Structure*>(value.value())) {
1514
                if (set.contains(structure)) {
1515
                    m_state.setFoundConstants(true);
1516
                    break;
1517
                }
1518
            }
1519
            m_state.setIsValid(false);
1520
            break;
1521
        }
1522
        
1523
        if (m_phiChildren) {
1524
            bool allGood = true;
1525
            m_phiChildren->forAllTransitiveIncomingValues(
1526
                node,
1527
                [&] (Node* incoming) {
1528
                    if (Structure* structure = incoming->dynamicCastConstant<Structure*>()) {
1529
                        if (set.contains(structure))
1530
                            return;
1531
                    }
1532
                    allGood = false;
1533
                });
1534
            if (allGood) {
1535
                m_state.setFoundConstants(true);
1536
                break;
1537
            }
1538
        }
1539
            
1540
        if (Structure* structure = set.onlyStructure()) {
1541
            filterByValue(node->child1(), *m_graph.freeze(structure));
1542
            break;
1543
        }
1544
        
1545
        // Aw shucks, we can't do anything!
1546
        break;
1547
    }
1548
        
1481
    case PutStructure:
1549
    case PutStructure:
1482
        if (!forNode(node->child1()).m_structure.isClear()) {
1550
        if (!forNode(node->child1()).m_structure.isClear()) {
1483
            if (forNode(node->child1()).m_structure.onlyStructure() == node->transition()->next)
1551
            if (forNode(node->child1()).m_structure.onlyStructure() == node->transition()->next)
- 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 +95 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 <wtf/ListDump.h>
32
33
namespace JSC { namespace DFG {
34
35
void AvailabilityMap::prune()
36
{
37
    if (m_heap.isEmpty())
38
        return;
39
    
40
    HashSet<Node*> possibleNodes;
41
    
42
    for (unsigned i = m_locals.size(); i--;) {
43
        if (m_locals[i].hasNode())
44
            possibleNodes.add(m_locals[i].node());
45
    }
46
47
    int oldPossibleNodesSize;
48
    do {
49
        oldPossibleNodesSize = possibleNodes.size();
50
        for (auto pair : m_heap) {
51
            if (pair.value.hasNode() && possibleNodes.contains(pair.key.base()))
52
                possibleNodes.add(pair.value.node());
53
        }
54
    } while (oldPossibleNodesSize != possibleNodes.size());
55
    
56
    HashMap<PromotedHeapLocation, Availability> newHeap;
57
    for (auto pair : m_heap) {
58
        if (possibleNodes.contains(pair.key.base()))
59
            newHeap.add(pair.key, pair.value);
60
    }
61
    m_heap = newHeap;
62
}
63
64
void AvailabilityMap::clear()
65
{
66
    m_locals.fill(Availability());
67
    m_heap.clear();
68
}
69
70
void AvailabilityMap::dump(PrintStream& out) const
71
{
72
    out.print("{locals = ", m_locals, "; heap = ", mapDump(m_heap), "}");
73
}
74
75
bool AvailabilityMap::operator==(const AvailabilityMap& other) const
76
{
77
    return m_locals == other.m_locals
78
        && m_heap == other.m_heap;
79
}
80
81
void AvailabilityMap::merge(const AvailabilityMap& other)
82
{
83
    for (unsigned i = other.m_locals.size(); i--;)
84
        m_locals[i] = other.m_locals[i].merge(m_locals[i]);
85
    
86
    for (auto pair : other.m_heap) {
87
        auto result = m_heap.add(pair.key, Availability());
88
        result.iterator->value = pair.value.merge(result.iterator->value);
89
    }
90
}
91
92
} } // namespace JSC::DFG
93
94
#endif // ENABLE(DFG_JIT)
95
- 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/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 / +148 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);
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 doToChildEdges(Node* node, const ChildFunctor& functor)
808
    {
809
        doToChildrenWithNode(
810
            node,
811
            [&functor] (Node*, Edge& edge) {
812
                functor(edge);
813
            });
814
    }
815
    
816
    template<typename ChildFunctor>
817
    void doToChildren(Node* node, const ChildFunctor& functor)
818
    {
819
        doToChildrenWithNode(
820
            node,
821
            [&functor] (Node*, Edge edge) {
822
                functor(edge);
823
            });
824
    }
825
    
679
    Profiler::Compilation* compilation() { return m_plan.compilation.get(); }
826
    Profiler::Compilation* compilation() { return m_plan.compilation.get(); }
680
    
827
    
681
    DesiredIdentifiers& identifiers() { return m_plan.identifiers; }
828
    DesiredIdentifiers& identifiers() { return m_plan.identifiers; }
Lines 736-741 public: Source/JavaScriptCore/dfg/DFGGraph.h_sec4
736
    Bag<SwitchData> m_switchData;
883
    Bag<SwitchData> m_switchData;
737
    Bag<MultiGetByOffsetData> m_multiGetByOffsetData;
884
    Bag<MultiGetByOffsetData> m_multiGetByOffsetData;
738
    Bag<MultiPutByOffsetData> m_multiPutByOffsetData;
885
    Bag<MultiPutByOffsetData> m_multiPutByOffsetData;
886
    Bag<ObjectMaterializationData> m_objectMaterializationData;
739
    Vector<InlineVariableData, 4> m_inlineVariableData;
887
    Vector<InlineVariableData, 4> m_inlineVariableData;
740
    HashMap<CodeBlock*, std::unique_ptr<FullBytecodeLiveness>> m_bytecodeLiveness;
888
    HashMap<CodeBlock*, std::unique_ptr<FullBytecodeLiveness>> m_bytecodeLiveness;
741
    bool m_hasArguments;
889
    bool m_hasArguments;
Lines 786-832 private: Source/JavaScriptCore/dfg/DFGGraph.h_sec5
786
    }
934
    }
787
};
935
};
788
936
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
937
} } // namespace JSC::DFG
831
938
832
#endif
939
#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/DFGNode.h -2 / +61 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_op = PutByOffsetHint;
508
        m_opInfo = storageAccessData().identifierNumber;
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->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 704-709 struct Node { Source/JavaScriptCore/dfg/DFGNode.h_sec4
704
        case PutById:
734
        case PutById:
705
        case PutByIdFlush:
735
        case PutByIdFlush:
706
        case PutByIdDirect:
736
        case PutByIdDirect:
737
        case PutByOffsetHint:
707
            return true;
738
            return true;
708
        default:
739
        default:
709
            return false;
740
            return false;
Lines 1105-1110 struct Node { Source/JavaScriptCore/dfg/DFGNode.h_sec5
1105
    {
1136
    {
1106
        switch (op()) {
1137
        switch (op()) {
1107
        case PutStructure:
1138
        case PutStructure:
1139
        case PutStructureHint:
1108
        case AllocatePropertyStorage:
1140
        case AllocatePropertyStorage:
1109
        case ReallocatePropertyStorage:
1141
        case ReallocatePropertyStorage:
1110
            return true;
1142
            return true;
Lines 1155-1161 struct Node { Source/JavaScriptCore/dfg/DFGNode.h_sec6
1155
    
1187
    
1156
    bool hasStorageAccessData()
1188
    bool hasStorageAccessData()
1157
    {
1189
    {
1158
        return op() == GetByOffset || op() == GetGetterSetterByOffset || op() == PutByOffset;
1190
        switch (op()) {
1191
        case GetByOffset:
1192
        case PutByOffset:
1193
        case GetGetterSetterByOffset:
1194
            return true;
1195
        default:
1196
            return false;
1197
        }
1159
    }
1198
    }
1160
    
1199
    
1161
    StorageAccessData& storageAccessData()
1200
    StorageAccessData& storageAccessData()
Lines 1184-1189 struct Node { Source/JavaScriptCore/dfg/DFGNode.h_sec7
1184
        return *reinterpret_cast<MultiPutByOffsetData*>(m_opInfo);
1223
        return *reinterpret_cast<MultiPutByOffsetData*>(m_opInfo);
1185
    }
1224
    }
1186
    
1225
    
1226
    bool hasObjectMaterializationData()
1227
    {
1228
        return op() == MaterializeNewObject;
1229
    }
1230
    
1231
    ObjectMaterializationData& objectMaterializationData()
1232
    {
1233
        return *reinterpret_cast<ObjectMaterializationData*>(m_opInfo);
1234
    }
1235
    
1236
    bool isPhantomObjectAllocation()
1237
    {
1238
        switch (op()) {
1239
        case PhantomNewObject:
1240
            return true;
1241
        default:
1242
            return false;
1243
        }
1244
    }
1245
    
1187
    bool hasFunctionDeclIndex()
1246
    bool hasFunctionDeclIndex()
1188
    {
1247
    {
1189
        return op() == NewFunction
1248
        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 -1 / +2 lines
Lines 49-57 public: Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.h_sec1
49
    ~LocalOSRAvailabilityCalculator();
49
    ~LocalOSRAvailabilityCalculator();
50
    
50
    
51
    void beginBlock(BasicBlock*);
51
    void beginBlock(BasicBlock*);
52
    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*);
53
    void executeNode(Node*);
53
    
54
    
54
    Operands<Availability> m_availability;
55
    AvailabilityMap m_availability;
55
};
56
};
56
57
57
} } // namespace JSC::DFG
58
} } // namespace JSC::DFG
- Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp +730 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 "DFGClobberize.h"
33
#include "DFGGraph.h"
34
#include "DFGInsertOSRHintsForUpdate.h"
35
#include "DFGInsertionSet.h"
36
#include "DFGLivenessAnalysisPhase.h"
37
#include "DFGOSRAvailabilityAnalysisPhase.h"
38
#include "DFGPhase.h"
39
#include "DFGPromoteHeapAccess.h"
40
#include "DFGSSACalculator.h"
41
#include "JSCInlines.h"
42
43
namespace JSC { namespace DFG {
44
45
class ObjectAllocationSinkingPhase : public Phase {
46
public:
47
    ObjectAllocationSinkingPhase(Graph& graph)
48
        : Phase(graph, "object allocation sinking")
49
        , m_ssaCalculator(graph)
50
        , m_insertionSet(graph)
51
    {
52
    }
53
    
54
    bool run()
55
    {
56
        ASSERT(m_graph.m_fixpointState == FixpointNotConverged);
57
        
58
        // Logically we wish to consider every NewObject and sink it. However it's definitely not
59
        // profitable to sink a NewObject that will always escape. So, first we do a very simple
60
        // forward flow analysis that determines the set of NewObject nodes that have any chance
61
        // of benefiting from object allocation sinking. Then we fixpoint the following rules:
62
        //
63
        // - For each NewObject, we turn the original NewObject into a PhantomNewObject and then
64
        //   we insert MaterializeNewObject just before each escaping site. Note that Upsilons
65
        //   constitute escaping sites. Then we use forward flow to eliminate unnecessary cases of
66
        //   MaterializeNewObject. We use the SSACalculator to insert these materializations. If a
67
        //   Phi is ever created that has the PhantomNewObject as one of its kids, then we insert
68
        //   a MaterializeNewObject in front of it; this way we never have a Phi that is confused
69
        //   about whether or not it has the real object. We then turn each PutByOffset over a
70
        //   PhantomNewObject into a PutByOffsetHint.
71
        //
72
        // - We perform the same optimization for MaterializeNewObject. This allows us to cover
73
        //   cases where we had MaterializeNewObject flowing into a PutByOffsetHint.
74
        //
75
        // We could also add this rule:
76
        //
77
        // - If all of the Upsilons of a Phi have a MaterializeNewObject that isn't used by anyone
78
        //   else, then replace the Phi with the MaterializeNewObject.
79
        //
80
        //   FIXME: Implement this. Note that this totally doable but it requires some gnarly
81
        //   code, and to be effective the pruner needs to be aware of it. Currently any Upsilon
82
        //   is considered to be an escape even by the pruner, so it's unlikely that we'll see
83
        //   many cases of Phi over Materializations.
84
        //   https://bugs.webkit.org/show_bug.cgi?id=136927
85
        
86
        if (!performSinking())
87
            return false;
88
        
89
        while (performSinking()) { }
90
        
91
        return true;
92
    }
93
94
private:
95
    bool performSinking()
96
    {
97
        m_graph.computeRefCounts();
98
        performLivenessAnalysis(m_graph);
99
        performOSRAvailabilityAnalysis(m_graph);
100
        
101
        // We want to only do sinking for those things that would benefit. We use a rough
102
        // heuristic: if it's possible for an allocation to make it to a return without escaping,
103
        // then we assume that it's worth sinking. It's a simple forward flow problem.
104
        //
105
        // It just so happens that this forward flow problem also tells us where we would
106
        // materialize those nodes that we choose to sink.
107
        pruneSinkingCandidates();
108
        if (m_sinkCandidates.isEmpty())
109
            return false;
110
        
111
        // At this point we are committed to sinking the sinking candidates.
112
        determineMaterializationPoints();
113
        placeMaterializationPoints();
114
        lowerNonReadingOperationsOnPhantomAllocations();
115
        promoteSunkenFields();
116
        
117
        return true;
118
    }
119
    
120
    void pruneSinkingCandidates()
121
    {
122
        m_sinkCandidates.clear();
123
        BlockMap<HashSet<Node*>> sinkCandidatesAtHead(m_graph);
124
        BlockMap<HashSet<Node*>> sinkCandidatesAtTail(m_graph);
125
        
126
        bool changed;
127
        do {
128
            changed = false;
129
            for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
130
                HashSet<Node*> sinkCandidates = sinkCandidatesAtHead[block];
131
                for (Node* node : *block) {
132
                    handleNode(
133
                        node,
134
                        [&] () {
135
                            sinkCandidates.add(node);
136
                        },
137
                        [&] (Node* escapee) {
138
                            sinkCandidates.remove(escapee);
139
                        });
140
                }
141
                if (sinkCandidatesAtTail[block] == sinkCandidates)
142
                    continue;
143
                
144
                sinkCandidatesAtTail[block] = sinkCandidates;
145
                changed = true;
146
                
147
                for (BasicBlock* successorBlock : block->successors()) {
148
                    for (Node* sinkCandidate : sinkCandidates) {
149
                        if (!successorBlock->ssa->liveAtHead.contains(sinkCandidate))
150
                            continue;
151
                        sinkCandidatesAtHead[successorBlock].add(sinkCandidate);
152
                    }
153
                }
154
            }
155
        } while (changed);
156
        
157
        // A node is a sink candidate if it is in the sinkCandidatesAtTail of a block but not in
158
        // the liveAtTail of that same block.
159
        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
160
            for (Node* sinkCandidate : sinkCandidatesAtTail[block]) {
161
                if (!block->ssa->liveAtTail.contains(sinkCandidate))
162
                    m_sinkCandidates.add(sinkCandidate);
163
            }
164
        }
165
    }
166
    
167
    void determineMaterializationPoints()
168
    {
169
        // The premise of this pass is that if there exists a point in the program where some
170
        // path from a phantom allocation site to that point causes materialization, then *all*
171
        // paths cause materialization. This should mean that there are never any redundant
172
        // materializations.
173
        
174
        m_edgeToMaterializationPoint.clear();
175
        
176
        BlockMap<HashSet<Node*>> materializedAtHead;
177
        BlockMap<HashSet<Node*>> materializedAtTail;
178
        
179
        bool changed;
180
        do {
181
            changed = false;
182
            for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
183
                HashSet<Node*> materialized = materializedAtHead[block];
184
                for (Node* node : *block) {
185
                    handleNode(
186
                        node,
187
                        [&] () { },
188
                        [&] (Node* escapee) {
189
                            if (m_sinkCandidates.contains(escapee))
190
                                materialized.add(escapee);
191
                        });
192
                }
193
                
194
                if (materialized == materializedAtTail[block])
195
                    continue;
196
                
197
                changed = true;
198
                
199
                for (BasicBlock* successorBlock : block->successors()) {
200
                    for (Node* materializee : materialized) {
201
                        if (!successorBlock->ssa->liveAtHead.contains(materializee))
202
                            continue;
203
                        materializedAtHead[successorBlock].add(materializee);
204
                    }
205
                }
206
            }
207
        } while (changed);
208
        
209
        // A materialization edge exists at any point where a node escapes but hasn't been
210
        // materialized yet.
211
        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
212
            HashSet<Node*> materialized = materializedAtHead[block];
213
            for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
214
                Node* node = block->at(nodeIndex);
215
                
216
                handleNode(
217
                    node,
218
                    [&] () { },
219
                    [&] (Node* escapee) {
220
                        if (!m_sinkCandidates.contains(escapee))
221
                            return;
222
                        
223
                        if (!materialized.add(escapee).isNewEntry)
224
                            return;
225
                        
226
                        m_edgeToMaterializationPoint.add(
227
                            std::make_pair(node, escapee),
228
                            createMaterialize(escapee, node->origin));
229
                    });
230
            }
231
        }
232
    }
233
    
234
    void placeMaterializationPoints()
235
    {
236
        m_ssaCalculator.reset();
237
        
238
        HashMap<Node*, SSACalculator::Variable*> nodeToVariable;
239
        Vector<Node*> indexToNode;
240
        
241
        for (Node* node : m_sinkCandidates) {
242
            SSACalculator::Variable* variable = m_ssaCalculator.newVariable();
243
            nodeToVariable.add(node, variable);
244
            ASSERT(indexToNode.size() == variable->index());
245
            indexToNode.append(node);
246
        }
247
        
248
        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
249
            for (Node* node : *block) {
250
                if (SSACalculator::Variable* variable = nodeToVariable.get(node))
251
                    m_ssaCalculator.newDef(variable, block, node);
252
                
253
                m_graph.doToChildren(
254
                    node,
255
                    [&] (Edge edge) {
256
                        Node* materialize =
257
                            m_edgeToMaterializationPoint.get(std::make_pair(node, edge.node()));
258
                        if (!materialize)
259
                            return;
260
                        
261
                        m_ssaCalculator.newDef(
262
                            nodeToVariable.get(edge.node()), block, materialize);
263
                    });
264
            }
265
        }
266
        
267
        m_ssaCalculator.computePhis(
268
            [&] (SSACalculator::Variable* variable, BasicBlock* block) -> Node* {
269
                Node* allocation = indexToNode[variable->index()];
270
                if (!block->ssa->liveAtHead.contains(allocation))
271
                    return nullptr;
272
                
273
                Node* phiNode = m_graph.addNode(allocation->prediction(), Phi, NodeOrigin());
274
                phiNode->mergeFlags(NodeResultJS);
275
                return phiNode;
276
            });
277
        
278
        // Place Phis in the right places. Replace all uses of any allocation with the appropriate
279
        // materialization. Create the appropriate Upsilon nodes.
280
        LocalOSRAvailabilityCalculator availabilityCalculator;
281
        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
282
            HashMap<Node*, Node*> mapping;
283
            
284
            for (Node* candidate : block->ssa->liveAtHead) {
285
                SSACalculator::Variable* variable = nodeToVariable.get(candidate);
286
                if (!variable)
287
                    continue;
288
                
289
                SSACalculator::Def* def = m_ssaCalculator.reachingDefAtHead(block, variable);
290
                if (!def)
291
                    continue;
292
                
293
                mapping.add(indexToNode[variable->index()], def->value());
294
            }
295
            
296
            availabilityCalculator.beginBlock(block);
297
            for (SSACalculator::Def* phiDef : m_ssaCalculator.phisForBlock(block)) {
298
                m_insertionSet.insert(0, phiDef->value());
299
                
300
                Node* originalNode = indexToNode[phiDef->variable()->index()];
301
                insertOSRHintsForUpdate(
302
                    m_insertionSet, 0, availabilityCalculator.m_availability, originalNode,
303
                    phiDef->value());
304
305
                mapping.add(originalNode, phiDef->value());
306
            }
307
            
308
            for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
309
                Node* node = block->at(nodeIndex);
310
311
                m_graph.doToChildEdges(
312
                    node,
313
                    [&] (Edge edge) {
314
                        Node* materialize = m_edgeToMaterializationPoint.get(
315
                            std::make_pair(node, edge.node()));
316
                        if (materialize) {
317
                            m_insertionSet.insert(nodeIndex, materialize);
318
                            insertOSRHintsForUpdate(
319
                                m_insertionSet, nodeIndex, availabilityCalculator.m_availability,
320
                                edge.node(), materialize);
321
                        }
322
                    });
323
324
                availabilityCalculator.executeNode(node);
325
                
326
                m_graph.doToChildEdges(
327
                    node,
328
                    [&] (Edge& edge) {
329
                        if (Node* materialize = mapping.get(edge.node()))
330
                            edge.setNode(materialize);
331
                    });
332
            }
333
            
334
            size_t upsilonInsertionPoint = block->size() - 1;
335
            NodeOrigin upsilonOrigin = block->last()->origin;
336
            for (BasicBlock* successorBlock : block->successors()) {
337
                for (SSACalculator::Def* phiDef : m_ssaCalculator.phisForBlock(successorBlock)) {
338
                    Node* phiNode = phiDef->value();
339
                    SSACalculator::Variable* variable = phiDef->variable();
340
                    Node* allocation = indexToNode[variable->index()];
341
                    
342
                    Node* originalIncoming = mapping.get(allocation);
343
                    Node* incoming;
344
                    if (originalIncoming == allocation) {
345
                        // If we have a Phi that combines materializations with the original
346
                        // phantom object, then the path with the phantom object must materialize.
347
                        
348
                        incoming = createMaterialize(allocation, upsilonOrigin);
349
                        m_insertionSet.insert(upsilonInsertionPoint, incoming);
350
                        insertOSRHintsForUpdate(
351
                            m_insertionSet, upsilonInsertionPoint,
352
                            availabilityCalculator.m_availability, originalIncoming, incoming);
353
                    } else
354
                        incoming = originalIncoming;
355
                    
356
                    Node* upsilon = m_insertionSet.insertNode(
357
                        upsilonInsertionPoint, SpecNone, Upsilon, upsilonOrigin,
358
                        OpInfo(phiNode), incoming->defaultEdge());
359
                    
360
                    if (originalIncoming == allocation) {
361
                        m_edgeToMaterializationPoint.add(
362
                            std::make_pair(upsilon, allocation), incoming);
363
                    }
364
                }
365
            }
366
            
367
            m_insertionSet.execute(block);
368
        }
369
        
370
        // At this point we have dummy materialization nodes along with edges to them. This means
371
        // that the part of the control flow graph that prefers to see actual object allocations
372
        // is completely fixed up, except for the materializations themselves.
373
    }
374
    
375
    void lowerNonReadingOperationsOnPhantomAllocations()
376
    {
377
        // Lower everything but reading operations on phantom allocations. We absolutely have to
378
        // lower all writes so as to reveal them to the SSA calculator. We cannot lower reads
379
        // because the whole point is that those go away completely.
380
        
381
        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
382
            for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
383
                Node* node = block->at(nodeIndex);
384
                switch (node->op()) {
385
                case PutByOffset: {
386
                    if (m_sinkCandidates.contains(node->child2().node()))
387
                        node->convertToPutByOffsetHint();
388
                    break;
389
                }
390
                    
391
                case PutStructure: {
392
                    if (m_sinkCandidates.contains(node->child1().node())) {
393
                        Node* structure = m_insertionSet.insertConstant(
394
                            nodeIndex, node->origin, JSValue(node->transition()->next));
395
                        node->convertToPutStructureHint(structure);
396
                    }
397
                    break;
398
                }
399
                    
400
                case NewObject: {
401
                    if (m_sinkCandidates.contains(node)) {
402
                        Node* structure = m_insertionSet.insertConstant(
403
                            nodeIndex + 1, node->origin, JSValue(node->structure()));
404
                        m_insertionSet.insertNode(
405
                            nodeIndex + 1, SpecNone, PutStructureHint, node->origin,
406
                            Edge(node, KnownCellUse), Edge(structure, KnownCellUse));
407
                        node->convertToPhantomNewObject();
408
                    }
409
                    break;
410
                }
411
                    
412
                case MaterializeNewObject: {
413
                    if (m_sinkCandidates.contains(node)) {
414
                        m_insertionSet.insertNode(
415
                            nodeIndex + 1, SpecNone, PutStructureHint, node->origin,
416
                            Edge(node, KnownCellUse), m_graph.varArgChild(node, 0));
417
                        for (unsigned i = 0; i < node->objectMaterializationData().m_properties.size(); ++i) {
418
                            m_insertionSet.insertNode(
419
                                nodeIndex + 1, SpecNone, PutByOffsetHint, node->origin,
420
                                Edge(node, KnownCellUse),m_graph.varArgChild(node, i + 1));
421
                        }
422
                        node->convertToPhantomNewObject();
423
                    }
424
                    break;
425
                }
426
                    
427
                default:
428
                    break;
429
                }
430
            }
431
            m_insertionSet.execute(block);
432
        }
433
    }
434
    
435
    void promoteSunkenFields()
436
    {
437
        // Henceforth when we encounter a materialization point, we will want to ask *who* it is
438
        // a materialization for. Invert the map to be able to answer such questions.
439
        m_materializationPointToEscapee.clear();
440
        for (auto pair : m_edgeToMaterializationPoint)
441
            m_materializationPointToEscapee.add(pair.value, pair.key.second);
442
        
443
        // Collect the set of heap locations that we will be operating over.
444
        HashSet<PromotedHeapLocation> locations;
445
        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
446
            for (Node* node : *block) {
447
                promoteHeapAccess(
448
                    node,
449
                    [&] (PromotedHeapLocation location, Edge) {
450
                        locations.add(location);
451
                    },
452
                    [&] (PromotedHeapLocation location) {
453
                        locations.add(location);
454
                    });
455
            }
456
        }
457
        
458
        // Figure out which locations belong to which allocations.
459
        m_locationsForAllocation.clear();
460
        for (PromotedHeapLocation location : locations) {
461
            auto result = m_locationsForAllocation.add(location.base(), Vector<PromotedHeapLocation>());
462
            ASSERT(!result.iterator->value.contains(location));
463
            result.iterator->value.append(location);
464
        }
465
        
466
        // For each sunken thingy, make sure we create Bottom values for all of its fields.
467
        // Note that this has the hilarious slight inefficiency of creating redundant hints for
468
        // things that were previously materializations. This should only impact compile times and
469
        // not code quality, and it's necessary for soundness without some data structure hackage.
470
        // For example, a MaterializeNewObject that we choose to sink may have new fields added to
471
        // it conditionally. That would necessitate Bottoms.
472
        Node* bottom = nullptr;
473
        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
474
            if (block == m_graph.block(0))
475
                bottom = m_insertionSet.insertNode(0, SpecNone, BottomValue, NodeOrigin());
476
            
477
            for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
478
                Node* node = block->at(nodeIndex);
479
                for (PromotedHeapLocation location : m_locationsForAllocation.get(node)) {
480
                    m_insertionSet.insert(
481
                        nodeIndex + 1, location.createHint(m_graph, node->origin, bottom));
482
                }
483
            }
484
            m_insertionSet.execute(block);
485
        }
486
487
        m_ssaCalculator.reset();
488
489
        // Collect the set of "variables" that we will be sinking.
490
        m_locationToVariable.clear();
491
        m_indexToLocation.clear();
492
        for (PromotedHeapLocation location : locations) {
493
            SSACalculator::Variable* variable = m_ssaCalculator.newVariable();
494
            m_locationToVariable.add(location, variable);
495
            ASSERT(m_indexToLocation.size() == variable->index());
496
            m_indexToLocation.append(location);
497
        }
498
        
499
        // Create Defs from the existing hints.
500
        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
501
            for (Node* node : *block) {
502
                promoteHeapAccess(
503
                    node,
504
                    [&] (PromotedHeapLocation location, Edge value) {
505
                        SSACalculator::Variable* variable = m_locationToVariable.get(location);
506
                        m_ssaCalculator.newDef(variable, block, value.node());
507
                    },
508
                    [&] (PromotedHeapLocation) { });
509
            }
510
        }
511
        
512
        // OMG run the SSA calculator to create Phis!
513
        m_ssaCalculator.computePhis(
514
            [&] (SSACalculator::Variable* variable, BasicBlock* block) -> Node* {
515
                PromotedHeapLocation location = m_indexToLocation[variable->index()];
516
                if (!block->ssa->liveAtHead.contains(location.base()))
517
                    return nullptr;
518
                
519
                Node* phiNode = m_graph.addNode(SpecHeapTop, Phi, NodeOrigin());
520
                phiNode->mergeFlags(NodeResultJS);
521
                return phiNode;
522
            });
523
        
524
        // Place Phis in the right places, replace all uses of any load with the appropriate
525
        // value, and create the appropriate Upsilon nodes.
526
        m_graph.clearReplacements();
527
        for (BasicBlock* block : m_graph.blocksInPreOrder()) {
528
            // This mapping table is intended to be lazy. If something is omitted from the table,
529
            // it means that there haven't been any local stores to that promoted heap location.
530
            m_localMapping.clear();
531
            
532
            // Insert the Phi functions that we had previously created.
533
            for (SSACalculator::Def* phiDef : m_ssaCalculator.phisForBlock(block)) {
534
                PromotedHeapLocation location = m_indexToLocation[phiDef->variable()->index()];
535
                
536
                m_insertionSet.insert(
537
                    0, phiDef->value());
538
                m_insertionSet.insert(
539
                    0, location.createHint(m_graph, NodeOrigin(), phiDef->value()));
540
                m_localMapping.add(location, phiDef->value());
541
            }
542
            
543
            // Process the block and replace all uses of loads with the promoted value.
544
            for (Node* node : *block) {
545
                m_graph.performSubstitution(node);
546
                
547
                if (Node* escapee = m_materializationPointToEscapee.get(node))
548
                    populateMaterialize(block, node, escapee);
549
                
550
                promoteHeapAccess(
551
                    node,
552
                    [&] (PromotedHeapLocation location, Edge value) {
553
                        m_localMapping.set(location, value.node());
554
                    },
555
                    [&] (PromotedHeapLocation location) {
556
                        node->replaceWith(resolve(block, location));
557
                    });
558
            }
559
            
560
            // Gotta drop some Upsilons.
561
            size_t upsilonInsertionPoint = block->size() - 1;
562
            NodeOrigin upsilonOrigin = block->last()->origin;
563
            for (BasicBlock* successorBlock : block->successors()) {
564
                for (SSACalculator::Def* phiDef : m_ssaCalculator.phisForBlock(successorBlock)) {
565
                    Node* phiNode = phiDef->value();
566
                    SSACalculator::Variable* variable = phiDef->variable();
567
                    PromotedHeapLocation location = m_indexToLocation[variable->index()];
568
                    Node* incoming = resolve(block, location);
569
                    
570
                    m_insertionSet.insertNode(
571
                        upsilonInsertionPoint, SpecNone, Upsilon, upsilonOrigin,
572
                        OpInfo(phiNode), incoming->defaultEdge());
573
                }
574
            }
575
            
576
            m_insertionSet.execute(block);
577
        }
578
    }
579
    
580
    Node* resolve(BasicBlock* block, PromotedHeapLocation location)
581
    {
582
        if (Node* result = m_localMapping.get(location))
583
            return result;
584
        
585
        // This implies that there is no local mapping. Find a non-local mapping.
586
        SSACalculator::Def* def = m_ssaCalculator.nonLocalReachingDef(
587
            block, m_locationToVariable.get(location));
588
        ASSERT(def);
589
        ASSERT(def->value());
590
        m_localMapping.add(location, def->value());
591
        return def->value();
592
    }
593
594
    template<typename SinkCandidateFunctor, typename EscapeFunctor>
595
    void handleNode(
596
        Node* node,
597
        const SinkCandidateFunctor& sinkCandidate,
598
        const EscapeFunctor& escape)
599
    {
600
        switch (node->op()) {
601
        case NewObject:
602
        case MaterializeNewObject:
603
            sinkCandidate();
604
            break;
605
            
606
        case CheckStructure:
607
        case GetByOffset:
608
        case MultiGetByOffset:
609
        case PutStructure:
610
        case GetGetterSetterByOffset:
611
        case MovHint:
612
            break;
613
            
614
        case PutByOffset:
615
            escape(node->child3().node());
616
            break;
617
            
618
        case MultiPutByOffset:
619
            // FIXME: In the future we should be able to handle this. It's just a matter of
620
            // building the appropriate *Hint variant of this instruction, along with a
621
            // PhantomStructureSelect node - since this transforms the Structure in a conditional
622
            // way.
623
            // https://bugs.webkit.org/show_bug.cgi?id=136924
624
            escape(node->child1().node());
625
            escape(node->child2().node());
626
            break;
627
628
        default:
629
            m_graph.doToChildren(
630
                node,
631
                [&escape] (Edge edge) {
632
                    escape(edge.node());
633
                });
634
            break;
635
        }
636
    }
637
    
638
    Node* createMaterialize(Node* escapee, const NodeOrigin whereOrigin)
639
    {
640
        switch (escapee->op()) {
641
        case NewObject:
642
        case MaterializeNewObject: {
643
            ObjectMaterializationData* data = m_graph.m_objectMaterializationData.add();
644
            
645
            Node* result = m_graph.addNode(
646
                escapee->prediction(), Node::VarArg, MaterializeNewObject,
647
                NodeOrigin(
648
                    escapee->origin.semantic,
649
                    whereOrigin.forExit),
650
                OpInfo(data), OpInfo(), 0, 0);
651
            return result;
652
        }
653
            
654
        default:
655
            DFG_CRASH(m_graph, escapee, "Bad escapee op");
656
            return nullptr;
657
        }
658
    }
659
    
660
    void populateMaterialize(BasicBlock* block, Node* node, Node* escapee)
661
    {
662
        switch (node->op()) {
663
        case MaterializeNewObject: {
664
            ObjectMaterializationData& data = node->objectMaterializationData();
665
            unsigned firstChild = m_graph.m_varArgChildren.size();
666
            
667
            Vector<PromotedHeapLocation> locations = m_locationsForAllocation.get(escapee);
668
            
669
            PromotedHeapLocation structure(StructurePLoc, escapee);
670
            ASSERT(locations.contains(structure));
671
            
672
            m_graph.m_varArgChildren.append(resolve(block, structure));
673
            
674
            for (unsigned i = 0; i < locations.size(); ++i) {
675
                switch (locations[i].kind()) {
676
                case StructurePLoc: {
677
                    ASSERT(locations[i] == structure);
678
                    break;
679
                }
680
                    
681
                case NamedPropertyPLoc: {
682
                    Node* value = resolve(block, locations[i]);
683
                    if (value->op() == BottomValue) {
684
                        // We can skip Bottoms entirely.
685
                        break;
686
                    }
687
                    
688
                    data.m_properties.append(PhantomPropertyValue(locations[i].info()));
689
                    m_graph.m_varArgChildren.append(value);
690
                    break;
691
                }
692
                    
693
                default:
694
                    DFG_CRASH(m_graph, node, "Bad location kind");
695
                }
696
            }
697
            
698
            node->children = AdjacencyList(
699
                AdjacencyList::Variable,
700
                firstChild, m_graph.m_varArgChildren.size() - firstChild);
701
            break;
702
        }
703
            
704
        default:
705
            DFG_CRASH(m_graph, node, "Bad materialize op");
706
            break;
707
        }
708
    }
709
    
710
    SSACalculator m_ssaCalculator;
711
    HashSet<Node*> m_sinkCandidates;
712
    HashMap<std::pair<Node*, Node*>, Node*> m_edgeToMaterializationPoint;
713
    HashMap<Node*, Node*> m_materializationPointToEscapee;
714
    HashMap<Node*, Vector<PromotedHeapLocation>> m_locationsForAllocation;
715
    HashMap<PromotedHeapLocation, SSACalculator::Variable*> m_locationToVariable;
716
    Vector<PromotedHeapLocation> m_indexToLocation;
717
    HashMap<PromotedHeapLocation, Node*> m_localMapping;
718
    InsertionSet m_insertionSet;
719
};
720
    
721
bool performObjectAllocationSinking(Graph& graph)
722
{
723
    SamplingRegion samplingRegion("DFG Object Allocation Sinking Phase");
724
    return runPhase<ObjectAllocationSinkingPhase>(graph);
725
}
726
727
} } // namespace JSC::DFG
728
729
#endif // ENABLE(DFG_JIT)
730
- 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 +61 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
namespace JSC { namespace DFG {
32
33
PhiChildren::PhiChildren()
34
{
35
}
36
37
PhiChildren::PhiChildren(Graph& graph)
38
{
39
    for (BasicBlock* block : graph.blocksInNaturalOrder()) {
40
        for (Node* node : *block) {
41
            if (node->op() != Upsilon)
42
                continue;
43
            
44
            m_children.add(node->phi(), List()).iterator->value.append(node);
45
        }
46
    }
47
}
48
49
PhiChildren::~PhiChildren()
50
{
51
}
52
53
const PhiChildren::List& PhiChildren::childrenOf(Node* node) const
54
{
55
    return m_children.get(node);
56
}
57
58
} } // namespace JSC::DFG
59
60
#endif // ENABLE(DFG_JIT)
61
- Source/JavaScriptCore/dfg/DFGPhiChildren.h +86 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
namespace JSC { namespace DFG {
32
33
class PhiChildren {
34
public:
35
    typedef Vector<Node*, 3> List;
36
    
37
    PhiChildren();
38
    PhiChildren(Graph&);
39
    ~PhiChildren();
40
    
41
    // The list of Upsilons that point to the children of the Phi.
42
    const List& upsilonsOf(Node*) const;
43
    
44
    template<typename Functor>
45
    void forAllIncomingValues(Node* node, const Functor& functor)
46
    {
47
        for (Node* upsilon : upsilonsOf(node))
48
            functor(upsilon->child1().node());
49
    }
50
    
51
    // This walks the Phi graph.
52
    template<typename Functor>
53
    void forAllTransitiveIncomingValues(Node* node, const Functor& functor)
54
    {
55
        if (node->op() != Phi) {
56
            functor(node);
57
            return;
58
        }
59
        HashSet<Node*> seen;
60
        Vector<Node*> worklist;
61
        seen.add(node);
62
        worklist.append(node);
63
        while (!worklist.isEmpty()) {
64
            Node* currentNode = worklist.takeLast();
65
            forAllIncomingValues(
66
                currentNode,
67
                [&] (Node* incomingNode) {
68
                    if (incomingNode->op() == Phi) {
69
                        if (seen.add(incomingNode).isNewEntry)
70
                            worklist.append(incomingNode);
71
                    } else
72
                        functor(incomingNode);
73
                });
74
        }
75
    }
76
    
77
private:
78
    HashMap<Node*, List> m_children;
79
};
80
81
} } // namespace JSC::DFG
82
83
#endif // ENABLE(DFG_JIT)
84
85
#endif // DFGPhiChildren_h
86
- 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 BaselessPromotedHeapLocation::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 +167 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 BaselessPromotedHeapLocation {
44
public:
45
    BaselessPromotedHeapLocation(
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 BaselessPromotedHeapLocation& other) const
63
    {
64
        return m_kind == other.m_kind
65
            && m_info == other.m_info;
66
    }
67
68
    bool isHashTableDeletedValue() const
69
    {
70
        return m_kind == InvalidPromotedLocationKind && m_info;
71
    }
72
    
73
    void dump(PrintStream& out) const;
74
75
private:
76
    PromotedLocationKind m_kind;
77
    unsigned m_info;
78
};
79
80
class PromotedHeapLocation {
81
public:
82
    PromotedHeapLocation(
83
        PromotedLocationKind kind = InvalidPromotedLocationKind,
84
        Node* base = nullptr, unsigned info = 0)
85
        : m_base(base)
86
        , m_meta(kind, info)
87
    {
88
    }
89
    
90
    PromotedHeapLocation(
91
        PromotedLocationKind kind, Edge base, unsigned info = 0)
92
        : PromotedHeapLocation(kind, base.node(), info)
93
    {
94
    }
95
    
96
    PromotedHeapLocation(Node* base, BaselessPromotedHeapLocation meta)
97
        : m_base(base)
98
        , m_meta(meta)
99
    {
100
    }
101
    
102
    PromotedHeapLocation(WTF::HashTableDeletedValueType)
103
        : m_base(nullptr)
104
        , m_meta(InvalidPromotedLocationKind, 1)
105
    {
106
    }
107
    
108
    Node* createHint(Graph&, NodeOrigin, Node* value);
109
    
110
    bool operator!() const { return kind() == InvalidPromotedLocationKind; }
111
    
112
    PromotedLocationKind kind() const { return m_meta.kind(); }
113
    Node* base() const { return m_base; }
114
    unsigned info() const { return m_meta.info(); }
115
    BaselessPromotedHeapLocation baseless() const { return m_meta; }
116
    
117
    unsigned hash() const
118
    {
119
        return m_meta.hash() + WTF::PtrHash<Node*>::hash(m_base);
120
    }
121
    
122
    bool operator==(const PromotedHeapLocation& other) const
123
    {
124
        return m_base == other.m_base
125
            && m_meta == other.m_meta;
126
    }
127
    
128
    bool isHashTableDeletedValue() const
129
    {
130
        return m_meta.isHashTableDeletedValue();
131
    }
132
    
133
    void dump(PrintStream& out) const;
134
    
135
private:
136
    Node* m_base;
137
    BaselessPromotedHeapLocation m_meta;
138
};
139
140
struct PromotedHeapLocationHash {
141
    static unsigned hash(const PromotedHeapLocation& key) { return key.hash(); }
142
    static bool equal(const PromotedHeapLocation& a, const PromotedHeapLocation& b) { return a == b; }
143
    static const bool safeToCompareToEmptyOrDeleted = true;
144
};
145
146
} } // namespace JSC::DFG
147
148
namespace WTF {
149
150
void printInternal(PrintStream&, JSC::DFG::PromotedLocationKind);
151
152
template<typename T> struct DefaultHash;
153
template<> struct DefaultHash<JSC::DFG::PromotedHeapLocation> {
154
    typedef JSC::DFG::PromotedHeapLocationHash Hash;
155
};
156
157
template<typename T> struct HashTraits;
158
template<> struct HashTraits<JSC::DFG::PromotedHeapLocation> : SimpleClassHashTraits<JSC::DFG::PromotedHeapLocation> {
159
    static const bool emptyValueIsZero = false;
160
};
161
162
} // namespace WTF
163
164
#endif // ENABLE(DFG_JIT)
165
166
#endif // DFGPromotedHeapLocation_h
167
- 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/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 +68 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
#include <wtf/StringImpl.h>
34
35
namespace JSC { namespace FTL {
36
37
class ExitPropertyValue {
38
public:
39
    ExitPropertyValue()
40
        : m_uid(nullptr)
41
    {
42
    }
43
    
44
    ExitPropertyValue(BaselessPromotedHeapLocation location, const ExitValue& value)
45
        : m_location(location)
46
        , m_value(value)
47
    {
48
        ASSERT(!!uid == !!value);
49
    }
50
    
51
    bool operator!() const { return !m_uid; }
52
    
53
    BaselessPromotedHeapLocation location() const { return m_location; }
54
    const ExitValue& value() const { return m_value; }
55
    
56
    void dump(PrintStream& out) const;
57
58
private:
59
    BaselessPromotedHeapLocation m_location;
60
    ExitValue m_value;
61
};
62
63
} } // namespace JSC::FTL
64
65
#endif // ENABLE(FTL_JIT)
66
67
#endif // FTLExitPropertyValue_h
68
- Source/JavaScriptCore/ftl/FTLExitTimeObjectMaterialization.cpp +65 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
namespace JSC { namespace FTL {
32
33
ExitTimeObjectMaterialization::ExitTimeObjectMaterialization(NodeType type)
34
    : m_type(type)
35
{
36
}
37
38
ExitTimeObjectMaterialization::~ExitTimeObjectMaterialization()
39
{
40
}
41
42
void ExitTimeObjectMaterialization::add(
43
    BaselessPromotedHeapLocation location, const ExitValue& value)
44
{
45
    m_properties.append(ExitPropertyValue(location, value));
46
}
47
48
const ExitValue& ExitTimeObjectMaterialization::get(BaselessPromotedHeapLocation location) const
49
{
50
    for (ExitPropertyValue value : m_properties) {
51
        if (value.location() == location)
52
            return value.value();
53
    }
54
    return ExitValue();
55
}
56
57
void ExitTimeObjectMaterialization::dump(PrintStream& out) const
58
{
59
    out.print("<", Graph::opName(m_type), ": ", listDump(m_properties), ">");
60
}
61
62
} } // namespace JSC::FTL
63
64
#endif // ENABLE(FTL_JIT)
65
- Source/JavaScriptCore/ftl/FTLExitTimeObjectMaterialization.h +62 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 "FTLExitPropertyValue.h"
32
#include "FTLExitValue.h"
33
#include <wtf/Noncopyable.h>
34
35
namespace JSC { namespace FTL {
36
37
class ExitTimeObjectMaterialization {
38
    WTF_MAKE_NONCOPYABLE(ExitTimeObjectMaterialization)
39
public:
40
    ExitTimeObjectMaterialization(NodeType);
41
    ~ExitTimeObjectMaterialization();
42
    
43
    void add(DFG::BaselessPromptedHeapLocation, const ExitValue&);
44
    
45
    NodeType type() const { return m_type; }
46
    
47
    const ExitValue& get(DFG::BaselessPromotedHeapLocation) const;
48
    const Vector<ExitPropertyValue>& properties() const { return m_properties; }
49
    
50
    void dump(PrintStream& out) const;
51
    
52
private:
53
    NodeType m_type;
54
    Vector<ExitPropertyValue> m_properties;
55
};
56
57
} } // namespace JSC::FTL
58
59
#endif // ENABLE(FTL_JIT)
60
61
#endif // FTLExitTimeObjectMaterialization_h
62
- Source/JavaScriptCore/ftl/FTLExitValue.cpp +11 lines
Lines 32-37 Source/JavaScriptCore/ftl/FTLExitValue.cpp_sec1
32
32
33
namespace JSC { namespace FTL {
33
namespace JSC { namespace FTL {
34
34
35
void ExitValue ExitValue::materializeNewObject(ExitTimeObjectMaterialization* data)
36
{
37
    ExitValue result;
38
    result.m_kind = ExitValueMaterializeNewObject;
39
    result.u.newObjectMaterializationData = data;
40
    return result;
41
}
42
35
void ExitValue::dumpInContext(PrintStream& out, DumpContext* context) const
43
void ExitValue::dumpInContext(PrintStream& out, DumpContext* context) const
36
{
44
{
37
    switch (kind()) {
45
    switch (kind()) {
Lines 65-70 void ExitValue::dumpInContext(PrintStrea Source/JavaScriptCore/ftl/FTLExitValue.cpp_sec2
65
    case ExitValueRecovery:
73
    case ExitValueRecovery:
66
        out.print("Recovery(", recoveryOpcode(), ", arg", leftRecoveryArgument(), ", arg", rightRecoveryArgument(), ", ", recoveryFormat(), ")");
74
        out.print("Recovery(", recoveryOpcode(), ", arg", leftRecoveryArgument(), ", arg", rightRecoveryArgument(), ", ", recoveryFormat(), ")");
67
        return;
75
        return;
76
    case ExitValueMaterializeNewObject:
77
        out.print("Materialize(", pointerDump(objectMaterialization()), ")");
78
        return;
68
    }
79
    }
69
    
80
    
70
    RELEASE_ASSERT_NOT_REACHED();
81
    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(const 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 -152 / +332 lines
Lines 725-730 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec1
725
        case ToIndexString:
725
        case ToIndexString:
726
            compileToIndexString();
726
            compileToIndexString();
727
            break;
727
            break;
728
        case CheckStructureImmediate:
729
            compileCheckStructureImmediate();
730
            break;
731
        case MaterializeNewObject:
732
            compileMaterializeNewObject();
733
            break;
728
734
729
        case PhantomLocal:
735
        case PhantomLocal:
730
        case SetArgument:
736
        case SetArgument:
Lines 735-740 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec2
735
        case AllocationProfileWatchpoint:
741
        case AllocationProfileWatchpoint:
736
        case MovHint:
742
        case MovHint:
737
        case ZombieHint:
743
        case ZombieHint:
744
        case PhantomNewObject:
745
        case PutByOffsetHint:
746
        case PutStructureHint:
738
            break;
747
            break;
739
        default:
748
        default:
740
            DFG_CRASH(m_graph, m_node, "Unrecognized node in FTL backend");
749
            DFG_CRASH(m_graph, m_node, "Unrecognized node in FTL backend");
Lines 1704-1733 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec3
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, 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_sec4
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_sec5
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_sec6
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_sec7
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_nde->child1());
4333
        checkStructure(structureID, noValue(), BadCache, 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
                Structure* structure = incoming->dynamicCastConstant<Structure*>();
4351
                DFG_ASSERT(m_graph, m_node, structure);
4352
                set.add(structure);
4353
            });
4354
        
4355
        Vector<LBasicBlock, 1> blocks(set.size());
4356
        for (unsigned i = set.size(); i--;)
4357
            blocks[i] = FTL_NEW_BLOCK(m_out, ("MaterializeNewObject case ", i));
4358
        LBasicBlock dummyDefault = FTL_NEW_BLOCK(m_out, ("MaterializeNewObject default case"));
4359
        LBasicBlock outerContinuation = FTL_NEW_BLOCK(m_out, ("MaterializeNewObject continuation"));
4360
        
4361
        Vector<SwitchCase, 1> cases(set.size());
4362
        for (unsigned i = set.size(); i--;)
4363
            cases[i] = SwitchCase(weakStructure(set[i]), blocks[i], Weight(1));
4364
        m_out.switchInstruction(
4365
            lowCell(m_graph.varArgChild(m_node, 0)), cases, dummyDefault, Weight(0));
4366
        
4367
        LBasicBlock outerLastNext = m_out.nextBlock;
4368
        
4369
        Vector<ValueFromBlock, 1> results;
4370
        
4371
        for (unsigned i = set.size(); i--;) {
4372
            m_out.appendTo(blocks[i], i + 1 < set.size() ? blocks[i + 1] : dummyDefault);
4373
            
4374
            Structure* structure = set[i];
4375
            
4376
            LValue object;
4377
            LValue butterfly;
4378
            
4379
            if (structure->outOfLineCapacity()) {
4380
                size_t allocationSize = JSFinalObject::allocationSize(primordialStructure->inlineCapacity());
4381
                MarkedAllocator* allocator = &vm().heap.allocatorForObjectWithoutDestructor(allocationSize);
4382
                
4383
                LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("MaterializeNewObject complex object allocation slow path"));
4384
                LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("MaterializeNewObject complex object allocation continuation"));
4385
                
4386
                LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
4387
                
4388
                LValue endOfStorage = allocateBasicStorageAndGetEnd(
4389
                    m_out.constIntPtr(structure->outOfLineCapacity() * sizeof(JSValue)),
4390
                    slowPath);
4391
                
4392
                LValue fastButterflyValue = m_out.add(
4393
                    m_out.constIntPtr(sizeof(IndexingHeader)), endOfStorage);
4394
                
4395
                Lvalue fastObjectValue = allocateObject(
4396
                    m_out.constIntPtr(allocator), structure, fastButterflyValue, slowPath);
4397
4398
                ValueFromBlock fastObject = m_out.anchor(fastObjectvalue);
4399
                ValueFromBlock fastButterfly = m_out.anchor(fastButterflyValue);
4400
                m_out.jump(continuation);
4401
                
4402
                m_out.appendTo(slowPath, continuation);
4403
                
4404
                ValueFromBlock slowObject = m_out.anchor(vmCall(
4405
                    m_out.operation(operationNewObjectWithButterfly),
4406
                    m_callFrame, m_out.constIntPtr(structure)));
4407
                ValueFromBlock slowButterfly = m_out.anchor(
4408
                    m_out.loadPtr(slowObject.value(), m_heaps.JSObject_butterfly));
4409
                
4410
                m_out.jump(continuation);
4411
                
4412
                m_out.appendTo(continuation, lastNext);
4413
                
4414
                object = m_out.phi(m_out.intPtr, fastObject, slowObject);
4415
                butterfly = m_out.phi(m_out.intPtr, fastButterfly, slowButterfly);
4416
            } else {
4417
                // In the easy case where we can do a one-shot allocation, we simply allocate the
4418
                // object to directly have the desired structure.
4419
                object = allocateObject(structure);
4420
                butterfly = nullptr; // Don't have one, don't need one.
4421
            }
4422
            
4423
            for (PropertyMapEntry entry : structure->getPropertiesConcurrently()) {
4424
                for (unsigned i = data.m_properties.size(); i--;) {
4425
                    PhantomPropertyValue value = data.m_properties[i];
4426
                    if (m_graph.identifiers()[value.m_identifierNumber] != entry.key)
4427
                        continue;
4428
                    
4429
                    LValue base = isInlineOffset(entry.offset) ? object : butterfly;
4430
                    storeProperty(values[i], base, value.m_identifierNumber, entry.offset);
4431
                    break;
4432
                }
4433
            }
4434
            
4435
            results.append(m_out.anchor(object));
4436
            m_out.jump(outerContinuation);
4437
        }
4438
        
4439
        m_out.appendTo(dummyDefault, outerContinuation);
4440
        m_out.unreachable();
4441
        
4442
        m_out.appendTo(outerContinuation, outerLastNext);
4443
        setJSValue(m_out.phi(m_out.intPtr, results));
4444
    }
4363
4445
4364
#if ENABLE(FTL_NATIVE_CALL_INLINING)
4446
#if ENABLE(FTL_NATIVE_CALL_INLINING)
4365
    LValue getFunctionBySymbol(const CString symbol)
4447
    LValue getFunctionBySymbol(const CString symbol)
Lines 4525-4530 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec8
4525
        return m_out.booleanFalse;
4607
        return m_out.booleanFalse;
4526
    }
4608
    }
4527
    
4609
    
4610
    void checkStructure(
4611
        LValue structureID, const FormattedValue& formattedValue, ExitKind exitKind,
4612
        const StructureSet& set)
4613
    {
4614
        if (set.size() == 1) {
4615
            speculate(
4616
                exitKind, formattedValue, 0,
4617
                m_out.notEqual(structureID, weakStructure(set[0])));
4618
            return;
4619
        }
4620
        
4621
        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("checkStructure continuation"));
4622
        
4623
        LBasicBlock lastNext = m_out.insertNewBlocksBefore(continuation);
4624
        for (unsigned i = 0; i < set.size() - 1; ++i) {
4625
            LBasicBlock nextStructure = FTL_NEW_BLOCK(m_out, ("checkStructure nextStructure"));
4626
            m_out.branch(
4627
                m_out.equal(structureID, weakStructure(set[i])),
4628
                unsure(continuation), unsure(nextStructure));
4629
            m_out.appendTo(nextStructure);
4630
        }
4631
        
4632
        speculate(
4633
            exitKind, formattedValue, 0,
4634
            m_out.notEqual(structureID, weakStructure(set.last())));
4635
        
4636
        m_out.jump(continuation);
4637
        m_out.appendTo(continuation, lastNext);
4638
    }
4639
    
4528
    LValue numberOrNotCellToInt32(Edge edge, LValue value)
4640
    LValue numberOrNotCellToInt32(Edge edge, LValue value)
4529
    {
4641
    {
4530
        LBasicBlock intCase = FTL_NEW_BLOCK(m_out, ("ValueToInt32 int case"));
4642
        LBasicBlock intCase = FTL_NEW_BLOCK(m_out, ("ValueToInt32 int case"));
Lines 4624-4707 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec9
4624
                m_callFrame, object);
4736
                m_callFrame, object);
4625
        }
4737
        }
4626
        
4738
        
4627
        LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("allocatePropertyStorage slow path"));
4739
        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);
4740
        m_out.storePtr(result, object, m_heaps.JSObject_butterfly);
4651
        
4652
        return result;
4741
        return result;
4653
    }
4742
    }
4654
    
4743
    
4655
    LValue reallocatePropertyStorage(
4744
    LValue reallocatePropertyStorage(
4656
        LValue object, LValue oldStorage, Structure* previous, Structure* next)
4745
        LValue object, LValue oldStorage, Structure* previous, Structure* next)
4657
    {
4746
    {
4658
        size_t oldSize = previous->outOfLineCapacity() * sizeof(JSValue);
4747
        size_t oldSize = previous->outOfLineCapacity();
4659
        size_t newSize = oldSize * outOfLineGrowthFactor; 
4748
        size_t newSize = oldSize * outOfLineGrowthFactor; 
4660
4749
4661
        ASSERT_UNUSED(next, newSize == next->outOfLineCapacity() * sizeof(JSValue));
4750
        ASSERT_UNUSED(next, newSize == next->outOfLineCapacity());
4662
        
4751
        
4663
        if (previous->couldHaveIndexingHeader()) {
4752
        if (previous->couldHaveIndexingHeader()) {
4664
            LValue newAllocSize = m_out.constInt64(newSize / sizeof(JSValue));                    
4753
            LValue newAllocSize = m_out.constIntPtr(newSize);                    
4665
            return vmCall(m_out.operation(operationReallocateButterflyToGrowPropertyStorage), m_callFrame, object, newAllocSize);
4754
            return vmCall(m_out.operation(operationReallocateButterflyToGrowPropertyStorage), m_callFrame, object, newAllocSize);
4666
        }
4755
        }
4667
        
4756
        
4668
        LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("reallocatePropertyStorage slow path"));
4757
        LValue result = allocatePropertyStorageWithSizeImpl(newSize);
4669
        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("reallocatePropertyStorage continuation"));
4758
4759
        ptrdiff_t headerSize = -sizeof(IndexingHeader) - sizeof(void*);
4760
        ptrdiff_t endStorage = headerSize - static_cast<ptrdiff_t>(oldSize * sizeof(JSValue));
4761
4762
        for (ptrdiff_t offset = headerSize; offset > endStorage; offset -= sizeof(void*)) {
4763
            LValue loaded = 
4764
                m_out.loadPtr(m_out.address(m_heaps.properties.atAnyNumber(), oldStorage, offset));
4765
            m_out.storePtr(loaded, m_out.address(m_heaps.properties.atAnyNumber(), result, offset));
4766
        }
4767
        
4768
        m_out.storePtr(result, m_out.address(object, m_heaps.JSObject_butterfly));
4769
        
4770
        return result;
4771
    }
4772
    
4773
    LValue allocatePropertyStorageWithSizeImpl(size_t sizeInValues)
4774
    {
4775
        LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("allocatePropertyStorageWithSizeImpl slow path"));
4776
        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("allocatePropertyStorageWithSizeImpl continuation"));
4777
        
4670
        LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
4778
        LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
4671
        
4779
        
4672
        LValue endOfStorage = 
4780
        LValue endOfStorage = allocateBasicStorageAndGetEnd(
4673
            allocateBasicStorageAndGetEnd(m_out.constIntPtr(newSize), slowPath);
4781
            m_out.constIntPtr(sizeInValues * sizeof(JSValue)), slowPath);
4674
        
4782
        
4675
        ValueFromBlock fastButterfly = m_out.anchor(m_out.add(m_out.constIntPtr(sizeof(IndexingHeader)), endOfStorage));
4783
        ValueFromBlock fastButterfly = m_out.anchor(
4784
            m_out.add(m_out.constIntPtr(sizeof(IndexingHeader)), endOfStorage));
4676
        
4785
        
4677
        m_out.jump(continuation);
4786
        m_out.jump(continuation);
4678
        
4787
        
4679
        m_out.appendTo(slowPath, continuation);
4788
        m_out.appendTo(slowPath, continuation);
4680
        
4789
        
4681
        LValue newAllocSize = m_out.constInt64(newSize / sizeof(JSValue));       
4790
        LValue slowButterflyValue;
4682
        
4791
        if (sizeInValues == initialOutOfLineCapacity) {
4683
        LValue storageLocation = vmCall(m_out.operation(operationAllocatePropertyStorage), m_callFrame, newAllocSize);
4792
            slowButterflyValue = vmCall(
4684
        
4793
                m_out.operation(operationAllocatePropertyStorageWithInitialCapacity),
4685
        ValueFromBlock slowButterfly = m_out.anchor(storageLocation);
4794
                m_callFrame);
4795
        } else {
4796
            slowButterflyValue = vmCall(
4797
                m_out.operation(operationAllocatePropertyStorage),
4798
                m_callFrame, m_out.constIntPtr(sizeInValues));
4799
        }
4800
        ValueFromBlock slowButterfly = m_out.anchor(slowButterflyValue);
4686
        
4801
        
4687
        m_out.jump(continuation);
4802
        m_out.jump(continuation);
4688
        
4803
        
4689
        m_out.appendTo(continuation, lastNext);
4804
        m_out.appendTo(continuation, lastNext);
4690
        
4805
        
4691
        LValue result = m_out.phi(m_out.intPtr, fastButterfly, slowButterfly);
4806
        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
    }
4807
    }
4706
    
4808
    
4707
    LValue getById(LValue base)
4809
    LValue getById(LValue base)
Lines 4841-4847 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec10
4841
        setBoolean(m_out.phi(m_out.boolean, fastResult, slowResult));
4943
        setBoolean(m_out.phi(m_out.boolean, fastResult, slowResult));
4842
    }
4944
    }
4843
4945
4844
    LValue allocateCell(LValue allocator, Structure* structure, LBasicBlock slowPath)
4946
    LValue allocateCell(LValue allocator, LBasicBlock slowPath)
4845
    {
4947
    {
4846
        LBasicBlock success = FTL_NEW_BLOCK(m_out, ("object allocation success"));
4948
        LBasicBlock success = FTL_NEW_BLOCK(m_out, ("object allocation success"));
4847
        
4949
        
Lines 4856-4867 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec11
4856
            m_out.loadPtr(result, m_heaps.JSCell_freeListNext),
4958
            m_out.loadPtr(result, m_heaps.JSCell_freeListNext),
4857
            allocator, m_heaps.MarkedAllocator_freeListHead);
4959
            allocator, m_heaps.MarkedAllocator_freeListHead);
4858
        
4960
        
4961
        return result;
4962
    }
4963
    
4964
    void storeStructure(LValue object, Structure* structure)
4965
    {
4859
        m_out.store32(m_out.constInt32(structure->id()), result, m_heaps.JSCell_structureID);
4966
        m_out.store32(m_out.constInt32(structure->id()), result, m_heaps.JSCell_structureID);
4860
        
4861
        m_out.store32(
4967
        m_out.store32(
4862
            m_out.constInt32(structure->objectInitializationBlob()),
4968
            m_out.constInt32(structure->objectInitializationBlob()),
4863
            result, m_heaps.JSCell_usefulBytes);
4969
            result, m_heaps.JSCell_usefulBytes);
4864
        
4970
    }
4971
4972
    LValue allocateCell(LValue allocator, Structure* structure, LBasicBlock slowPath)
4973
    {
4974
        LValue result = allocateCell(allocator, slowPath);
4975
        storeStructure(result, structure);
4865
        return result;
4976
        return result;
4866
    }
4977
    }
4867
4978
Lines 4908-4913 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec12
4908
            m_out.loadPtr(m_out.absolute(&allocator.m_currentPayloadEnd)), newRemaining);
5019
            m_out.loadPtr(m_out.absolute(&allocator.m_currentPayloadEnd)), newRemaining);
4909
    }
5020
    }
4910
    
5021
    
5022
    LValue allocateObject(Structure* structure)
5023
    {
5024
        size_t allocationSize = JSFinalObject::allocationSize(structure->inlineCapacity());
5025
        MarkedAllocator* allocator = &vm().heap.allocatorForObjectWithoutDestructor(allocationSize);
5026
        
5027
        LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("allocateObject slow path"));
5028
        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("allocateObject continuation"));
5029
        
5030
        LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
5031
        
5032
        ValueFromBlock fastResult = m_out.anchor(allocateObject(
5033
            m_out.constIntPtr(allocator), structure, m_out.intPtrZero, slowPath));
5034
        
5035
        m_out.jump(continuation);
5036
        
5037
        m_out.appendTo(slowPath, continuation);
5038
        
5039
        ValueFromBlock slowResult = m_out.anchor(vmCall(
5040
            m_out.operation(operationNewObject), m_callFrame, m_out.constIntPtr(structure)));
5041
        m_out.jump(continuation);
5042
        
5043
        m_out.appendTo(continuation, lastNext);
5044
        return m_out.phi(m_out.intPtr, fastResult, slowResult);
5045
    }
5046
    
4911
    struct ArrayValues {
5047
    struct ArrayValues {
4912
        ArrayValues()
5048
        ArrayValues()
4913
            : array(0)
5049
            : array(0)
Lines 6344-6350 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec13
6344
        ExitKind kind, FormattedValue lowValue, Node* highValue, LValue failCondition)
6480
        ExitKind kind, FormattedValue lowValue, Node* highValue, LValue failCondition)
6345
    {
6481
    {
6346
        if (verboseCompilationEnabled()) {
6482
        if (verboseCompilationEnabled()) {
6347
            dataLog("    OSR exit #", m_ftlState.jitCode->osrExit.size(), " with availability: ", availability(), "\n");
6483
            dataLog("    OSR exit #", m_ftlState.jitCode->osrExit.size(), " with availability: ", availabilityMap(), "\n");
6348
            if (!m_availableRecoveries.isEmpty())
6484
            if (!m_availableRecoveries.isEmpty())
6349
                dataLog("        Available recoveries: ", listDump(m_availableRecoveries), "\n");
6485
                dataLog("        Available recoveries: ", listDump(m_availableRecoveries), "\n");
6350
        }
6486
        }
Lines 6354-6360 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec14
6354
        m_ftlState.jitCode->osrExit.append(OSRExit(
6490
        m_ftlState.jitCode->osrExit.append(OSRExit(
6355
            kind, lowValue.format(), m_graph.methodOfGettingAValueProfileFor(highValue),
6491
            kind, lowValue.format(), m_graph.methodOfGettingAValueProfileFor(highValue),
6356
            m_codeOriginForExitTarget, m_codeOriginForExitProfile,
6492
            m_codeOriginForExitTarget, m_codeOriginForExitProfile,
6357
            availability().numberOfArguments(), availability().numberOfLocals()));
6493
            availabilityMap().m_locals.numberOfArguments(),
6494
            availabilityMap().m_locals.numberOfLocals()));
6358
        m_ftlState.finalizer->osrExit.append(OSRExitCompilationInfo());
6495
        m_ftlState.finalizer->osrExit.append(OSRExitCompilationInfo());
6359
        
6496
        
6360
        OSRExit& exit = m_ftlState.jitCode->osrExit.last();
6497
        OSRExit& exit = m_ftlState.jitCode->osrExit.last();
Lines 6394-6449 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec15
6394
        if (!!lowValue)
6531
        if (!!lowValue)
6395
            arguments.append(lowValue.value());
6532
            arguments.append(lowValue.value());
6396
        
6533
        
6534
        AvailabilityMap availabilityMap = availabilityMap();
6535
        
6397
        for (unsigned i = 0; i < exit.m_values.size(); ++i) {
6536
        for (unsigned i = 0; i < exit.m_values.size(); ++i) {
6398
            int operand = exit.m_values.operandForIndex(i);
6537
            int operand = exit.m_values.operandForIndex(i);
6399
            bool isLive = m_graph.isLiveInBytecode(VirtualRegister(operand), codeOrigin);
6538
            if (!m_graph.isLiveInBytecode(VirtualRegister(operand), codeOrigin))
6400
            if (!isLive) {
6539
                availabilityMap.m_locals[i] = Availability();
6401
                exit.m_values[i] = ExitValue::dead();
6540
        }
6402
                continue;
6541
        
6403
            }
6542
        availabilityMap.prune();
6404
            
6543
        
6405
            Availability availability = this->availability()[i];
6544
        HashMap<Node*, ExitTimeObjectMaterialization*> map;
6406
            FlushedAt flush = availability.flushedAt();
6545
        availabilityMap.forEachAvailability(
6407
            switch (flush.format()) {
6546
            [&] (Availability availability) {
6408
            case DeadFlush:
6547
                if (!availability.shouldUseNode())
6409
            case ConflictingFlush:
6548
                    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
                
6549
                
6439
            case FlushedDouble:
6550
                Node* node = availability.node();
6440
                exit.m_values[i] = ExitValue::inJSStackAsDouble(flush.virtualRegister());
6551
                if (!node->isPhantomObjectAllocation())
6441
                break;
6552
                    return;
6442
                
6553
                
6443
            case FlushedArguments:
6554
                auto result = map.add(node, nullptr);
6444
                exit.m_values[i] = ExitValue::argumentsObjectThatWasNotCreated();
6555
                if (result.isNewEntry)
6445
                break;
6556
                    result.iterator->value = exit.m_materializations.add(node->op());
6557
            });
6558
        
6559
        for (unsigned i = 0; i < exit.m_values.size(); ++i) {
6560
            int operand = exit.m_values.operandForIndex(i);
6561
            
6562
            Availability availability = this->availabilityMap().m_locals[i];
6563
            
6564
            if (Options::validateFTLOSRExitLiveness()) {
6565
                DFG_ASSERT(
6566
                    m_graph, m_node,
6567
                    m_graph.isLiveInBytecode(VirtualRegister(operand), codeOrigin)
6568
                    == availability.isDead());
6446
            }
6569
            }
6570
            
6571
            exit.m_values[i] = exitValueForAvailability(arguments, map, availability);
6572
        }
6573
        
6574
        for (auto heapPair : availabilityMap.m_heap) {
6575
            Node* node = heapPair.key.base();
6576
            ExitTimeObjectMaterialization* materialization = map.get(node);
6577
            materialization->add(
6578
                heapPair.key.baseless(),
6579
                exitValueForAvailability(arguments, map, heapPair.value));
6447
        }
6580
        }
6448
        
6581
        
6449
        if (verboseCompilationEnabled())
6582
        if (verboseCompilationEnabled())
Lines 6459-6471 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec16
6459
        m_out.call(m_out.stackmapIntrinsic(), arguments);
6592
        m_out.call(m_out.stackmapIntrinsic(), arguments);
6460
    }
6593
    }
6461
    
6594
    
6462
    ExitValue exitValueForNode(ExitArgumentList& arguments, Node* node)
6595
    ExitValue exitValueForAvailability(
6596
        ExitArgumentList& arguments, const HashMap<Node*, ExitTimeObjectMaterialization*>& map,
6597
        Availability availability)
6598
    {
6599
        FlushedAt flush = availability.flushedAt();
6600
        switch (flush.format()) {
6601
        case DeadFlush:
6602
        case ConflictingFlush:
6603
            if (availability.hasNode())
6604
                return exitValueForNode(arguments, map, availability.node());
6605
            
6606
            // This means that the value is dead. It could be dead in bytecode or it could have
6607
            // been killed by our DCE, which can sometimes kill things even if they were live in
6608
            // bytecode.
6609
            return ExitValue::dead();
6610
6611
        case FlushedJSValue:
6612
        case FlushedCell:
6613
        case FlushedBoolean:
6614
            return ExitValue::inJSStack(flush.virtualRegister());
6615
                
6616
        case FlushedInt32:
6617
            return ExitValue::inJSStackAsInt32(flush.virtualRegister());
6618
                
6619
        case FlushedInt52:
6620
            return ExitValue::inJSStackAsInt52(flush.virtualRegister());
6621
                
6622
        case FlushedDouble:
6623
            return ExitValue::inJSStackAsDouble(flush.virtualRegister());
6624
                
6625
        case FlushedArguments:
6626
            return ExitValue::argumentsObjectThatWasNotCreated();
6627
        }
6628
        
6629
        DFG_CRASH(m_graph, m_node, "Invalid flush format");
6630
    }
6631
    
6632
    ExitValue exitValueForNode(
6633
        ExitArgumentList& arguments, const HashMap<Node*, ExitTimeObjectMaterialization*>& map,
6634
        Node* node)
6463
    {
6635
    {
6464
        ASSERT(node->shouldGenerate());
6636
        ASSERT(node->shouldGenerate());
6465
        ASSERT(node->hasResult());
6637
        ASSERT(node->hasResult());
6466
6638
6467
        if (node) {
6639
        if (node) {
6468
            switch (node->op()) {
6640
            switch (node->op()) {
6641
            case BottomValue:
6642
                // This might arise in object materializations. I actually doubt that it would,
6643
                // but it seems worthwhile to be conservative.
6644
                return ExitValue::dead();
6645
                
6469
            case JSConstant:
6646
            case JSConstant:
6470
            case Int52Constant:
6647
            case Int52Constant:
6471
            case DoubleConstant:
6648
            case DoubleConstant:
Lines 6474-6479 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec17
6474
            case PhantomArguments:
6651
            case PhantomArguments:
6475
                return ExitValue::argumentsObjectThatWasNotCreated();
6652
                return ExitValue::argumentsObjectThatWasNotCreated();
6476
                
6653
                
6654
            case PhantomNewObject:
6655
                return ExitValue::materializeNewObject(map.get(node));
6656
                
6477
            default:
6657
            default:
6478
                break;
6658
                break;
6479
            }
6659
            }
Lines 6721-6727 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec18
6721
        m_out.unreachable();
6901
        m_out.unreachable();
6722
    }
6902
    }
6723
    
6903
    
6724
    Operands<Availability>& availability() { return m_availabilityCalculator.m_availability; }
6904
    AvailabilityMap& availabilityMap() { return m_availabilityCalculator.m_availability; }
6725
    
6905
    
6726
    VM& vm() { return m_graph.m_vm; }
6906
    VM& vm() { return m_graph.m_vm; }
6727
    CodeBlock* codeBlock() { return m_graph.m_codeBlock; }
6907
    CodeBlock* codeBlock() { return m_graph.m_codeBlock; }
- Source/JavaScriptCore/ftl/FTLOSRExit.h -1 / +2 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 160-165 struct OSRExit : public DFG::OSRExitBase Source/JavaScriptCore/ftl/FTLOSRExit.h_sec2
160
    unsigned m_patchableCodeOffset;
160
    unsigned m_patchableCodeOffset;
161
    
161
    
162
    Operands<ExitValue> m_values;
162
    Operands<ExitValue> m_values;
163
    Bag<ExitTimeObjectMaterialization> m_materializations;
163
    
164
    
164
    uint32_t m_stackmapID;
165
    uint32_t m_stackmapID;
165
    
166
    
- Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp -76 / +166 lines
Lines 46-51 namespace JSC { namespace FTL { Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp_sec1
46
46
47
using namespace DFG;
47
using namespace DFG;
48
48
49
static void compileRecovery(
50
    CCallHeleprs& jit, const ExitValue& value, StackMaps::Record* record, StackMaps& stackmaps,
51
    char *registerScratch,
52
    const HashMap<ExitTimeObjectMaterialization*, EncodedJSValue*>& materializationToPointer)
53
{
54
    switch (value.kind()) {
55
    case ExitValueDead:
56
        jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsUndefined())), GPRInfo::regT0);
57
        break;
58
            
59
    case ExitValueConstant:
60
        jit.move(MacroAssembler::TrustedImm64(JSValue::encode(value.constant())), GPRInfo::regT0);
61
        break;
62
            
63
    case ExitValueArgument:
64
        record->locations[value.exitArgument().argument()].restoreInto(
65
            jit, jitCode->stackmaps, registerScratch, GPRInfo::regT0);
66
        break;
67
            
68
    case ExitValueInJSStack:
69
    case ExitValueInJSStackAsInt32:
70
    case ExitValueInJSStackAsInt52:
71
    case ExitValueInJSStackAsDouble:
72
        jit.load64(AssemblyHelpers::addressFor(value.virtualRegister()), GPRInfo::regT0);
73
        break;
74
            
75
    case ExitValueArgumentsObjectThatWasNotCreated:
76
        // We can't actually recover this yet, but we can make the stack look sane. This is
77
        // a prerequisite to running the actual arguments recovery.
78
        jit.move(MacroAssembler::TrustedImm64(JSValue::encode(JSValue())), GPRInfo::regT0);
79
        break;
80
            
81
    case ExitValueRecovery:
82
        record->locations[value.rightRecoveryArgument()].restoreInto(
83
            jit, jitCode->stackmaps, registerScratch, GPRInfo::regT1);
84
        record->locations[value.leftRecoveryArgument()].restoreInto(
85
            jit, jitCode->stackmaps, registerScratch, GPRInfo::regT0);
86
        switch (value.recoveryOpcode()) {
87
        case AddRecovery:
88
            switch (value.recoveryFormat()) {
89
            case ValueFormatInt32:
90
                jit.add32(GPRInfo::regT1, GPRInfo::regT0);
91
                break;
92
            case ValueFormatInt52:
93
                jit.add64(GPRInfo::regT1, GPRInfo::regT0);
94
                break;
95
            default:
96
                RELEASE_ASSERT_NOT_REACHED();
97
                break;
98
            }
99
            break;
100
        case SubRecovery:
101
            switch (value.recoveryFormat()) {
102
            case ValueFormatInt32:
103
                jit.sub32(GPRInfo::regT1, GPRInfo::regT0);
104
                break;
105
            case ValueFormatInt52:
106
                jit.sub64(GPRInfo::regT1, GPRInfo::regT0);
107
                break;
108
            default:
109
                RELEASE_ASSERT_NOT_REACHED();
110
                break;
111
            }
112
            break;
113
        default:
114
            RELEASE_ASSERT_NOT_REACHED();
115
            break;
116
        }
117
        break;
118
        
119
    case ExitValueMaterializeNewObject:
120
        jit.loadPtr(materializationToPointer.get(value.objectMaterialization()), GPRInfo::regT0);
121
        break;
122
            
123
    default:
124
        RELEASE_ASSERT_NOT_REACHED();
125
        break;
126
    }
127
        
128
    reboxAccordingToFormat(
129
        value.valueFormat(), jit, GPRInfo::regT0, GPRInfo::regT1, GPRInfo::regT2);
130
}
131
49
static void compileStub(
132
static void compileStub(
50
    unsigned exitID, JITCode* jitCode, OSRExit& exit, VM* vm, CodeBlock* codeBlock)
133
    unsigned exitID, JITCode* jitCode, OSRExit& exit, VM* vm, CodeBlock* codeBlock)
51
{
134
{
Lines 64-76 static void compileStub( Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp_sec2
64
147
65
    CCallHelpers jit(vm, codeBlock);
148
    CCallHelpers jit(vm, codeBlock);
66
    
149
    
67
    // We need scratch space to save all registers and to build up the JSStack.
150
    // 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.
151
    // 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));
152
    // that we materialize.
153
    
154
    // Figure out how much space we need for those object allocations.
155
    unsigned numMaterializations = 0;
156
    unsigned maxMaterializationNumArguments = 0;
157
    for (ExitTimeObjectMaterialization* materialization : exit.m_materializations) {
158
        numMaterializations++;
159
        
160
        maxMaterializationNumArguments = std::max(
161
            maxMaterializationNumArguments,
162
            materialization.properties().size());
163
    }
164
    
165
    ScratchBuffer* scratchBuffer = vm->scratchBufferForSize(
166
        sizeof(EncodedJSValue) * (
167
            exit.m_values.size() + numMaterializations + maxMaterializationNumArguments) +
168
        requiredScratchMemorySizeInBytes() +
169
        jitCode->unwindInfo.m_registers.size() * sizeof(uint64_t));
70
    EncodedJSValue* scratch = scratchBuffer ? static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) : 0;
170
    EncodedJSValue* scratch = scratchBuffer ? static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) : 0;
71
    char* registerScratch = bitwise_cast<char*>(scratch + exit.m_values.size());
171
    EncodedJSValue* materializationPointers = scratch + exit.m_values.size();
172
    EncodedJSValue* materializationArguments = materializationPointers + numMaterializations;
173
    char* registerScratch = bitwise_cast<char*>(materializationArguments + maxMaterializationNumArguments);
72
    uint64_t* unwindScratch = bitwise_cast<uint64_t*>(registerScratch + requiredScratchMemorySizeInBytes());
174
    uint64_t* unwindScratch = bitwise_cast<uint64_t*>(registerScratch + requiredScratchMemorySizeInBytes());
73
    
175
    
176
    HashMap<ExitTimeObjectMaterialization*, EncodedJSValue*> materializationToPointer;
177
    unsigned materializationCount = 0;
178
    for (ExitTimeObjectMaterialization* materialization : exit.m_materializations) {
179
        materializationToPointer.add(
180
            materialization, materializationPointers + materializationCount++);
181
    }
182
    
74
    // Note that we come in here, the stack used to be as LLVM left it except that someone called pushToSave().
183
    // 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
184
    // 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().
185
    // that slot for saveAllRegisters().
Lines 120-205 static void compileStub( Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp_sec3
120
        if (!!exit.m_valueProfile)
229
        if (!!exit.m_valueProfile)
121
            jit.store64(GPRInfo::regT0, exit.m_valueProfile.getSpecFailBucket(0));
230
            jit.store64(GPRInfo::regT0, exit.m_valueProfile.getSpecFailBucket(0));
122
    }
231
    }
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
    
232
    
127
    for (unsigned index = exit.m_values.size(); index--;) {
233
    // Materialize all objects. Don't materialize an object until all of the objects it needs
128
        ExitValue value = exit.m_values[index];
234
    // have been materialized.
235
    HashSet<ExitTimeObjectMaterialization*> toMaterialize;
236
    for (ExitTimeObjectMaterialization* materialization : exit.m_materializations)
237
        toMaterialize.add(materialization);
238
    
239
    while (!toMaterialize.isEmpty()) {
240
        size_t previousToMaterializeSize = toMaterialize.size();
129
        
241
        
130
        switch (value.kind()) {
242
        Vector<ExitTimeObjectMaterialization*> worklist;
131
        case ExitValueDead:
243
        worklist.appendRange(toMaterialize.begin(), toMaterialize.end());
132
            jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsUndefined())), GPRInfo::regT0);
244
        for (ExitTimeObjectMaterialization* materialization : worklist) {
133
            break;
245
            // Check if we can do anything about this right now.
134
            
246
            bool allGood = true;
135
        case ExitValueConstant:
247
            for (ExitPropertyValue value : materialization->properties()) {
136
            jit.move(MacroAssembler::TrustedImm64(JSValue::encode(value.constant())), GPRInfo::regT0);
248
                if (!value.value().isObjectMaterialization())
137
            break;
249
                    continue;
138
            
250
                if (toMaterialize.contains(value.value().objectMaterialization())) {
139
        case ExitValueArgument:
251
                    // Gotta skip this one, since one of its fields points to a materialization
140
            record->locations[value.exitArgument().argument()].restoreInto(
252
                    // that hasn't been materialized.
141
                jit, jitCode->stackmaps, registerScratch, GPRInfo::regT0);
253
                    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;
254
                    break;
187
                }
255
                }
188
                break;
189
            default:
190
                RELEASE_ASSERT_NOT_REACHED();
191
                break;
192
            }
256
            }
193
            break;
257
            if (!allGood)
258
                continue;
194
            
259
            
195
        default:
260
            // All systems go for materializing the object. First we recover the values of all of
196
            RELEASE_ASSERT_NOT_REACHED();
261
            // its fields and then we call a function to actually allocate the beast.
197
            break;
262
            for (unsigned propertyIndex = materialization->properties().size(); propertyIndex--;) {
263
                const ExitValue& value = materialization->properties()[propertyIndex].value();
264
                compileRecovery(
265
                    jit, value, record, jitCode->stackmaps, registerScratch,
266
                    materializationToPointer);
267
                jit.storePtr(GPRInfo::regT0, materializationArguments + propertyIndex);
268
            }
269
            
270
            // This call assumes that we don't pass arguments on the stack.
271
            jit.setupArgumentsWithExecState(materialization, materializationArguments);
272
            jit.move(CCallHelpers::TrustedImmPtr(operationMaterializeObjectInOSR), GPRInfo::nonArgGPR0);
273
            jit.call(GPRInfo::nonArgGPR0);
274
            jit.storePtr(GPRInfo::returnValueGPR, materializationToPointer.get(materialization));
275
            
276
            // Let everyone know that we're done.
277
            toMaterialize.remove(materialization);
198
        }
278
        }
199
        
279
        
200
        reboxAccordingToFormat(
280
        // We expect progress! This ensures that we crash rather than looping infinitely if there
201
            value.valueFormat(), jit, GPRInfo::regT0, GPRInfo::regT1, GPRInfo::regT2);
281
        // is something broken about this fixpoint. Or, this could happen if we ever violate the
202
        
282
        // "materializations form a DAG" rule.
283
        RELEASE_ASSERT(toMaterialize.size() < previousToMaterializeSize);
284
    }
285
286
    // Save all state from wherever the exit data tells us it was, into the appropriate place in
287
    // the scratch buffer. This also does the reboxing.
288
    
289
    for (unsigned index = exit.m_values.size(); index--;) {
290
        compileRecovery(
291
            jit, exit.m_values[index], record, jitCode->stackmaps, registerScratch,
292
            materializationToPointer);
203
        jit.store64(GPRInfo::regT0, scratch + index);
293
        jit.store64(GPRInfo::regT0, scratch + index);
204
    }
294
    }
205
    
295
    
- Source/JavaScriptCore/ftl/FTLOperations.cpp +94 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
extern "C" JSCell* JIT_OPERATION operationNewObjectWithButterfly(ExecState*, Structure* structure)
34
{
35
    VM& vm = &exec->vm();
36
    NativeCallFrameTracer tracer(&vm, exec);
37
    
38
    Butterfly* buttefly = Butterfly::create(
39
        vm, nullptr, 0, structure->outOfLineCapacity(), false, IndexingHeader(), 0);
40
    
41
    return JSFinalObject::create(exec, structure, butterfly);
42
}
43
44
extern "C" JSCell* JIT_OPERATION operationMaterializeObjectInOSR(
45
    ExecState* exec, FTL::ExitTimeObjectMaterialization* materialization, EncodedJSValue* values)
46
{
47
    VM& vm = exec->vm();
48
    CodeBlock* codeBlock = exec->codeBlock();
49
50
    // We cannot GC. We've got pointers in evil places.
51
    DeferGCForAWhile deferGC(vm.heap);
52
    
53
    // In the future, we may have many different kinds of materializations. For now we just
54
    // materialize NewObject.
55
    RELEASE_ASSERT(materialization->type() == PhantomNewObject);
56
    
57
    // First figure out what the structure is.
58
    Structure* structure = nullptr;
59
    for (unsigned i = materialization.properties().size(); i--;) {
60
        const ExitPropertyValue& property = materialization.properties()[i];
61
        if (property.location() != BaselessPromotedHeapLocation(StructurePLoc))
62
            continue;
63
        
64
        structure = jsCast<Structure*>(JSValue::decode(values[i]));
65
    }
66
    RELEASE_ASSERT(structure);
67
    
68
    // Let's create that object!
69
    JSFinalObject* result = JSFinalObject::create(vm, structure);
70
    
71
    // Now figure out what the heck to populate the object with. Use getPropertiesConcurrently()
72
    // because that happens to be lower-level and more convenient. It doesn't change the
73
    // materialization of the property table. We want to have minimal visible effects on the
74
    // system. Also, don't mind that this is O(n^2). It doesn't matter. We only get here from OSR
75
    // exit.
76
    for (PropertyMapEntry entry : structure->getPropertiesConcurrently()) {
77
        for (unsigned i = materialization.properties().size(); i--;) {
78
            const ExitPropertyValue& property = materialization.properties()[i];
79
            if (property.location().kind() != NamedPropertyPLoc)
80
                continue;
81
            if (codeBlock->identifier(property.location().info()).impl() != entry.key)
82
                continue;
83
            
84
            result->putDirect(vm, entry.offset, JSValue::decode(values[i]));
85
        }
86
    }
87
    
88
    return result;
89
}
90
91
} } // namespace JSC::FTL
92
93
#endif // ENABLE(FTL_JIT)
94
- Source/JavaScriptCore/ftl/FTLOperations.h +49 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
33
namespace JSC { namespace FTL {
34
35
extern "C" {
36
37
JSCell* JIT_OPERATION operationNewObjectWithButterfly(ExecState*, Structure* primordialStructure, Structure* actualStructure) WTF_INTERNAL;
38
39
JSCell* JIT_OPERATION operationMaterializeObjectInOSR(
40
    ExecState*, FTL::ExitTimeObjectMaterialization*, EncodedJSValue*) WTF_INTERNAL;
41
42
} // extern "C"
43
44
} } // namespace JSC::DFG
45
46
#endif // ENABLE(FTL_JIT)
47
48
#endif // FTLOperations_h
49
- 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>

Return to Bug 136330