Source/JavaScriptCore/ChangeLog

 12013-02-20 Filip Pizlo <fpizlo@apple.com>
 2
 3 DFG should not change its mind about what type speculations a node does, by encoding the checks in the NodeType, UseKind, and ArrayMode
 4 https://bugs.webkit.org/show_bug.cgi?id=109371
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 FixupPhase now locks in the speculations that each node will do. The DFG then
 9 remembers those speculations, and doesn't change its mind about them even if the
 10 graph is transformed - for example if a node's child is repointed to a different
 11 node as part of CSE, CFG simplification, or folding. Each node ensures that it
 12 executes the speculations promised by its edges. This is true even for Phantom
 13 nodes.
 14
 15 This still leaves some craziness on the table for future work, like the
 16 elimination of speculating SetLocal's due to CFG simplification
 17 (webkit.org/b/109388) and elimination of nodes via DCE (webkit.org/b/109389).
 18
 19 In all, this allows for a huge simplification of the DFG. Instead of having to
 20 execute the right speculation heuristic each time you want to decide what a node
 21 does (for example Node::shouldSpeculateInteger(child1, child2) &&
 22 node->canSpeculateInteger()), you just ask for the use kinds of its children
 23 (typically node->binaryUseKind() == Int32Use). Because the use kinds are
 24 discrete, you can often just switch over them. This makes many parts of the code
 25 more clear than they were before.
 26
 27 Having UseKinds describe the speculations being performed also makes it far
 28 easier to perform analyses that need to know what speculations are done. This is
 29 so far only used to simplify large parts of the CFA.
 30
 31 To have a larger vocabulary of UseKinds, this also changes the node allocator to
 32 be able to round up Node sizes to the nearest multiple of 16.
 33
 34 This appears to be neutral on benchmarks, except for some goofy speed-ups, like
 35 8% on Octane/box2d.
 36
 37 * CMakeLists.txt:
 38 * GNUmakefile.list.am:
 39 * JavaScriptCore.xcodeproj/project.pbxproj:
 40 * Target.pri:
 41 * dfg/DFGAbstractState.cpp:
 42 (JSC::DFG::AbstractState::startExecuting):
 43 (DFG):
 44 (JSC::DFG::AbstractState::executeEdges):
 45 (JSC::DFG::AbstractState::verifyEdge):
 46 (JSC::DFG::AbstractState::verifyEdges):
 47 (JSC::DFG::AbstractState::executeEffects):
 48 (JSC::DFG::AbstractState::execute):
 49 * dfg/DFGAbstractState.h:
 50 (AbstractState):
 51 (JSC::DFG::AbstractState::filterEdgeByUse):
 52 (JSC::DFG::AbstractState::filterByType):
 53 * dfg/DFGAbstractValue.h:
 54 (JSC::DFG::AbstractValue::filter):
 55 * dfg/DFGAdjacencyList.h:
 56 (JSC::DFG::AdjacencyList::AdjacencyList):
 57 (JSC::DFG::AdjacencyList::child):
 58 (JSC::DFG::AdjacencyList::setChild):
 59 (JSC::DFG::AdjacencyList::reset):
 60 (JSC::DFG::AdjacencyList::firstChild):
 61 (JSC::DFG::AdjacencyList::setFirstChild):
 62 (JSC::DFG::AdjacencyList::numChildren):
 63 (JSC::DFG::AdjacencyList::setNumChildren):
 64 (AdjacencyList):
 65 * dfg/DFGAllocator.h:
 66 (DFG):
 67 (Allocator):
 68 (JSC::DFG::Allocator::cellSize):
 69 (JSC::DFG::Allocator::Region::headerSize):
 70 (JSC::DFG::Allocator::Region::numberOfThingsPerRegion):
 71 (JSC::DFG::Allocator::Region::payloadSize):
 72 (JSC::DFG::Allocator::Region::payloadBegin):
 73 (JSC::DFG::Allocator::Region::payloadEnd):
 74 (JSC::DFG::Allocator::Region::isInThisRegion):
 75 (JSC::DFG::::Allocator):
 76 (JSC::DFG::::~Allocator):
 77 (JSC::DFG::::allocate):
 78 (JSC::DFG::::free):
 79 (JSC::DFG::::freeAll):
 80 (JSC::DFG::::reset):
 81 (JSC::DFG::::indexOf):
 82 (JSC::DFG::::allocatorOf):
 83 (JSC::DFG::::bumpAllocate):
 84 (JSC::DFG::::freeListAllocate):
 85 (JSC::DFG::::allocateSlow):
 86 (JSC::DFG::::freeRegionsStartingAt):
 87 (JSC::DFG::::startBumpingIn):
 88 * dfg/DFGByteCodeParser.cpp:
 89 (JSC::DFG::ByteCodeParser::addToGraph):
 90 (JSC::DFG::ByteCodeParser::handleMinMax):
 91 * dfg/DFGCSEPhase.cpp:
 92 (JSC::DFG::CSEPhase::setLocalStoreElimination):
 93 (JSC::DFG::CSEPhase::eliminateIrrelevantPhantomChildren):
 94 (JSC::DFG::CSEPhase::setReplacement):
 95 (JSC::DFG::CSEPhase::performNodeCSE):
 96 * dfg/DFGCommon.h:
 97 (DFG):
 98 * dfg/DFGConstantFoldingPhase.cpp:
 99 (JSC::DFG::ConstantFoldingPhase::foldConstants):
 100 (JSC::DFG::ConstantFoldingPhase::addStructureTransitionCheck):
 101 * dfg/DFGDriver.cpp:
 102 (JSC::DFG::compile):
 103 * dfg/DFGEdge.cpp:
 104 (JSC::DFG::Edge::dump):
 105 * dfg/DFGEdge.h:
 106 (JSC::DFG::Edge::useKindUnchecked):
 107 (JSC::DFG::Edge::useKind):
 108 (JSC::DFG::Edge::shift):
 109 * dfg/DFGFixupPhase.cpp:
 110 (JSC::DFG::FixupPhase::run):
 111 (JSC::DFG::FixupPhase::fixupNode):
 112 (JSC::DFG::FixupPhase::checkArray):
 113 (JSC::DFG::FixupPhase::blessArrayOperation):
 114 (JSC::DFG::FixupPhase::fixIntEdge):
 115 (JSC::DFG::FixupPhase::fixDoubleEdge):
 116 (JSC::DFG::FixupPhase::injectInt32ToDoubleNode):
 117 (FixupPhase):
 118 (JSC::DFG::FixupPhase::truncateConstantToInt32):
 119 (JSC::DFG::FixupPhase::truncateConstantsIfNecessary):
 120 (JSC::DFG::FixupPhase::attemptToMakeIntegerAdd):
 121 * dfg/DFGGraph.cpp:
 122 (DFG):
 123 (JSC::DFG::Graph::refChildren):
 124 (JSC::DFG::Graph::derefChildren):
 125 * dfg/DFGGraph.h:
 126 (JSC::DFG::Graph::ref):
 127 (JSC::DFG::Graph::deref):
 128 (JSC::DFG::Graph::performSubstitution):
 129 (JSC::DFG::Graph::isPredictedNumerical):
 130 (JSC::DFG::Graph::addImmediateShouldSpeculateInteger):
 131 (DFG):
 132 * dfg/DFGNode.h:
 133 (JSC::DFG::Node::Node):
 134 (JSC::DFG::Node::convertToGetByOffset):
 135 (JSC::DFG::Node::convertToPutByOffset):
 136 (JSC::DFG::Node::willHaveCodeGenOrOSR):
 137 (JSC::DFG::Node::child1):
 138 (JSC::DFG::Node::child2):
 139 (JSC::DFG::Node::child3):
 140 (JSC::DFG::Node::binaryUseKind):
 141 (Node):
 142 (JSC::DFG::Node::isBinaryUseKind):
 143 * dfg/DFGNodeAllocator.h:
 144 (DFG):
 145 * dfg/DFGNodeFlags.cpp:
 146 (JSC::DFG::nodeFlagsAsString):
 147 * dfg/DFGNodeType.h:
 148 (DFG):
 149 * dfg/DFGPredictionPropagationPhase.cpp:
 150 (JSC::DFG::PredictionPropagationPhase::propagate):
 151 * dfg/DFGSpeculativeJIT.cpp:
 152 (JSC::DFG::SpeculativeJIT::speculationCheck):
 153 (DFG):
 154 (JSC::DFG::SpeculativeJIT::speculationWatchpoint):
 155 (JSC::DFG::SpeculativeJIT::forwardSpeculationCheck):
 156 (JSC::DFG::SpeculativeJIT::terminateSpeculativeExecution):
 157 (JSC::DFG::SpeculativeJIT::typeCheck):
 158 (JSC::DFG::SpeculativeJIT::forwardTypeCheck):
 159 (JSC::DFG::SpeculativeJIT::fillStorage):
 160 (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
 161 (JSC::DFG::SpeculativeJIT::compile):
 162 (JSC::DFG::SpeculativeJIT::compileDoublePutByVal):
 163 (JSC::DFG::SpeculativeJIT::compileValueToInt32):
 164 (JSC::DFG::SpeculativeJIT::compileInt32ToDouble):
 165 (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
 166 (JSC::DFG::SpeculativeJIT::compileInstanceOf):
 167 (JSC::DFG::SpeculativeJIT::compileAdd):
 168 (JSC::DFG::SpeculativeJIT::compileArithSub):
 169 (JSC::DFG::SpeculativeJIT::compileArithNegate):
 170 (JSC::DFG::SpeculativeJIT::compileArithMul):
 171 (JSC::DFG::SpeculativeJIT::compileArithMod):
 172 (JSC::DFG::SpeculativeJIT::compare):
 173 (JSC::DFG::SpeculativeJIT::compileStrictEq):
 174 (JSC::DFG::SpeculativeJIT::speculateInt32):
 175 (JSC::DFG::SpeculativeJIT::speculateNumber):
 176 (JSC::DFG::SpeculativeJIT::speculateRealNumber):
 177 (JSC::DFG::SpeculativeJIT::speculateBoolean):
 178 (JSC::DFG::SpeculativeJIT::speculateCell):
 179 (JSC::DFG::SpeculativeJIT::speculateObject):
 180 (JSC::DFG::SpeculativeJIT::speculateObjectOrOther):
 181 (JSC::DFG::SpeculativeJIT::speculateString):
 182 (JSC::DFG::SpeculativeJIT::speculateNotCell):
 183 (JSC::DFG::SpeculativeJIT::speculateOther):
 184 (JSC::DFG::SpeculativeJIT::speculate):
 185 * dfg/DFGSpeculativeJIT.h:
 186 (SpeculativeJIT):
 187 (JSC::DFG::SpeculativeJIT::valueOfNumberConstant):
 188 (JSC::DFG::SpeculativeJIT::needsTypeCheck):
 189 (JSC::DFG::IntegerOperand::IntegerOperand):
 190 (JSC::DFG::IntegerOperand::edge):
 191 (IntegerOperand):
 192 (JSC::DFG::IntegerOperand::node):
 193 (JSC::DFG::IntegerOperand::gpr):
 194 (JSC::DFG::IntegerOperand::use):
 195 (JSC::DFG::JSValueOperand::JSValueOperand):
 196 (JSValueOperand):
 197 (JSC::DFG::JSValueOperand::edge):
 198 (JSC::DFG::JSValueOperand::node):
 199 (JSC::DFG::JSValueOperand::gpr):
 200 (JSC::DFG::JSValueOperand::fill):
 201 (JSC::DFG::JSValueOperand::use):
 202 (JSC::DFG::StorageOperand::StorageOperand):
 203 (JSC::DFG::StorageOperand::edge):
 204 (StorageOperand):
 205 (JSC::DFG::StorageOperand::node):
 206 (JSC::DFG::StorageOperand::gpr):
 207 (JSC::DFG::StorageOperand::use):
 208 (JSC::DFG::SpeculateIntegerOperand::SpeculateIntegerOperand):
 209 (SpeculateIntegerOperand):
 210 (JSC::DFG::SpeculateIntegerOperand::edge):
 211 (JSC::DFG::SpeculateIntegerOperand::node):
 212 (JSC::DFG::SpeculateIntegerOperand::gpr):
 213 (JSC::DFG::SpeculateIntegerOperand::use):
 214 (JSC::DFG::SpeculateStrictInt32Operand::SpeculateStrictInt32Operand):
 215 (SpeculateStrictInt32Operand):
 216 (JSC::DFG::SpeculateStrictInt32Operand::edge):
 217 (JSC::DFG::SpeculateStrictInt32Operand::node):
 218 (JSC::DFG::SpeculateStrictInt32Operand::gpr):
 219 (JSC::DFG::SpeculateStrictInt32Operand::use):
 220 (JSC::DFG::SpeculateDoubleOperand::SpeculateDoubleOperand):
 221 (SpeculateDoubleOperand):
 222 (JSC::DFG::SpeculateDoubleOperand::edge):
 223 (JSC::DFG::SpeculateDoubleOperand::node):
 224 (JSC::DFG::SpeculateDoubleOperand::fpr):
 225 (JSC::DFG::SpeculateDoubleOperand::use):
 226 (JSC::DFG::SpeculateCellOperand::SpeculateCellOperand):
 227 (SpeculateCellOperand):
 228 (JSC::DFG::SpeculateCellOperand::edge):
 229 (JSC::DFG::SpeculateCellOperand::node):
 230 (JSC::DFG::SpeculateCellOperand::gpr):
 231 (JSC::DFG::SpeculateCellOperand::use):
 232 (JSC::DFG::SpeculateBooleanOperand::SpeculateBooleanOperand):
 233 (JSC::DFG::SpeculateBooleanOperand::edge):
 234 (SpeculateBooleanOperand):
 235 (JSC::DFG::SpeculateBooleanOperand::node):
 236 (JSC::DFG::SpeculateBooleanOperand::gpr):
 237 (JSC::DFG::SpeculateBooleanOperand::use):
 238 (DFG):
 239 * dfg/DFGSpeculativeJIT32_64.cpp:
 240 (JSC::DFG::SpeculativeJIT::fillInteger):
 241 (JSC::DFG::SpeculativeJIT::fillJSValue):
 242 (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
 243 (JSC::DFG::SpeculativeJIT::fillSpeculateInt):
 244 (JSC::DFG::SpeculativeJIT::fillSpeculateIntStrict):
 245 (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
 246 (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
 247 (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
 248 (JSC::DFG::SpeculativeJIT::compileObjectEquality):
 249 (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
 250 (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
 251 (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
 252 (JSC::DFG::SpeculativeJIT::compileLogicalNot):
 253 (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
 254 (JSC::DFG::SpeculativeJIT::emitBranch):
 255 (JSC::DFG::SpeculativeJIT::compile):
 256 * dfg/DFGSpeculativeJIT64.cpp:
 257 (JSC::DFG::SpeculativeJIT::fillInteger):
 258 (JSC::DFG::SpeculativeJIT::fillJSValue):
 259 (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
 260 (JSC::DFG::SpeculativeJIT::fillSpeculateInt):
 261 (JSC::DFG::SpeculativeJIT::fillSpeculateIntStrict):
 262 (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
 263 (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
 264 (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
 265 (JSC::DFG::SpeculativeJIT::compileObjectEquality):
 266 (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
 267 (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
 268 (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
 269 (JSC::DFG::SpeculativeJIT::compileLogicalNot):
 270 (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
 271 (JSC::DFG::SpeculativeJIT::emitBranch):
 272 (JSC::DFG::SpeculativeJIT::compile):
 273 * dfg/DFGStructureCheckHoistingPhase.cpp:
 274 (JSC::DFG::StructureCheckHoistingPhase::run):
 275 * dfg/DFGUseKind.cpp: Added.
 276 (WTF):
 277 (WTF::printInternal):
 278 * dfg/DFGUseKind.h: Added.
 279 (DFG):
 280 (JSC::DFG::typeFilterFor):
 281 (JSC::DFG::isNumerical):
 282 (WTF):
 283 * dfg/DFGValidate.cpp:
 284 (JSC::DFG::Validate::reportValidationContext):
 285
12862013-02-20 Filip Pizlo <fpizlo@apple.com>
2287
3288 DFG inlines Resolves that it doesn't know how to handle correctly
143562

Source/JavaScriptCore/CMakeLists.txt

@@set(JavaScriptCore_SOURCES
113113 dfg/DFGStructureCheckHoistingPhase.cpp
114114 dfg/DFGThunks.cpp
115115 dfg/DFGUnificationPhase.cpp
 116 dfg/DFGUseKind.cpp
116117 dfg/DFGValueSource.cpp
117118 dfg/DFGVariableAccessDataDump.cpp
118119 dfg/DFGVariableEvent.cpp
143562

Source/JavaScriptCore/GNUmakefile.list.am

@@javascriptcore_sources += \
272272 Source/JavaScriptCore/dfg/DFGThunks.h \
273273 Source/JavaScriptCore/dfg/DFGUnificationPhase.cpp \
274274 Source/JavaScriptCore/dfg/DFGUnificationPhase.h \
 275 Source/JavaScriptCore/dfg/DFGUseKind.cpp \
 276 Source/JavaScriptCore/dfg/DFGUseKind.h \
275277 Source/JavaScriptCore/dfg/DFGValueRecoveryOverride.h \
276278 Source/JavaScriptCore/dfg/DFGValueSource.cpp \
277279 Source/JavaScriptCore/dfg/DFGValueSource.h \
143562

Source/JavaScriptCore/Target.pri

@@SOURCES += \
149149 dfg/DFGStructureCheckHoistingPhase.cpp \
150150 dfg/DFGThunks.cpp \
151151 dfg/DFGUnificationPhase.cpp \
 152 dfg/DFGUseKind.cpp \
152153 dfg/DFGValueSource.cpp \
153154 dfg/DFGVariableAccessDataDump.cpp \
154155 dfg/DFGVariableEvent.cpp \
143562

Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

109109 0F2C557014738F3500121E4F /* DFGCodeBlocks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2C556D14738F2E00121E4F /* DFGCodeBlocks.cpp */; };
110110 0F2E892C16D028AD009E4FD2 /* UnusedPointer.h in Headers */ = {isa = PBXBuildFile; fileRef = 65987F2F16828A7E003C2F8D /* UnusedPointer.h */; settings = {ATTRIBUTES = (Private, ); }; };
111111 0F2E892D16D02BAF009E4FD2 /* DFGMinifiedID.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB4B51016B3A964003F696B /* DFGMinifiedID.h */; settings = {ATTRIBUTES = (Private, ); }; };
 112 0F34B14916D42010001CDA5A /* DFGUseKind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F34B14716D4200E001CDA5A /* DFGUseKind.cpp */; };
 113 0F34B14A16D42013001CDA5A /* DFGUseKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F34B14816D4200E001CDA5A /* DFGUseKind.h */; settings = {ATTRIBUTES = (Private, ); }; };
112114 0F34B14C16D43E0D001CDA5A /* PolymorphicAccessStructureList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F34B14B16D43E0C001CDA5A /* PolymorphicAccessStructureList.h */; settings = {ATTRIBUTES = (Private, ); }; };
113115 0F3B3A1A153E68F2003ED0FF /* DFGConstantFoldingPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3B3A17153E68EF003ED0FF /* DFGConstantFoldingPhase.cpp */; };
114116 0F3B3A1B153E68F4003ED0FF /* DFGConstantFoldingPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3B3A18153E68EF003ED0FF /* DFGConstantFoldingPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };

10011003 0F2BDC5015228FFA00CD8910 /* DFGVariableEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGVariableEvent.cpp; path = dfg/DFGVariableEvent.cpp; sourceTree = "<group>"; };
10021004 0F2C556D14738F2E00121E4F /* DFGCodeBlocks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DFGCodeBlocks.cpp; sourceTree = "<group>"; };
10031005 0F2C556E14738F2E00121E4F /* DFGCodeBlocks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DFGCodeBlocks.h; sourceTree = "<group>"; };
 1006 0F34B14716D4200E001CDA5A /* DFGUseKind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGUseKind.cpp; path = dfg/DFGUseKind.cpp; sourceTree = "<group>"; };
 1007 0F34B14816D4200E001CDA5A /* DFGUseKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGUseKind.h; path = dfg/DFGUseKind.h; sourceTree = "<group>"; };
10041008 0F34B14B16D43E0C001CDA5A /* PolymorphicAccessStructureList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PolymorphicAccessStructureList.h; sourceTree = "<group>"; };
10051009 0F3B3A17153E68EF003ED0FF /* DFGConstantFoldingPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGConstantFoldingPhase.cpp; path = dfg/DFGConstantFoldingPhase.cpp; sourceTree = "<group>"; };
10061010 0F3B3A18153E68EF003ED0FF /* DFGConstantFoldingPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGConstantFoldingPhase.h; path = dfg/DFGConstantFoldingPhase.h; sourceTree = "<group>"; };

27092713 0FC097A0146B28C700CF2442 /* DFGThunks.h */,
27102714 0FBE0F6F16C1DB010082C5E8 /* DFGUnificationPhase.cpp */,
27112715 0FBE0F7016C1DB010082C5E8 /* DFGUnificationPhase.h */,
 2716 0F34B14716D4200E001CDA5A /* DFGUseKind.cpp */,
 2717 0F34B14816D4200E001CDA5A /* DFGUseKind.h */,
27122718 0F3B3A2915474FF4003ED0FF /* DFGValidate.cpp */,
27132719 0F3B3A2A15474FF4003ED0FF /* DFGValidate.h */,
27142720 0F2BDC3F1522801700CD8910 /* DFGValueRecoveryOverride.h */,

32513257 868916B0155F286300CB2B9A /* PrivateName.h in Headers */,
32523258 BC18C4500E16F5CD00B34460 /* Profile.h in Headers */,
32533259 95CD45770E1C4FDD0085358E /* ProfileGenerator.h in Headers */,
 3260 0F34B14A16D42013001CDA5A /* DFGUseKind.h in Headers */,
32543261 BC18C4510E16F5CD00B34460 /* ProfileNode.h in Headers */,
32553262 0FF729A5166AD351000F5BA3 /* ProfilerBytecode.h in Headers */,
32563263 0FF729B9166AD360000F5BA3 /* ProfilerBytecodes.h in Headers */,

39573964 0FF729B0166AD35C000F5BA3 /* ProfilerCompilationKind.cpp in Sources */,
39583965 0FF729B1166AD35C000F5BA3 /* ProfilerCompiledBytecode.cpp in Sources */,
39593966 0FF729B2166AD35C000F5BA3 /* ProfilerDatabase.cpp in Sources */,
 3967 0F34B14916D42010001CDA5A /* DFGUseKind.cpp in Sources */,
39603968 0FF729B3166AD35C000F5BA3 /* ProfilerOrigin.cpp in Sources */,
39613969 0FF729B4166AD35C000F5BA3 /* ProfilerOriginStack.cpp in Sources */,
39623970 0FB1058B1675483100F8AB6E /* ProfilerOSRExit.cpp in Sources */,
143562

Source/JavaScriptCore/dfg/DFGAbstractState.cpp

@@AbstractState::BooleanResult AbstractSta
234234 return UnknownBooleanResult;
235235}
236236
237 bool AbstractState::execute(unsigned indexInBlock)
 237bool AbstractState::startExecuting(Node* node)
238238{
239239 ASSERT(m_block);
240240 ASSERT(m_isValid);
241241
242242 m_didClobber = false;
243243
244  Node* node = m_block->at(indexInBlock);
245 
 244 node->setCanExit(false);
 245
246246 if (!node->shouldGenerate())
247  return true;
248 
 247 return false;
 248
 249 return true;
 250}
 251
 252bool AbstractState::startExecuting(unsigned indexInBlock)
 253{
 254 return startExecuting(m_block->at(indexInBlock));
 255}
 256
 257void AbstractState::executeEdges(Node* node)
 258{
 259 DFG_NODE_DO_TO_CHILDREN(m_graph, node, filterEdgeByUse);
 260}
 261
 262void AbstractState::executeEdges(unsigned indexInBlock)
 263{
 264 executeEdges(m_block->at(indexInBlock));
 265}
 266
 267void AbstractState::verifyEdge(Node*, Edge edge)
 268{
 269 RELEASE_ASSERT(!(forNode(edge).m_type & ~typeFilterFor(edge.useKind())));
 270}
 271
 272void AbstractState::verifyEdges(Node* node)
 273{
 274 DFG_NODE_DO_TO_CHILDREN(m_graph, node, verifyEdge);
 275}
 276
 277bool AbstractState::executeEffects(unsigned indexInBlock, Node* node)
 278{
 279 if (!ASSERT_DISABLED)
 280 verifyEdges(node);
 281
249282 switch (node->op()) {
250283 case JSConstant:
251284 case WeakJSConstant:
252285 case PhantomArguments: {
253286 forNode(node).set(m_graph.valueOfJSConstant(node));
254  node->setCanExit(false);
255287 break;
256288 }
257289
258290 case Identity: {
259291 forNode(node) = forNode(node->child1());
260  node->setCanExit(false);
261292 break;
262293 }
263294

@@bool AbstractState::execute(unsigned ind
265296 VariableAccessData* variableAccessData = node->variableAccessData();
266297 if (variableAccessData->prediction() == SpecNone) {
267298 m_isValid = false;
268  node->setCanExit(true);
269299 break;
270300 }
271  bool canExit = false;
272301 AbstractValue value = m_variables.operand(variableAccessData->local());
273302 if (!variableAccessData->isCaptured()) {
274303 if (value.isClear())
275  canExit |= true;
 304 node->setCanExit(true);
276305 }
277306 if (value.value())
278307 m_foundConstants = true;
279308 forNode(node) = value;
280  node->setCanExit(canExit);
281309 break;
282310 }
283311

@@bool AbstractState::execute(unsigned ind
286314 if (value.value())
287315 m_foundConstants = true;
288316 forNode(node) = value;
289  node->setCanExit(false);
290317 break;
291318 }
292319
293320 case SetLocal: {
294  if (node->variableAccessData()->isCaptured()
295  || m_graph.isCreatedThisArgument(node->local())) {
296  m_variables.operand(node->local()) = forNode(node->child1());
297  node->setCanExit(false);
298  break;
299  }
300 
301  if (node->variableAccessData()->shouldUseDoubleFormat()) {
302  speculateNumberUnary(node);
303  m_variables.operand(node->local()).set(SpecDouble);
304  break;
305  }
306 
307  SpeculatedType predictedType = node->variableAccessData()->argumentAwarePrediction();
308  if (isInt32Speculation(predictedType))
309  speculateInt32Unary(node);
310  else if (isCellSpeculation(predictedType)) {
311  node->setCanExit(!isCellSpeculation(forNode(node->child1()).m_type));
312  forNode(node->child1()).filter(SpecCell);
313  } else if (isBooleanSpeculation(predictedType))
314  speculateBooleanUnary(node);
315  else
316  node->setCanExit(false);
317 
318321 m_variables.operand(node->local()) = forNode(node->child1());
319322 break;
320323 }

@@bool AbstractState::execute(unsigned ind
322325 case SetArgument:
323326 // Assert that the state of arguments has been set.
324327 ASSERT(!m_block->valuesAtHead.operand(node->local()).isClear());
325  node->setCanExit(false);
326328 break;
327329
328330 case BitAnd:

@@bool AbstractState::execute(unsigned ind
362364 }
363365 if (constantWasSet) {
364366 m_foundConstants = true;
365  node->setCanExit(false);
366367 break;
367368 }
368369 }
369  speculateInt32Binary(node);
370370 forNode(node).set(SpecInt32);
371371 break;
372372 }

@@bool AbstractState::execute(unsigned ind
377377 ASSERT(child.isInt32());
378378 if (trySetConstant(node, JSValue(child.asUInt32()))) {
379379 m_foundConstants = true;
380  node->setCanExit(false);
381380 break;
382381 }
383382 }
384  if (!node->canSpeculateInteger()) {
 383 if (!node->canSpeculateInteger())
385384 forNode(node).set(SpecDouble);
386  node->setCanExit(false);
387  } else {
 385 else {
388386 forNode(node).set(SpecInt32);
389387 node->setCanExit(true);
390388 }
391389 break;
392390 }
393 
394391
395392 case DoubleAsInt32: {
396393 JSValue child = forNode(node->child1()).value();

@@bool AbstractState::execute(unsigned ind
404401 }
405402 }
406403 node->setCanExit(true);
407  forNode(node->child1()).filter(SpecNumber);
408404 forNode(node).set(SpecInt32);
409405 break;
410406 }

@@bool AbstractState::execute(unsigned ind
419415 constantWasSet = trySetConstant(node, JSValue(JSC::toInt32(child.asDouble())));
420416 if (constantWasSet) {
421417 m_foundConstants = true;
422  node->setCanExit(false);
423418 break;
424419 }
425420 }
426  if (node->child1()->shouldSpeculateInteger())
427  speculateInt32Unary(node);
428  else if (node->child1()->shouldSpeculateBoolean())
429  speculateBooleanUnary(node);
430  else if (node->child1()->shouldSpeculateNumber())
431  speculateNumberUnary(node);
432  else {
433  node->setCanExit(forNode(node->child1()).m_type & SpecCell);
434  forNode(node->child1()).filter(~SpecCell);
435  }
436421
437422 forNode(node).set(SpecInt32);
438423 break;

@@bool AbstractState::execute(unsigned ind
444429 if (child && child.isNumber()
445430 && trySetConstant(node, JSValue(JSValue::EncodeAsDouble, child.asNumber()))) {
446431 m_foundConstants = true;
447  node->setCanExit(false);
448432 break;
449433 }
450  speculateNumberUnary(node);
451434 if (isInt32Speculation(forNode(node->child1()).m_type))
452435 forNode(node).set(SpecDoubleReal);
453436 else

@@bool AbstractState::execute(unsigned ind
455438 break;
456439 }
457440
458  case CheckNumber:
459  forNode(node->child1()).filter(SpecNumber);
460  break;
461 
462441 case ValueAdd:
463442 case ArithAdd: {
464443 JSValue left = forNode(node->child1()).value();

@@bool AbstractState::execute(unsigned ind
466445 if (left && right && left.isNumber() && right.isNumber()
467446 && trySetConstant(node, JSValue(left.asNumber() + right.asNumber()))) {
468447 m_foundConstants = true;
469  node->setCanExit(false);
470448 break;
471449 }
472  if (m_graph.addShouldSpeculateInteger(node)) {
473  speculateInt32Binary(
474  node, !nodeCanTruncateInteger(node->arithNodeFlags()));
 450 switch (node->binaryUseKind()) {
 451 case Int32Use:
475452 forNode(node).set(SpecInt32);
 453 if (!nodeCanTruncateInteger(node->arithNodeFlags()))
 454 node->setCanExit(true);
476455 break;
477  }
478  if (Node::shouldSpeculateNumberExpectingDefined(node->child1().node(), node->child2().node())) {
479  speculateNumberBinary(node);
 456 case NumberUse:
480457 if (isRealNumberSpeculation(forNode(node->child1()).m_type)
481458 && isRealNumberSpeculation(forNode(node->child2()).m_type))
482459 forNode(node).set(SpecDoubleReal);
483460 else
484461 forNode(node).set(SpecDouble);
485462 break;
486  }
487  if (node->op() == ValueAdd) {
 463 default:
 464 RELEASE_ASSERT(node->op() == ValueAdd);
488465 clobberWorld(node->codeOrigin, indexInBlock);
489466 forNode(node).set(SpecString | SpecInt32 | SpecNumber);
490  node->setCanExit(false);
491467 break;
492468 }
493  // We don't handle this yet. :-(
494  m_isValid = false;
495  node->setCanExit(true);
496469 break;
497470 }
498471

@@bool AbstractState::execute(unsigned ind
502475 if (left && right && left.isNumber() && right.isNumber()
503476 && trySetConstant(node, JSValue(left.asNumber() - right.asNumber()))) {
504477 m_foundConstants = true;
505  node->setCanExit(false);
506478 break;
507479 }
508  if (m_graph.addShouldSpeculateInteger(node)) {
509  speculateInt32Binary(
510  node, !nodeCanTruncateInteger(node->arithNodeFlags()));
 480 switch (node->binaryUseKind()) {
 481 case Int32Use:
511482 forNode(node).set(SpecInt32);
 483 if (!nodeCanTruncateInteger(node->arithNodeFlags()))
 484 node->setCanExit(true);
 485 break;
 486 case NumberUse:
 487 forNode(node).set(SpecDouble);
 488 break;
 489 default:
 490 RELEASE_ASSERT_NOT_REACHED();
512491 break;
513492 }
514  speculateNumberBinary(node);
515  forNode(node).set(SpecDouble);
516493 break;
517494 }
518495

@@bool AbstractState::execute(unsigned ind
521498 if (child && child.isNumber()
522499 && trySetConstant(node, JSValue(-child.asNumber()))) {
523500 m_foundConstants = true;
524  node->setCanExit(false);
525501 break;
526502 }
527  if (m_graph.negateShouldSpeculateInteger(node)) {
528  speculateInt32Unary(
529  node, !nodeCanTruncateInteger(node->arithNodeFlags()));
 503 switch (node->child1().useKind()) {
 504 case Int32Use:
530505 forNode(node).set(SpecInt32);
 506 if (!nodeCanTruncateInteger(node->arithNodeFlags()))
 507 node->setCanExit(true);
 508 break;
 509 case NumberUse:
 510 forNode(node).set(SpecDouble);
 511 break;
 512 default:
 513 RELEASE_ASSERT_NOT_REACHED();
531514 break;
532515 }
533  speculateNumberUnary(node);
534  forNode(node).set(SpecDouble);
535516 break;
536517 }
537518

@@bool AbstractState::execute(unsigned ind
541522 if (left && right && left.isNumber() && right.isNumber()
542523 && trySetConstant(node, JSValue(left.asNumber() * right.asNumber()))) {
543524 m_foundConstants = true;
544  node->setCanExit(false);
545525 break;
546526 }
547  if (m_graph.mulShouldSpeculateInteger(node)) {
548  speculateInt32Binary(
549  node,
550  !nodeCanTruncateInteger(node->arithNodeFlags())
551  || !nodeCanIgnoreNegativeZero(node->arithNodeFlags()));
 527 switch (node->binaryUseKind()) {
 528 case Int32Use:
552529 forNode(node).set(SpecInt32);
 530 if (!nodeCanTruncateInteger(node->arithNodeFlags())
 531 || !nodeCanIgnoreNegativeZero(node->arithNodeFlags()))
 532 node->setCanExit(true);
 533 break;
 534 case NumberUse:
 535 if (isRealNumberSpeculation(forNode(node->child1()).m_type)
 536 || isRealNumberSpeculation(forNode(node->child2()).m_type))
 537 forNode(node).set(SpecDoubleReal);
 538 else
 539 forNode(node).set(SpecDouble);
 540 break;
 541 default:
 542 RELEASE_ASSERT_NOT_REACHED();
553543 break;
554544 }
555  speculateNumberBinary(node);
556  if (isRealNumberSpeculation(forNode(node->child1()).m_type)
557  || isRealNumberSpeculation(forNode(node->child2()).m_type))
558  forNode(node).set(SpecDoubleReal);
559  else
560  forNode(node).set(SpecDouble);
561545 break;
562546 }
563547

@@bool AbstractState::execute(unsigned ind
591575 }
592576 if (constantWasSet) {
593577 m_foundConstants = true;
594  node->setCanExit(false);
595578 break;
596579 }
597580 }
598  if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node())
599  && node->canSpeculateInteger()) {
600  speculateInt32Binary(node, true); // forcing can-exit, which is a bit on the conservative side.
 581 switch (node->binaryUseKind()) {
 582 case Int32Use:
601583 forNode(node).set(SpecInt32);
 584 node->setCanExit(true);
 585 break;
 586 case NumberUse:
 587 forNode(node).set(SpecDouble);
 588 break;
 589 default:
 590 RELEASE_ASSERT_NOT_REACHED();
602591 break;
603592 }
604  speculateNumberBinary(node);
605  forNode(node).set(SpecDouble);
606593 break;
607594 }
608595

@@bool AbstractState::execute(unsigned ind
611598 if (child && child.isNumber()
612599 && trySetConstant(node, JSValue(fabs(child.asNumber())))) {
613600 m_foundConstants = true;
614  node->setCanExit(false);
615601 break;
616602 }
617  if (node->child1()->shouldSpeculateIntegerForArithmetic()
618  && node->canSpeculateInteger()) {
619  speculateInt32Unary(node, true);
 603 switch (node->child1().useKind()) {
 604 case Int32Use:
620605 forNode(node).set(SpecInt32);
 606 node->setCanExit(true);
 607 break;
 608 case NumberUse:
 609 forNode(node).set(SpecDouble);
 610 break;
 611 default:
 612 RELEASE_ASSERT_NOT_REACHED();
621613 break;
622614 }
623  speculateNumberUnary(node);
624  forNode(node).set(SpecDouble);
625615 break;
626616 }
627617

@@bool AbstractState::execute(unsigned ind
630620 if (child && child.isNumber()
631621 && trySetConstant(node, JSValue(sqrt(child.asNumber())))) {
632622 m_foundConstants = true;
633  node->setCanExit(false);
634623 break;
635624 }
636  speculateNumberUnary(node);
637625 forNode(node).set(SpecDouble);
638626 break;
639627 }

@@bool AbstractState::execute(unsigned ind
652640 }
653641 if (didSetConstant) {
654642 m_foundConstants = true;
655  node->setCanExit(false);
656643 break;
657644 }
658  Node* child = node->child1().node();
659  if (isBooleanSpeculation(child->prediction()))
660  speculateBooleanUnary(node);
661  else if (child->shouldSpeculateObjectOrOther()) {
 645 switch (node->child1().useKind()) {
 646 case BooleanUse:
 647 case Int32Use:
 648 case NumberUse:
 649 case UntypedUse:
 650 break;
 651 case ObjectOrOtherUse:
662652 node->setCanExit(true);
663  forNode(child).filter((SpecCell & ~SpecString) | SpecOther);
664  } else if (child->shouldSpeculateInteger())
665  speculateInt32Unary(node);
666  else if (child->shouldSpeculateNumber())
667  speculateNumberUnary(node);
668  else
669  node->setCanExit(false);
 653 break;
 654 default:
 655 RELEASE_ASSERT_NOT_REACHED();
 656 break;
 657 }
670658 forNode(node).set(SpecBoolean);
671659 break;
672660 }

@@bool AbstractState::execute(unsigned ind
764752 break;
765753 }
766754 }
767 
768  Node* childNode = node->child1().node();
769  if (isCellSpeculation(childNode->prediction())) {
770  if (isStringSpeculation(childNode->prediction()))
771  forNode(childNode).filter(SpecString);
772  else
773  forNode(childNode).filter(SpecCell);
 755
 756 switch (node->child1().useKind()) {
 757 case StringUse:
 758 case CellUse:
774759 node->setCanExit(true);
 760 break;
 761 case UntypedUse:
 762 break;
 763 default:
 764 RELEASE_ASSERT_NOT_REACHED();
 765 break;
775766 }
776767 forNode(node).set(SpecString);
777768 break;

@@bool AbstractState::execute(unsigned ind
823814
824815 if (constantWasSet) {
825816 m_foundConstants = true;
826  node->setCanExit(false);
827817 break;
828818 }
829819
830820 forNode(node).set(SpecBoolean);
831821
832  if (node->op() == CompareEqConstant) {
833  // We can exit if we haven't fired the MasqueradesAsUndefind watchpoint yet.
834  node->setCanExit(m_codeBlock->globalObjectFor(node->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid());
835  break;
836  }
837 
838  Node* left = node->child1().node();
839  Node* right = node->child2().node();
840  SpeculatedType filter;
841  SpeculatedTypeChecker checker;
842  if (Node::shouldSpeculateInteger(left, right)) {
843  filter = SpecInt32;
844  checker = isInt32Speculation;
845  } else if (Node::shouldSpeculateNumber(left, right)) {
846  filter = SpecNumber;
847  checker = isNumberSpeculation;
848  } else if (node->op() == CompareEq) {
849  if (left->shouldSpeculateString() || right->shouldSpeculateString()) {
850  node->setCanExit(false);
851  break;
852  }
853  if (left->shouldSpeculateObject() && right->shouldSpeculateObject()) {
854  node->setCanExit(true);
855  forNode(left).filter(SpecObject);
856  forNode(right).filter(SpecObject);
857  break;
858  }
859  if (left->shouldSpeculateObject() && right->shouldSpeculateObjectOrOther()) {
860  node->setCanExit(true);
861  forNode(left).filter(SpecObject);
862  forNode(right).filter(SpecObject | SpecOther);
863  break;
864  }
865  if (left->shouldSpeculateObjectOrOther() && right->shouldSpeculateObject()) {
866  node->setCanExit(true);
867  forNode(left).filter(SpecObject | SpecOther);
868  forNode(right).filter(SpecObject);
869  break;
870  }
871 
872  filter = SpecTop;
873  checker = isAnySpeculation;
874  clobberWorld(node->codeOrigin, indexInBlock);
875  } else {
876  filter = SpecTop;
877  checker = isAnySpeculation;
878  clobberWorld(node->codeOrigin, indexInBlock);
879  }
880  node->setCanExit(
881  !checker(forNode(left).m_type)
882  || !checker(forNode(right).m_type));
883  forNode(left).filter(filter);
884  forNode(right).filter(filter);
 822 // This is overly conservative. But the only thing this prevents is store elimination,
 823 // and how likely is it, really, that you'll have redundant stores across a comparison
 824 // operation? Comparison operations are typically at the end of basic blocks, so
 825 // unless we have global store elimination (super unlikely given how unprofitable that
 826 // optimization is to begin with), you aren't going to be wanting to store eliminate
 827 // across an equality op.
 828 node->setCanExit(true);
885829 break;
886830 }
887831

@@bool AbstractState::execute(unsigned ind
894838 if (left && right && left.isNumber() && right.isNumber()
895839 && trySetConstant(node, jsBoolean(left.asNumber() == right.asNumber()))) {
896840 m_foundConstants = true;
897  node->setCanExit(false);
898841 break;
899842 }
900843 forNode(node).set(SpecBoolean);
901  if (node->op() == CompareStrictEqConstant) {
902  node->setCanExit(false);
903  break;
904  }
905  if (Node::shouldSpeculateInteger(leftNode, rightNode)) {
906  speculateInt32Binary(node);
907  break;
908  }
909  if (Node::shouldSpeculateNumber(leftNode, rightNode)) {
910  speculateNumberBinary(node);
911  break;
912  }
913  if (leftNode->shouldSpeculateString() || rightNode->shouldSpeculateString()) {
914  node->setCanExit(false);
915  break;
916  }
917  if (leftNode->shouldSpeculateObject() && rightNode->shouldSpeculateObject()) {
918  node->setCanExit(true);
919  forNode(leftNode).filter(SpecObject);
920  forNode(rightNode).filter(SpecObject);
921  break;
922  }
923  node->setCanExit(false);
 844 node->setCanExit(true); // This is overly conservative.
924845 break;
925846 }
926847
927848 case StringCharCodeAt:
928849 node->setCanExit(true);
929  forNode(node->child1()).filter(SpecString);
930  forNode(node->child2()).filter(SpecInt32);
931850 forNode(node).set(SpecInt32);
932851 break;
933852
934853 case StringCharAt:
935854 node->setCanExit(true);
936  forNode(node->child1()).filter(SpecString);
937  forNode(node->child2()).filter(SpecInt32);
938855 forNode(node).set(SpecString);
939856 break;
940857

@@bool AbstractState::execute(unsigned ind
954871 forNode(node).makeTop();
955872 break;
956873 case Array::String:
957  forNode(node->child2()).filter(SpecInt32);
958874 forNode(node).set(SpecString);
959875 break;
960876 case Array::Arguments:
961  forNode(node->child2()).filter(SpecInt32);
962877 forNode(node).makeTop();
963878 break;
964879 case Array::Int32:
965  forNode(node->child2()).filter(SpecInt32);
966880 if (node->arrayMode().isOutOfBounds()) {
967881 clobberWorld(node->codeOrigin, indexInBlock);
968882 forNode(node).makeTop();

@@bool AbstractState::execute(unsigned ind
970884 forNode(node).set(SpecInt32);
971885 break;
972886 case Array::Double:
973  forNode(node->child2()).filter(SpecInt32);
974887 if (node->arrayMode().isOutOfBounds()) {
975888 clobberWorld(node->codeOrigin, indexInBlock);
976889 forNode(node).makeTop();

@@bool AbstractState::execute(unsigned ind
982895 case Array::Contiguous:
983896 case Array::ArrayStorage:
984897 case Array::SlowPutArrayStorage:
985  forNode(node->child2()).filter(SpecInt32);
986898 if (node->arrayMode().isOutOfBounds())
987899 clobberWorld(node->codeOrigin, indexInBlock);
988900 forNode(node).makeTop();
989901 break;
990902 case Array::Int8Array:
991  forNode(node->child2()).filter(SpecInt32);
992903 forNode(node).set(SpecInt32);
993904 break;
994905 case Array::Int16Array:
995  forNode(node->child2()).filter(SpecInt32);
996906 forNode(node).set(SpecInt32);
997907 break;
998908 case Array::Int32Array:
999  forNode(node->child2()).filter(SpecInt32);
1000909 forNode(node).set(SpecInt32);
1001910 break;
1002911 case Array::Uint8Array:
1003  forNode(node->child2()).filter(SpecInt32);
1004912 forNode(node).set(SpecInt32);
1005913 break;
1006914 case Array::Uint8ClampedArray:
1007  forNode(node->child2()).filter(SpecInt32);
1008915 forNode(node).set(SpecInt32);
1009916 break;
1010917 case Array::Uint16Array:
1011  forNode(node->child2()).filter(SpecInt32);
1012918 forNode(node).set(SpecInt32);
1013919 break;
1014920 case Array::Uint32Array:
1015  forNode(node->child2()).filter(SpecInt32);
1016921 if (node->shouldSpeculateInteger())
1017922 forNode(node).set(SpecInt32);
1018923 else
1019924 forNode(node).set(SpecDouble);
1020925 break;
1021926 case Array::Float32Array:
1022  forNode(node->child2()).filter(SpecInt32);
1023927 forNode(node).set(SpecDouble);
1024928 break;
1025929 case Array::Float64Array:
1026  forNode(node->child2()).filter(SpecInt32);
1027930 forNode(node).set(SpecDouble);
1028931 break;
1029932 default:

@@bool AbstractState::execute(unsigned ind
1036939 case PutByVal:
1037940 case PutByValAlias: {
1038941 node->setCanExit(true);
1039  Edge child1 = m_graph.varArgChild(node, 0);
1040  Edge child2 = m_graph.varArgChild(node, 1);
1041  Edge child3 = m_graph.varArgChild(node, 2);
1042942 switch (node->arrayMode().modeForPut().type()) {
1043943 case Array::ForceExit:
1044944 m_isValid = false;

@@bool AbstractState::execute(unsigned ind
1047947 clobberWorld(node->codeOrigin, indexInBlock);
1048948 break;
1049949 case Array::Int32:
1050  forNode(child1).filter(SpecCell);
1051  forNode(child2).filter(SpecInt32);
1052  forNode(child3).filter(SpecInt32);
1053950 if (node->arrayMode().isOutOfBounds())
1054951 clobberWorld(node->codeOrigin, indexInBlock);
1055952 break;
1056953 case Array::Double:
1057  forNode(child1).filter(SpecCell);
1058  forNode(child2).filter(SpecInt32);
1059  forNode(child3).filter(SpecRealNumber);
1060954 if (node->arrayMode().isOutOfBounds())
1061955 clobberWorld(node->codeOrigin, indexInBlock);
1062956 break;
1063957 case Array::Contiguous:
1064958 case Array::ArrayStorage:
1065  forNode(child1).filter(SpecCell);
1066  forNode(child2).filter(SpecInt32);
1067959 if (node->arrayMode().isOutOfBounds())
1068960 clobberWorld(node->codeOrigin, indexInBlock);
1069961 break;
1070962 case Array::SlowPutArrayStorage:
1071  forNode(child1).filter(SpecCell);
1072  forNode(child2).filter(SpecInt32);
1073963 if (node->arrayMode().mayStoreToHole())
1074964 clobberWorld(node->codeOrigin, indexInBlock);
1075965 break;
1076  case Array::Arguments:
1077  forNode(child1).filter(SpecCell);
1078  forNode(child2).filter(SpecInt32);
1079  break;
1080  case Array::Int8Array:
1081  forNode(child1).filter(SpecCell);
1082  forNode(child2).filter(SpecInt32);
1083  if (child3->shouldSpeculateInteger())
1084  forNode(child3).filter(SpecInt32);
1085  else
1086  forNode(child3).filter(SpecNumber);
1087  break;
1088  case Array::Int16Array:
1089  forNode(child1).filter(SpecCell);
1090  forNode(child2).filter(SpecInt32);
1091  if (child3->shouldSpeculateInteger())
1092  forNode(child3).filter(SpecInt32);
1093  else
1094  forNode(child3).filter(SpecNumber);
1095  break;
1096  case Array::Int32Array:
1097  forNode(child1).filter(SpecCell);
1098  forNode(child2).filter(SpecInt32);
1099  if (child3->shouldSpeculateInteger())
1100  forNode(child3).filter(SpecInt32);
1101  else
1102  forNode(child3).filter(SpecNumber);
1103  break;
1104  case Array::Uint8Array:
1105  forNode(child1).filter(SpecCell);
1106  forNode(child2).filter(SpecInt32);
1107  if (child3->shouldSpeculateInteger())
1108  forNode(child3).filter(SpecInt32);
1109  else
1110  forNode(child3).filter(SpecNumber);
1111  break;
1112  case Array::Uint8ClampedArray:
1113  forNode(child1).filter(SpecCell);
1114  forNode(child2).filter(SpecInt32);
1115  if (child3->shouldSpeculateInteger())
1116  forNode(child3).filter(SpecInt32);
1117  else
1118  forNode(child3).filter(SpecNumber);
1119  break;
1120  case Array::Uint16Array:
1121  forNode(child1).filter(SpecCell);
1122  forNode(child2).filter(SpecInt32);
1123  if (child3->shouldSpeculateInteger())
1124  forNode(child3).filter(SpecInt32);
1125  else
1126  forNode(child3).filter(SpecNumber);
1127  break;
1128  case Array::Uint32Array:
1129  forNode(child1).filter(SpecCell);
1130  forNode(child2).filter(SpecInt32);
1131  if (child3->shouldSpeculateInteger())
1132  forNode(child3).filter(SpecInt32);
1133  else
1134  forNode(child3).filter(SpecNumber);
1135  break;
1136  case Array::Float32Array:
1137  forNode(child1).filter(SpecCell);
1138  forNode(child2).filter(SpecInt32);
1139  forNode(child3).filter(SpecNumber);
1140  break;
1141  case Array::Float64Array:
1142  forNode(child1).filter(SpecCell);
1143  forNode(child2).filter(SpecInt32);
1144  forNode(child3).filter(SpecNumber);
1145  break;
1146966 default:
1147  CRASH();
1148967 break;
1149968 }
1150969 break;

@@bool AbstractState::execute(unsigned ind
1152971
1153972 case ArrayPush:
1154973 node->setCanExit(true);
1155  switch (node->arrayMode().type()) {
1156  case Array::Int32:
1157  forNode(node->child2()).filter(SpecInt32);
1158  break;
1159  case Array::Double:
1160  forNode(node->child2()).filter(SpecRealNumber);
1161  break;
1162  default:
1163  break;
1164  }
1165974 clobberWorld(node->codeOrigin, indexInBlock);
1166975 forNode(node).set(SpecNumber);
1167976 break;

@@bool AbstractState::execute(unsigned ind
1174983
1175984 case RegExpExec:
1176985 case RegExpTest:
1177  node->setCanExit(
1178  !isCellSpeculation(forNode(node->child1()).m_type)
1179  || !isCellSpeculation(forNode(node->child2()).m_type));
1180  forNode(node->child1()).filter(SpecCell);
1181  forNode(node->child2()).filter(SpecCell);
1182986 forNode(node).makeTop();
1183987 break;
1184988
1185989 case Jump:
1186  node->setCanExit(false);
1187990 break;
1188991
1189992 case Branch: {

@@bool AbstractState::execute(unsigned ind
1191994 BooleanResult result = booleanResult(node, forNode(child));
1192995 if (result == DefinitelyTrue) {
1193996 m_branchDirection = TakeTrue;
1194  node->setCanExit(false);
1195997 break;
1196998 }
1197999 if (result == DefinitelyFalse) {
11981000 m_branchDirection = TakeFalse;
1199  node->setCanExit(false);
12001001 break;
12011002 }
12021003 // FIXME: The above handles the trivial cases of sparse conditional
12031004 // constant propagation, but we can do better:
12041005 // We can specialize the source variable's value on each direction of
12051006 // the branch.
1206  if (child->shouldSpeculateBoolean())
1207  speculateBooleanUnary(node);
1208  else if (child->shouldSpeculateObjectOrOther()) {
1209  node->setCanExit(true);
1210  forNode(child).filter(SpecObject | SpecOther);
1211  } else if (child->shouldSpeculateInteger())
1212  speculateInt32Unary(node);
1213  else if (child->shouldSpeculateNumber())
1214  speculateNumberUnary(node);
1215  else
1216  node->setCanExit(false);
 1007 node->setCanExit(true); // This is overly conservative.
12171008 m_branchDirection = TakeBoth;
12181009 break;
12191010 }
12201011
12211012 case Return:
12221013 m_isValid = false;
1223  node->setCanExit(false);
12241014 break;
12251015
12261016 case Throw:

@@bool AbstractState::execute(unsigned ind
12301020 break;
12311021
12321022 case ToPrimitive: {
1233  Node* child = node->child1().node();
1234 
1235  JSValue childConst = forNode(child).value();
 1023 JSValue childConst = forNode(node->child1()).value();
12361024 if (childConst && childConst.isNumber() && trySetConstant(node, childConst)) {
12371025 m_foundConstants = true;
1238  node->setCanExit(false);
12391026 break;
12401027 }
12411028
1242  if (child->shouldSpeculateInteger()) {
1243  speculateInt32Unary(node);
 1029 if (node->child1().useKind() == Int32Use) {
12441030 forNode(node).set(SpecInt32);
12451031 break;
12461032 }
12471033
1248  AbstractValue& source = forNode(child);
 1034 AbstractValue& source = forNode(node->child1());
12491035 AbstractValue& destination = forNode(node);
12501036
12511037 // NB. The more canonical way of writing this would have been:

@@bool AbstractState::execute(unsigned ind
12751061 type |= SpecString;
12761062 }
12771063 destination.set(type);
1278  node->setCanExit(false);
12791064 break;
12801065 }
12811066
12821067 case StrCat:
1283  node->setCanExit(false);
12841068 forNode(node).set(SpecString);
12851069 break;
12861070
12871071 case NewArray:
12881072 node->setCanExit(true);
1289  switch (node->indexingType()) {
1290  case ALL_BLANK_INDEXING_TYPES:
1291  CRASH();
1292  break;
1293  case ALL_UNDECIDED_INDEXING_TYPES:
1294  ASSERT(!node->numChildren());
1295  break;
1296  case ALL_INT32_INDEXING_TYPES:
1297  for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
1298  forNode(m_graph.m_varArgChildren[node->firstChild() + operandIndex]).filter(SpecInt32);
1299  break;
1300  case ALL_DOUBLE_INDEXING_TYPES:
1301  for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
1302  forNode(m_graph.m_varArgChildren[node->firstChild() + operandIndex]).filter(SpecRealNumber);
1303  break;
1304  case ALL_CONTIGUOUS_INDEXING_TYPES:
1305  case ALL_ARRAY_STORAGE_INDEXING_TYPES:
1306  break;
1307  default:
1308  CRASH();
1309  break;
1310  }
13111073 forNode(node).set(m_graph.globalObjectFor(node->codeOrigin)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
13121074 m_haveStructures = true;
13131075 break;

@@bool AbstractState::execute(unsigned ind
13201082
13211083 case NewArrayWithSize:
13221084 node->setCanExit(true);
1323  forNode(node->child1()).filter(SpecInt32);
13241085 forNode(node).set(SpecArray);
13251086 m_haveStructures = true;
13261087 break;
13271088
13281089 case NewRegexp:
1329  node->setCanExit(false);
13301090 forNode(node).set(m_graph.globalObjectFor(node->codeOrigin)->regExpStructure());
13311091 m_haveStructures = true;
13321092 break;
13331093
13341094 case ConvertThis: {
1335  Node* child = node->child1().node();
13361095 AbstractValue& source = forNode(node->child1());
13371096 AbstractValue& destination = forNode(node);
13381097

@@bool AbstractState::execute(unsigned ind
13411100 // object, so there's nothing to do. I don't think this case will
13421101 // be hit, but then again, you never know.
13431102 destination = source;
1344  node->setCanExit(false);
13451103 m_foundConstants = true; // Tell the constant folder to turn this into Identity.
13461104 break;
13471105 }
13481106
13491107 node->setCanExit(true);
1350 
1351  if (isOtherSpeculation(child->prediction())) {
1352  source.filter(SpecOther);
 1108 switch (node->child1().useKind()) {
 1109 case OtherUse:
13531110 destination.set(SpecObjectOther);
13541111 break;
1355  }
1356 
1357  if (isObjectSpeculation(child->prediction())) {
1358  source.filter(SpecObject);
 1112 case ObjectUse:
 1113 destination = source;
 1114 break;
 1115 case UntypedUse:
13591116 destination = source;
 1117 destination.merge(SpecObjectOther);
 1118 break;
 1119 default:
 1120 RELEASE_ASSERT_NOT_REACHED();
13601121 break;
13611122 }
1362 
1363  destination = source;
1364  destination.merge(SpecObjectOther);
13651123 break;
13661124 }
13671125
13681126 case CreateThis: {
1369  AbstractValue& source = forNode(node->child1());
1370  AbstractValue& destination = forNode(node);
1371 
1372  node->setCanExit(!isCellSpeculation(source.m_type));
1373 
1374  source.filter(SpecFunction);
1375  destination.set(SpecFinalObject);
 1127 forNode(node).set(SpecFinalObject);
13761128 break;
13771129 }
13781130

@@bool AbstractState::execute(unsigned ind
13811133 break;
13821134
13831135 case NewObject:
1384  node->setCanExit(false);
13851136 forNode(node).set(node->structure());
13861137 m_haveStructures = true;
13871138 break;
13881139
13891140 case CreateActivation:
1390  node->setCanExit(false);
13911141 forNode(node).set(m_codeBlock->globalObjectFor(node->codeOrigin)->activationStructure());
13921142 m_haveStructures = true;
13931143 break;
13941144
13951145 case CreateArguments:
1396  node->setCanExit(false);
13971146 forNode(node).set(m_codeBlock->globalObjectFor(node->codeOrigin)->argumentsStructure());
13981147 m_haveStructures = true;
13991148 break;
14001149
14011150 case TearOffActivation:
14021151 case TearOffArguments:
1403  node->setCanExit(false);
14041152 // Does nothing that is user-visible.
14051153 break;
14061154
14071155 case CheckArgumentsNotCreated:
14081156 if (isEmptySpeculation(
14091157 m_variables.operand(
1410  m_graph.argumentsRegisterFor(node->codeOrigin)).m_type)) {
1411  node->setCanExit(false);
 1158 m_graph.argumentsRegisterFor(node->codeOrigin)).m_type))
14121159 m_foundConstants = true;
1413  } else
 1160 else
14141161 node->setCanExit(true);
14151162 break;
14161163

@@bool AbstractState::execute(unsigned ind
14301177 break;
14311178
14321179 case GetMyArgumentsLengthSafe:
1433  node->setCanExit(false);
14341180 // This potentially clobbers all structures if the arguments object had a getter
14351181 // installed on the length property.
14361182 clobberWorld(node->codeOrigin, indexInBlock);

@@bool AbstractState::execute(unsigned ind
14441190 // We know that this executable does not escape its arguments, so we can optimize
14451191 // the arguments a bit. Note that this ends up being further optimized by the
14461192 // ArgumentsSimplificationPhase.
1447  forNode(node->child1()).filter(SpecInt32);
14481193 forNode(node).makeTop();
14491194 break;
14501195

@@bool AbstractState::execute(unsigned ind
14531198 // This potentially clobbers all structures if the property we're accessing has
14541199 // a getter. We don't speculate against this.
14551200 clobberWorld(node->codeOrigin, indexInBlock);
1456  // But we do speculate that the index is an integer.
1457  forNode(node->child1()).filter(SpecInt32);
14581201 // And the result is unknown.
14591202 forNode(node).makeTop();
14601203 break;

@@bool AbstractState::execute(unsigned ind
14621205 case NewFunction:
14631206 case NewFunctionExpression:
14641207 case NewFunctionNoCheck:
1465  node->setCanExit(false);
14661208 forNode(node).set(m_codeBlock->globalObjectFor(node->codeOrigin)->functionStructure());
14671209 break;
14681210
14691211 case GetCallee:
1470  node->setCanExit(false);
14711212 forNode(node).set(SpecFunction);
14721213 break;
14731214
14741215 case SetCallee:
14751216 case SetMyScope:
1476  node->setCanExit(false);
14771217 break;
14781218
14791219 case GetScope: // FIXME: We could get rid of these if we know that the JSFunction is a constant. https://bugs.webkit.org/show_bug.cgi?id=106202
14801220 case GetMyScope:
14811221 case SkipTopScope:
1482  node->setCanExit(false);
14831222 forNode(node).set(SpecCellOther);
14841223 break;
14851224
14861225 case SkipScope: {
1487  node->setCanExit(false);
14881226 JSValue child = forNode(node->child1()).value();
14891227 if (child && trySetConstant(node, JSValue(jsCast<JSScope*>(child.asCell())->next()))) {
14901228 m_foundConstants = true;

@@bool AbstractState::execute(unsigned ind
14951233 }
14961234
14971235 case GetScopeRegisters:
1498  node->setCanExit(false);
1499  forNode(node->child1()).filter(SpecCell);
15001236 forNode(node).clear(); // The result is not a JS value.
15011237 break;
15021238
15031239 case GetScopedVar:
1504  node->setCanExit(false);
15051240 forNode(node).makeTop();
15061241 break;
15071242
15081243 case PutScopedVar:
1509  node->setCanExit(false);
15101244 clobberCapturedVars(node->codeOrigin);
15111245 break;
15121246

@@bool AbstractState::execute(unsigned ind
15181252 break;
15191253 }
15201254 if (isCellSpeculation(node->child1()->prediction())) {
1521  forNode(node->child1()).filter(SpecCell);
1522 
15231255 if (Structure* structure = forNode(node->child1()).bestProvenStructure()) {
15241256 GetByIdStatus status = GetByIdStatus::computeFor(
15251257 m_graph.m_globalData, structure,

@@bool AbstractState::execute(unsigned ind
15551287 // more thoroughly. https://bugs.webkit.org/show_bug.cgi?id=106200
15561288 // FIXME: We could eliminate these entirely if we know the exact value that flows into this.
15571289 // https://bugs.webkit.org/show_bug.cgi?id=106201
1558  forNode(node->child1()).filter(SpecCell);
15591290 node->setCanExit(true);
15601291 break;
15611292 }

@@bool AbstractState::execute(unsigned ind
15641295 case ForwardCheckStructure: {
15651296 // FIXME: We should be able to propagate the structure sets of constants (i.e. prototypes).
15661297 AbstractValue& value = forNode(node->child1());
 1298 ASSERT(!(value.m_type & ~SpecCell)); // Edge filtering should have already ensured this.
15671299 // If this structure check is attempting to prove knowledge already held in
15681300 // the futurePossibleStructure set then the constant folding phase should
15691301 // turn this into a watchpoint instead.

@@bool AbstractState::execute(unsigned ind
15711303 if (value.m_futurePossibleStructure.isSubsetOf(set)
15721304 || value.m_currentKnownStructure.isSubsetOf(set))
15731305 m_foundConstants = true;
1574  node->setCanExit(
1575  !value.m_currentKnownStructure.isSubsetOf(set)
1576  || !isCellSpeculation(value.m_type));
 1306 if (!value.m_currentKnownStructure.isSubsetOf(set))
 1307 node->setCanExit(true);
15771308 value.filter(set);
15781309 m_haveStructures = true;
15791310 break;

@@bool AbstractState::execute(unsigned ind
15911322 // infinity of structures.
15921323 ASSERT(value.m_futurePossibleStructure.isSubsetOf(StructureSet(node->structure())));
15931324
1594  ASSERT(value.isClear() || isCellSpeculation(value.m_type)); // Value could be clear if we've proven must-exit due to a speculation statically known to be bad.
15951325 value.filter(node->structure());
15961326 m_haveStructures = true;
15971327 node->setCanExit(true);

@@bool AbstractState::execute(unsigned ind
16001330
16011331 case PutStructure:
16021332 case PhantomPutStructure:
1603  node->setCanExit(false);
16041333 if (!forNode(node->child1()).m_currentKnownStructure.isClear()) {
16051334 clobberStructures(indexInBlock);
16061335 forNode(node->child1()).set(node->structureTransitionData().newStructure);

@@bool AbstractState::execute(unsigned ind
16101339 case GetButterfly:
16111340 case AllocatePropertyStorage:
16121341 case ReallocatePropertyStorage:
1613  node->setCanExit(!isCellSpeculation(forNode(node->child1()).m_type));
1614  forNode(node->child1()).filter(SpecCell);
16151342 forNode(node).clear(); // The result is not a JS value.
16161343 break;
16171344 case CheckArray: {
16181345 if (node->arrayMode().alreadyChecked(m_graph, node, forNode(node->child1()))) {
16191346 m_foundConstants = true;
1620  node->setCanExit(false);
16211347 break;
16221348 }
16231349 node->setCanExit(true); // Lies, but this is followed by operations (like GetByVal) that always exit, so there is no point in us trying to be clever here.

@@bool AbstractState::execute(unsigned ind
16301356 case Array::Contiguous:
16311357 case Array::ArrayStorage:
16321358 case Array::SlowPutArrayStorage:
1633  forNode(node->child1()).filter(SpecCell);
16341359 break;
16351360 case Array::Arguments:
16361361 forNode(node->child1()).filter(SpecArguments);

@@bool AbstractState::execute(unsigned ind
16731398 case Arrayify: {
16741399 if (node->arrayMode().alreadyChecked(m_graph, node, forNode(node->child1()))) {
16751400 m_foundConstants = true;
1676  node->setCanExit(false);
16771401 break;
16781402 }
16791403 ASSERT(node->arrayMode().conversion() == Array::Convert
16801404 || node->arrayMode().conversion() == Array::RageConvert);
16811405 node->setCanExit(true);
1682  forNode(node->child1()).filter(SpecCell);
1683  if (node->child2())
1684  forNode(node->child2()).filter(SpecInt32);
16851406 clobberStructures(indexInBlock);
16861407 forNode(node->child1()).filterArrayModes(node->arrayMode().arrayModesThatPassFiltering());
16871408 m_haveStructures = true;

@@bool AbstractState::execute(unsigned ind
16941415 || value.m_currentKnownStructure.isSubsetOf(set))
16951416 m_foundConstants = true;
16961417 node->setCanExit(true);
1697  if (node->child2())
1698  forNode(node->child2()).filter(SpecInt32);
16991418 clobberStructures(indexInBlock);
17001419 value.filter(set);
17011420 m_haveStructures = true;
17021421 break;
17031422 }
17041423 case GetIndexedPropertyStorage: {
1705  node->setCanExit(false);
17061424 forNode(node).clear();
17071425 break;
17081426 }
1709  case GetByOffset:
1710  if (!node->child1()->hasStorageResult()) {
1711  node->setCanExit(!isCellSpeculation(forNode(node->child1()).m_type));
1712  forNode(node->child1()).filter(SpecCell);
1713  }
 1427 case GetByOffset: {
17141428 forNode(node).makeTop();
17151429 break;
 1430 }
17161431
17171432 case PutByOffset: {
1718  bool canExit = false;
1719  if (!node->child1()->hasStorageResult()) {
1720  canExit |= !isCellSpeculation(forNode(node->child1()).m_type);
1721  forNode(node->child1()).filter(SpecCell);
1722  }
1723  canExit |= !isCellSpeculation(forNode(node->child2()).m_type);
1724  forNode(node->child2()).filter(SpecCell);
1725  node->setCanExit(canExit);
17261433 break;
17271434 }
17281435

@@bool AbstractState::execute(unsigned ind
17311438 if (value == node->function()) {
17321439 m_foundConstants = true;
17331440 ASSERT(value);
1734  node->setCanExit(false);
17351441 break;
17361442 }
17371443

@@bool AbstractState::execute(unsigned ind
17661472 break;
17671473 }
17681474 }
1769  forNode(node->child1()).filter(SpecCell);
17701475 clobberWorld(node->codeOrigin, indexInBlock);
17711476 break;
17721477
17731478 case GetGlobalVar:
1774  node->setCanExit(false);
17751479 forNode(node).makeTop();
17761480 break;
17771481

@@bool AbstractState::execute(unsigned ind
17811485
17821486 case PutGlobalVar:
17831487 case PutGlobalVarCheck:
1784  node->setCanExit(false);
17851488 break;
17861489
17871490 case CheckHasInstance:
17881491 node->setCanExit(true);
1789  forNode(node->child1()).filter(SpecCell);
17901492 // Sadly, we don't propagate the fact that we've done CheckHasInstance
17911493 break;
17921494
17931495 case InstanceOf:
17941496 node->setCanExit(true);
17951497 // Again, sadly, we don't propagate the fact that we've done InstanceOf
1796  // FIXME: This appears broken: CheckHasInstance already does an unconditional cell
1797  // check. https://bugs.webkit.org/show_bug.cgi?id=107479
1798  if (!(node->child1()->prediction() & ~SpecCell) && !(forNode(node->child1()).m_type & ~SpecCell))
1799  forNode(node->child1()).filter(SpecCell);
1800  forNode(node->child2()).filter(SpecCell);
18011498 forNode(node).set(SpecBoolean);
18021499 break;
18031500
18041501 case Phi:
18051502 case Flush:
18061503 case PhantomLocal:
1807  node->setCanExit(false);
1808  break;
1809 
18101504 case Breakpoint:
1811  node->setCanExit(false);
18121505 break;
18131506
18141507 case Call:

@@bool AbstractState::execute(unsigned ind
18361529 case InlineStart:
18371530 case Nop:
18381531 case CountExecution:
1839  node->setCanExit(false);
18401532 break;
18411533
18421534 case LastNodeType:

@@bool AbstractState::execute(unsigned ind
18471539 return m_isValid;
18481540}
18491541
 1542bool AbstractState::executeEffects(unsigned indexInBlock)
 1543{
 1544 return executeEffects(indexInBlock, m_block->at(indexInBlock));
 1545}
 1546
 1547bool AbstractState::execute(unsigned indexInBlock)
 1548{
 1549 Node* node = m_block->at(indexInBlock);
 1550 if (!startExecuting(node))
 1551 return true;
 1552
 1553 executeEdges(node);
 1554 return executeEffects(indexInBlock, node);
 1555}
 1556
18501557inline void AbstractState::clobberWorld(const CodeOrigin& codeOrigin, unsigned indexInBlock)
18511558{
18521559 clobberCapturedVars(codeOrigin);
143562

Source/JavaScriptCore/dfg/DFGAbstractState.h

@@public:
158158 // if execution should continue past this node. Notably, it will return true
159159 // for block terminals, so long as those terminals are not Return or variants
160160 // of Throw.
161  bool execute(unsigned);
 161 //
 162 // This is guaranteed to be equivalent to doing:
 163 //
 164 // if (state.startExecuting(index)) {
 165 // state.executeEdges(index);
 166 // result = state.executeEffects(index);
 167 // } else
 168 // result = true;
 169 bool execute(unsigned indexInBlock);
 170
 171 // Indicate the start of execution of the node. It resets any state in the node,
 172 // that is progressively built up by executeEdges() and executeEffects(). In
 173 // particular, this resets canExit(), so if you want to "know" between calls of
 174 // startExecuting() and executeEdges()/Effects() whether the last run of the
 175 // analysis concluded that the node can exit, you should probably set that
 176 // information aside prior to calling startExecuting().
 177 bool startExecuting(Node*);
 178 bool startExecuting(unsigned indexInBlock);
 179
 180 // Abstractly execute the edges of the given node. This runs filterEdgeByUse()
 181 // on all edges of the node. You can skip this step, if you have already used
 182 // filterEdgeByUse() (or some equivalent) on each edge.
 183 void executeEdges(Node*);
 184 void executeEdges(unsigned indexInBlock);
 185
 186 ALWAYS_INLINE void filterEdgeByUse(Node* node, Edge edge)
 187 {
 188#if !ASSERT_DISABLED
 189 switch (edge.useKind()) {
 190 case KnownInt32Use:
 191 case KnownNumberUse:
 192 case KnownCellUse:
 193 ASSERT(!(forNode(edge).m_type & ~typeFilterFor(edge.useKind())));
 194 break;
 195 default:
 196 break;
 197 }
 198#endif // !ASSERT_DISABLED
 199
 200 filterByType(node, edge.node(), typeFilterFor(edge.useKind()));
 201 }
 202
 203 // Abstractly execute the effects of the given node. This changes the abstract
 204 // state assuming that edges have already been filtered.
 205 bool executeEffects(unsigned indexInBlock);
 206 bool executeEffects(unsigned indexInBlock, Node*);
162207
163208 // Did the last executed node clobber the world?
164209 bool didClobber() const { return m_didClobber; }

@@private:
191236
192237 static bool mergeVariableBetweenBlocks(AbstractValue& destination, AbstractValue& source, Node* destinationNode, Node* sourceNode);
193238
194  void speculateInt32Unary(Node* node, bool forceCanExit = false)
195  {
196  AbstractValue& childValue = forNode(node->child1());
197  node->setCanExit(forceCanExit || !isInt32Speculation(childValue.m_type));
198  childValue.filter(SpecInt32);
199  }
200 
201  void speculateNumberUnary(Node* node)
202  {
203  AbstractValue& childValue = forNode(node->child1());
204  node->setCanExit(!isNumberSpeculation(childValue.m_type));
205  childValue.filter(SpecNumber);
206  }
207 
208  void speculateBooleanUnary(Node* node)
209  {
210  AbstractValue& childValue = forNode(node->child1());
211  node->setCanExit(!isBooleanSpeculation(childValue.m_type));
212  childValue.filter(SpecBoolean);
213  }
214 
215  void speculateInt32Binary(Node* node, bool forceCanExit = false)
216  {
217  AbstractValue& childValue1 = forNode(node->child1());
218  AbstractValue& childValue2 = forNode(node->child2());
219  node->setCanExit(
220  forceCanExit
221  || !isInt32Speculation(childValue1.m_type)
222  || !isInt32Speculation(childValue2.m_type));
223  childValue1.filter(SpecInt32);
224  childValue2.filter(SpecInt32);
225  }
226 
227  void speculateNumberBinary(Node* node)
228  {
229  AbstractValue& childValue1 = forNode(node->child1());
230  AbstractValue& childValue2 = forNode(node->child2());
231  node->setCanExit(
232  !isNumberSpeculation(childValue1.m_type)
233  || !isNumberSpeculation(childValue2.m_type));
234  childValue1.filter(SpecNumber);
235  childValue2.filter(SpecNumber);
236  }
237 
238239 enum BooleanResult {
239240 UnknownBooleanResult,
240241 DefinitelyFalse,

@@private:
259260 return true;
260261 }
261262
 263 ALWAYS_INLINE void filterByType(Node* node, Node* child, SpeculatedType type)
 264 {
 265 AbstractValue& value = forNode(child);
 266 if (value.m_type & ~type)
 267 node->setCanExit(true);
 268 value.filter(type);
 269 }
 270
 271 void verifyEdge(Node*, Edge);
 272 void verifyEdges(Node*);
 273
262274 CodeBlock* m_codeBlock;
263275 Graph& m_graph;
264276
143562

Source/JavaScriptCore/dfg/DFGAbstractValue.h

@@struct AbstractValue {
234234
235235 void filter(const StructureSet& other)
236236 {
 237 // FIXME: This could be optimized for the common case of m_type not
 238 // having structures, array modes, or a specific value.
 239 // https://bugs.webkit.org/show_bug.cgi?id=109663
237240 m_type &= other.speculationFromStructures();
238241 m_arrayModes &= other.arrayModesFromStructures();
239242 m_currentKnownStructure.filter(other);
143562

Source/JavaScriptCore/dfg/DFGAdjacencyList.h

@@public:
4747 AdjacencyList() { }
4848
4949 AdjacencyList(Kind kind)
50 #if !ASSERT_DISABLED
51  : m_kind(kind)
52 #endif
5350 {
5451 if (kind == Variable) {
5552 m_words[0].m_encodedWord = UINT_MAX;

@@public:
5754 }
5855 }
5956
60  AdjacencyList(Kind kind, Node* child1, Node* child2, Node* child3)
61 #if !ASSERT_DISABLED
62  : m_kind(Fixed)
63 #endif
 57 AdjacencyList(Kind kind, Edge child1, Edge child2, Edge child3)
6458 {
6559 ASSERT_UNUSED(kind, kind == Fixed);
6660 initialize(child1, child2, child3);
6761 }
6862
6963 AdjacencyList(Kind kind, unsigned firstChild, unsigned numChildren)
70 #if !ASSERT_DISABLED
71  : m_kind(Variable)
72 #endif
7364 {
7465 ASSERT_UNUSED(kind, kind == Variable);
7566 setFirstChild(firstChild);

@@public:
7970 const Edge& child(unsigned i) const
8071 {
8172 ASSERT(i < Size);
82  ASSERT(m_kind == Fixed);
8373 return m_words[i];
8474 }
8575
8676 Edge& child(unsigned i)
8777 {
8878 ASSERT(i < Size);
89  ASSERT(m_kind == Fixed);
9079 return m_words[i];
9180 }
9281
9382 void setChild(unsigned i, Edge nodeUse)
9483 {
9584 ASSERT(i < Size);
96  ASSERT(m_kind == Fixed);
9785 m_words[i] = nodeUse;
9886 }
9987

@@public:
125113
126114 void reset()
127115 {
128 #if !ASSERT_DISABLED
129  m_kind = Fixed;
130 #endif
131116 initialize();
132117 }
133118

@@public:
142127
143128 unsigned firstChild() const
144129 {
145  ASSERT(m_kind == Variable);
146130 return m_words[0].m_encodedWord;
147131 }
148132 void setFirstChild(unsigned firstChild)
149133 {
150  ASSERT(m_kind == Variable);
151134 m_words[0].m_encodedWord = firstChild;
152135 }
153136
154137 unsigned numChildren() const
155138 {
156  ASSERT(m_kind == Variable);
157139 return m_words[1].m_encodedWord;
158140 }
159141 void setNumChildren(unsigned numChildren)
160142 {
161  ASSERT(m_kind == Variable);
162143 m_words[1].m_encodedWord = numChildren;
163144 }
164145
165 #if !ASSERT_DISABLED
166  Kind kind() const { return m_kind; }
167 #endif
168146private:
169147 Edge m_words[Size];
170 #if !ASSERT_DISABLED
171  Kind m_kind;
172 #endif
173148};
174149
175150} } // namespace JSC::DFG
143562

Source/JavaScriptCore/dfg/DFGAllocator.h

@@namespace JSC { namespace DFG {
4343// anything. You can just call freeAll() instead.
4444// - You call free() on all T's that you allocated, and never use freeAll().
4545
46 template<typename T>
 46// forcedCellSize: set this to 0 if you're happy with the default alignment, or set it
 47// to a non-zero value if you want to forcibly align the allocations to a certain
 48// value. When you do this, Allocator will ASSERT that forcedCellAlignment >= sizeof(T).
 49
 50template<typename T, unsigned forcedCellAlignment>
4751class Allocator {
4852public:
4953 Allocator();

@@private:
6367 void* bumpAllocate();
6468 void* freeListAllocate();
6569 void* allocateSlow();
66 
 70
 71 static size_t cellSize()
 72 {
 73 if (!forcedCellAlignment)
 74 return sizeof(T);
 75
 76 ASSERT(forcedCellAlignment >= sizeof(T));
 77 return forcedCellAlignment;
 78 }
 79
6780 struct Region {
6881 static size_t size() { return 64 * KB; }
69  static size_t headerSize() { return std::max(sizeof(Region), sizeof(T)); }
70  static unsigned numberOfThingsPerRegion() { return (size() - headerSize()) / sizeof(T); }
71  T* data() { return bitwise_cast<T*>(bitwise_cast<char*>(this) + headerSize()); }
72  bool isInThisRegion(const T* pointer) { return static_cast<unsigned>(pointer - data()) < numberOfThingsPerRegion(); }
 82 static size_t headerSize() { return std::max(sizeof(Region), cellSize()); }
 83 static unsigned numberOfThingsPerRegion() { return (size() - headerSize()) / cellSize(); }
 84 static size_t payloadSize() { return numberOfThingsPerRegion() * cellSize(); }
 85 char* payloadBegin() { return bitwise_cast<char*>(this) + headerSize(); }
 86 char* payloadEnd() { return payloadBegin() + payloadSize(); }
 87 bool isInThisRegion(const T* pointer) { return static_cast<size_t>(bitwise_cast<char*>(pointer) - payloadBegin()) < payloadSize(); }
7388 static Region* regionFor(const T* pointer) { return bitwise_cast<Region*>(bitwise_cast<uintptr_t>(pointer) & ~(size() - 1)); }
7489
7590 PageAllocationAligned m_allocation;

@@private:
8297
8398 Region* m_regionHead;
8499 void** m_freeListHead;
85  T* m_bumpEnd;
86  unsigned m_bumpRemaining;
 100 char* m_bumpEnd;
 101 size_t m_bumpRemaining;
87102};
88103
89 template<typename T>
90 inline Allocator<T>::Allocator()
 104template<typename T, unsigned forcedCellAlignment>
 105inline Allocator<T, forcedCellAlignment>::Allocator()
91106 : m_regionHead(0)
92107 , m_freeListHead(0)
93108 , m_bumpRemaining(0)
94109{
95110}
96111
97 template<typename T>
98 inline Allocator<T>::~Allocator()
 112template<typename T, unsigned forcedCellAlignment>
 113inline Allocator<T, forcedCellAlignment>::~Allocator()
99114{
100115 reset();
101116}
102117
103 template<typename T>
104 ALWAYS_INLINE void* Allocator<T>::allocate()
 118template<typename T, unsigned forcedCellAlignment>
 119ALWAYS_INLINE void* Allocator<T, forcedCellAlignment>::allocate()
105120{
106121 void* result = bumpAllocate();
107122 if (LIKELY(!!result))

@@ALWAYS_INLINE void* Allocator<T>::alloca
109124 return freeListAllocate();
110125}
111126
112 template<typename T>
113 void Allocator<T>::free(T* object)
 127template<typename T, unsigned forcedCellAlignment>
 128void Allocator<T, forcedCellAlignment>::free(T* object)
114129{
115130 object->~T();
116131

@@void Allocator<T>::free(T* object)
119134 m_freeListHead = cell;
120135}
121136
122 template<typename T>
123 void Allocator<T>::freeAll()
 137template<typename T, unsigned forcedCellAlignment>
 138void Allocator<T, forcedCellAlignment>::freeAll()
124139{
125140 if (!m_regionHead) {
126141 ASSERT(!m_bumpRemaining);

@@void Allocator<T>::freeAll()
142157 startBumpingIn(m_regionHead);
143158}
144159
145 template<typename T>
146 void Allocator<T>::reset()
 160template<typename T, unsigned forcedCellAlignment>
 161void Allocator<T, forcedCellAlignment>::reset()
147162{
148163 freeRegionsStartingAt(m_regionHead);
149164

@@void Allocator<T>::reset()
152167 m_bumpRemaining = 0;
153168}
154169
155 template<typename T>
156 unsigned Allocator<T>::indexOf(const T* object)
 170template<typename T, unsigned forcedCellAlignment>
 171unsigned Allocator<T, forcedCellAlignment>::indexOf(const T* object)
157172{
158173 unsigned baseIndex = 0;
159174 for (Region* region = m_regionHead; region; region = region->m_next) {
160175 if (region->isInThisRegion(object))
161  return baseIndex + (object - region->data());
 176 return baseIndex + (bitwise_cast<char*>(object) - region->payloadBegin()) / cellSize();
162177 baseIndex += Region::numberOfThingsPerRegion();
163178 }
164179 CRASH();
165180 return 0;
166181}
167182
168 template<typename T>
169 Allocator<T>* Allocator<T>::allocatorOf(const T* object)
 183template<typename T, unsigned forcedCellAlignment>
 184Allocator<T, forcedCellAlignment>* Allocator<T, forcedCellAlignment>::allocatorOf(const T* object)
170185{
171186 return Region::regionFor(object)->m_allocator;
172187}
173188
174 template<typename T>
175 ALWAYS_INLINE void* Allocator<T>::bumpAllocate()
 189template<typename T, unsigned forcedCellAlignment>
 190ALWAYS_INLINE void* Allocator<T, forcedCellAlignment>::bumpAllocate()
176191{
177  if (unsigned remaining = m_bumpRemaining) {
178  remaining--;
 192 if (size_t remaining = m_bumpRemaining) {
 193 remaining -= cellSize();
179194 m_bumpRemaining = remaining;
180  return m_bumpEnd - (remaining + 1);
 195 return m_bumpEnd - (remaining + cellSize());
181196 }
182197 return 0;
183198}
184199
185 template<typename T>
186 void* Allocator<T>::freeListAllocate()
 200template<typename T, unsigned forcedCellAlignment>
 201void* Allocator<T, forcedCellAlignment>::freeListAllocate()
187202{
188203 void** result = m_freeListHead;
189204 if (UNLIKELY(!result))

@@void* Allocator<T>::freeListAllocate()
192207 return result;
193208}
194209
195 template<typename T>
196 void* Allocator<T>::allocateSlow()
 210template<typename T, unsigned forcedCellAlignment>
 211void* Allocator<T, forcedCellAlignment>::allocateSlow()
197212{
198213 ASSERT(!m_freeListHead);
199214 ASSERT(!m_bumpRemaining);

@@void* Allocator<T>::allocateSlow()
216231 return result;
217232}
218233
219 template<typename T>
220 void Allocator<T>::freeRegionsStartingAt(typename Allocator<T>::Region* region)
 234template<typename T, unsigned forcedCellAlignment>
 235void Allocator<T, forcedCellAlignment>::freeRegionsStartingAt(typename Allocator<T, forcedCellAlignment>::Region* region)
221236{
222237 while (region) {
223238 Region* nextRegion = region->m_next;

@@void Allocator<T>::freeRegionsStartingAt
226241 }
227242}
228243
229 template<typename T>
230 void Allocator<T>::startBumpingIn(typename Allocator<T>::Region* region)
 244template<typename T, unsigned forcedCellAlignment>
 245void Allocator<T, forcedCellAlignment>::startBumpingIn(typename Allocator<T, forcedCellAlignment>::Region* region)
231246{
232  m_bumpEnd = region->data() + Region::numberOfThingsPerRegion();
233  m_bumpRemaining = Region::numberOfThingsPerRegion();
 247 m_bumpEnd = region->payloadEnd();
 248 m_bumpRemaining = Region::payloadSize();
234249}
235250
236251} } // namespace JSC::DFG
143562

Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

@@private:
698698 {
699699 Node* result = m_graph.addNode(
700700 DontRefChildren, DontRefNode, SpecNone,
 701 op, currentCodeOrigin(), Edge(child1), Edge(child2), Edge(child3));
 702 ASSERT(op != Phi);
 703 m_currentBlock->append(result);
 704
 705 if (defaultFlags(op) & NodeMustGenerate)
 706 m_graph.refChildren(result);
 707 return result;
 708 }
 709 Node* addToGraph(NodeType op, Edge child1, Edge child2 = Edge(), Edge child3 = Edge())
 710 {
 711 Node* result = m_graph.addNode(
 712 DontRefChildren, DontRefNode, SpecNone,
701713 op, currentCodeOrigin(), child1, child2, child3);
702714 ASSERT(op != Phi);
703715 m_currentBlock->append(result);

@@private:
710722 {
711723 Node* result = m_graph.addNode(
712724 DontRefChildren, DontRefNode, SpecNone,
713  op, currentCodeOrigin(), info, child1, child2, child3);
 725 op, currentCodeOrigin(), info, Edge(child1), Edge(child2), Edge(child3));
714726 if (op == Phi)
715727 m_currentBlock->phis.append(result);
716728 else

@@private:
724736 {
725737 Node* result = m_graph.addNode(
726738 DontRefChildren, DontRefNode, SpecNone,
727  op, currentCodeOrigin(), info1, info2, child1, child2, child3);
 739 op, currentCodeOrigin(), info1, info2, Edge(child1), Edge(child2), Edge(child3));
728740 ASSERT(op != Phi);
729741 m_currentBlock->append(result);
730742

@@bool ByteCodeParser::handleMinMax(bool u
14651477
14661478 if (argumentCountIncludingThis == 2) { // Math.min(x)
14671479 Node* result = get(registerOffset + argumentToOperand(1));
1468  addToGraph(CheckNumber, result);
 1480 addToGraph(Phantom, Edge(result, NumberUse));
14691481 setIntrinsicResult(usesResult, resultOperand, result);
14701482 return true;
14711483 }
143562

Source/JavaScriptCore/dfg/DFGCSEPhase.cpp

@@private:
969969
970970 case GetByVal:
971971 // If this is accessing arguments then it's potentially accessing locals.
972  if (node->child1()->shouldSpeculateArguments())
 972 if (node->arrayMode().type() == Array::Arguments)
973973 result.mayBeAccessed = true;
974974 break;
975975

@@private:
10021002 Edge edge = node->children.child(i);
10031003 if (!edge)
10041004 continue;
 1005 if (edge.useKind() != UntypedUse)
 1006 continue; // Keep the type check.
10051007 if (edge->flags() & NodeRelevantToOSR)
10061008 continue;
10071009

@@private:
10141016 }
10151017 }
10161018
1017  enum PredictionHandlingMode { RequireSamePrediction, AllowPredictionMismatch };
1018  bool setReplacement(Node* replacement, PredictionHandlingMode predictionHandlingMode = RequireSamePrediction)
 1019 bool setReplacement(Node* replacement)
10191020 {
10201021 if (!replacement)
10211022 return false;
10221023
1023  // Be safe. Don't try to perform replacements if the predictions don't
1024  // agree.
1025  if (predictionHandlingMode == RequireSamePrediction
1026  && m_currentNode->prediction() != replacement->prediction())
1027  return false;
1028 
10291024#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
10301025 dataLogF(" Replacing @%u -> @%u", m_currentNode->index(), replacement->index());
10311026#endif

@@private:
12301225 case JSConstant:
12311226 // This is strange, but necessary. Some phases will convert nodes to constants,
12321227 // which may result in duplicated constants. We use CSE to clean this up.
1233  setReplacement(constantCSE(node), AllowPredictionMismatch);
 1228 setReplacement(constantCSE(node));
12341229 break;
12351230
12361231 case WeakJSConstant:
143562

Source/JavaScriptCore/dfg/DFGCommon.h

@@struct NodePointerTraits {
8383 static void dump(Node* value, PrintStream& out);
8484};
8585
86 enum UseKind {
87  UntypedUse,
88  DoubleUse,
89  LastUseKind // Must always be the last entry in the enum, as it is used to denote the number of enum elements.
90 };
91 
9286// Use RefChildren if the child ref counts haven't already been adjusted using
9387// other means and either of the following is true:
9488// - The node you're creating is MustGenerate.

@@enum RefNodeMode {
106100 DontRefNode
107101};
108102
109 inline const char* useKindToString(UseKind useKind)
110 {
111  switch (useKind) {
112  case UntypedUse:
113  return "";
114  case DoubleUse:
115  return "d";
116  default:
117  RELEASE_ASSERT_NOT_REACHED();
118  return 0;
119  }
120 }
121 
122103inline bool isARMv7s()
123104{
124105#if CPU(APPLE_ARMV7S)

@@enum UnificationState {
236217 GloballyUnified
237218};
238219
 220enum OperandSpeculationMode { AutomaticOperandSpeculation, ManualOperandSpeculation };
 221
239222enum SpeculationDirection { ForwardSpeculation, BackwardSpeculation };
240223
241224} } // namespace JSC::DFG
143562

Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp

@@private:
103103 set = node->structure();
104104 else
105105 set = node->structureSet();
106  if (!isCellSpeculation(value.m_type))
107  break;
108106 if (value.m_currentKnownStructure.isSubsetOf(set)) {
109107 ASSERT(node->refCount() == 1);
 108 m_state.execute(indexInBlock); // Catch the fact that we may filter on cell.
110109 node->setOpAndDefaultFlags(Phantom);
111110 eliminated = true;
112111 break;

@@private:
114113 StructureAbstractValue& structureValue = value.m_futurePossibleStructure;
115114 if (structureValue.isSubsetOf(set)
116115 && structureValue.hasSingleton()) {
117  node->convertToStructureTransitionWatchpoint(structureValue.singleton());
118  changed = true;
 116 Structure* structure = structureValue.singleton();
 117 m_state.execute(indexInBlock); // Catch the fact that we may filter on cell.
 118 node->convertToStructureTransitionWatchpoint(structure);
 119 eliminated = true;
 120 break;
119121 }
120122 break;
121123 }

@@private:
149151 case GetById:
150152 case GetByIdFlush: {
151153 CodeOrigin codeOrigin = node->codeOrigin;
152  Node* child = node->child1().node();
 154 Edge childEdge = node->child1();
 155 Node* child = childEdge.node();
153156 unsigned identifierNumber = node->identifierNumber();
154157
155  if (!isCellSpeculation(child->prediction()))
 158 if (childEdge.useKind() != CellUse)
156159 break;
157160
158161 Structure* structure = m_state.forNode(child).bestProvenStructure();

@@private:
164167 GetByIdStatus status = GetByIdStatus::computeFor(
165168 globalData(), structure, codeBlock()->identifier(identifierNumber));
166169
167  if (!status.isSimple())
 170 if (!status.isSimple()) {
 171 // FIXME: We could handle prototype cases.
 172 // https://bugs.webkit.org/show_bug.cgi?id=110386
168173 break;
 174 }
169175
170176 ASSERT(status.structureSet().size() == 1);
171177 ASSERT(status.chain().isEmpty());

@@private:
181187 ASSERT(m_state.forNode(child).m_futurePossibleStructure.isSubsetOf(StructureSet(structure)));
182188 m_insertionSet.insertNode(
183189 indexInBlock, RefChildren, DontRefNode, SpecNone,
184  StructureTransitionWatchpoint, codeOrigin, OpInfo(structure), child);
 190 StructureTransitionWatchpoint, codeOrigin, OpInfo(structure), childEdge);
 191 } else if (m_state.forNode(child).m_type & ~SpecCell) {
 192 m_insertionSet.insertNode(
 193 indexInBlock, RefChildren, DontRefNode, SpecNone,
 194 Phantom, codeOrigin, childEdge);
185195 }
186196
187  Node* propertyStorage;
 197 childEdge.setUseKind(KnownCellUse);
 198
 199 Edge propertyStorage;
188200
189201 child->ref();
190202 if (isInlineOffset(status.offset()))
191  propertyStorage = child;
 203 propertyStorage = childEdge;
192204 else {
193  propertyStorage = m_insertionSet.insertNode(
 205 propertyStorage = Edge(m_insertionSet.insertNode(
194206 indexInBlock, DontRefChildren, RefNode, SpecNone, GetButterfly, codeOrigin,
195  child);
 207 childEdge));
196208 }
197209
198210 node->convertToGetByOffset(m_graph.m_storageAccessData.size(), propertyStorage);

@@private:
207219 case PutById:
208220 case PutByIdDirect: {
209221 CodeOrigin codeOrigin = node->codeOrigin;
210  Node* child = node->child1().node();
 222 Edge childEdge = node->child1();
 223 Node* child = childEdge.node();
211224 unsigned identifierNumber = node->identifierNumber();
212225
 226 ASSERT(childEdge.useKind() == CellUse);
 227
213228 Structure* structure = m_state.forNode(child).bestProvenStructure();
214229 if (!structure)
215230 break;

@@private:
238253 ASSERT(m_state.forNode(child).m_futurePossibleStructure.isSubsetOf(StructureSet(structure)));
239254 m_insertionSet.insertNode(
240255 indexInBlock, RefChildren, DontRefNode, SpecNone,
241  StructureTransitionWatchpoint, codeOrigin, OpInfo(structure), child);
 256 StructureTransitionWatchpoint, codeOrigin, OpInfo(structure), childEdge);
 257 } else if (m_state.forNode(child).m_type & ~SpecCell) {
 258 m_insertionSet.insertNode(
 259 indexInBlock, RefChildren, DontRefNode, SpecNone,
 260 Phantom, codeOrigin, childEdge);
242261 }
243262
 263 childEdge.setUseKind(KnownCellUse);
 264
244265 StructureTransitionData* transitionData = 0;
245266 if (status.isSimpleTransition()) {
246267 transitionData = m_graph.addStructureTransitionData(

@@private:
264285 }
265286 }
266287
267  Node* propertyStorage;
 288 Edge propertyStorage;
268289
269290 if (isInlineOffset(status.offset())) {
270291 child->ref(); // The child will be used as the property index, so ref it to reflect the double use.
271  propertyStorage = child;
 292 propertyStorage = childEdge;
272293 } else if (status.isSimpleReplace() || structure->outOfLineCapacity() == status.newStructure()->outOfLineCapacity()) {
273  propertyStorage = m_insertionSet.insertNode(
274  indexInBlock, RefChildren, RefNode, SpecNone, GetButterfly, codeOrigin, child);
 294 propertyStorage = Edge(m_insertionSet.insertNode(
 295 indexInBlock, RefChildren, RefNode, SpecNone, GetButterfly, codeOrigin, childEdge));
275296 } else if (!structure->outOfLineCapacity()) {
276297 ASSERT(status.newStructure()->outOfLineCapacity());
277298 ASSERT(!isInlineOffset(status.offset()));
278  propertyStorage = m_insertionSet.insertNode(
 299 propertyStorage = Edge(m_insertionSet.insertNode(
279300 indexInBlock, RefChildren, RefNode, SpecNone, AllocatePropertyStorage,
280  codeOrigin, OpInfo(transitionData), child);
 301 codeOrigin, OpInfo(transitionData), childEdge));
281302 } else {
282303 ASSERT(structure->outOfLineCapacity());
283304 ASSERT(status.newStructure()->outOfLineCapacity() > structure->outOfLineCapacity());
284305 ASSERT(!isInlineOffset(status.offset()));
285306
286  propertyStorage = m_insertionSet.insertNode(
 307 propertyStorage = Edge(m_insertionSet.insertNode(
287308 indexInBlock, RefChildren, RefNode, SpecNone, ReallocatePropertyStorage,
288309 codeOrigin, OpInfo(transitionData),
289  child,
290  m_insertionSet.insertNode(
 310 childEdge,
 311 Edge(m_insertionSet.insertNode(
291312 indexInBlock, DontRefChildren, DontRefNode, SpecNone, GetButterfly,
292  codeOrigin, child));
 313 codeOrigin, childEdge))));
293314 }
294315
295316 if (status.isSimpleTransition()) {
296317 m_insertionSet.insertNode(
297318 indexInBlock, RefChildren, DontRefNode, SpecNone, PutStructure, codeOrigin,
298  OpInfo(transitionData), child);
 319 OpInfo(transitionData), childEdge);
299320 }
300321
301322 node->convertToPutByOffset(m_graph.m_storageAccessData.size(), propertyStorage);

@@private:
340361 m_graph.convertToConstant(node, value);
341362 Node* phantom = m_insertionSet.insertNode(
342363 indexInBlock, DontRefChildren, DontRefNode, SpecNone, PhantomLocal,
343  codeOrigin, OpInfo(variable), phi);
 364 codeOrigin, OpInfo(variable), Edge(phi));
344365 block->variablesAtHead.operand(variable->local()) = phantom;
345366 block->variablesAtTail.operand(variable->local()) = phantom;
346367

@@private:
391412 if (cell->structure()->transitionWatchpointSetIsStillValid()) {
392413 m_insertionSet.insertNode(
393414 indexInBlock, RefChildren, DontRefNode, SpecNone, StructureTransitionWatchpoint,
394  codeOrigin, OpInfo(cell->structure()), weakConstant);
 415 codeOrigin, OpInfo(cell->structure()), Edge(weakConstant, CellUse));
395416 return;
396417 }
397418
398419 m_insertionSet.insertNode(
399420 indexInBlock, RefChildren, DontRefNode, SpecNone, CheckStructure, codeOrigin,
400  OpInfo(m_graph.addStructureSet(cell->structure())), weakConstant);
 421 OpInfo(m_graph.addStructureSet(cell->structure())), Edge(weakConstant, CellUse));
401422 }
402423
403424 // This is necessary because the CFA may reach conclusions about constants based on its
143562

Source/JavaScriptCore/dfg/DFGDriver.cpp

@@inline bool compile(CompileMode compileM
144144 if (!changed)
145145 break;
146146
147  dfg.resetExitStates();
148  performFixup(dfg);
149147 performCPSRethreading(dfg);
150148 }
151149
143562

Source/JavaScriptCore/dfg/DFGEdge.cpp

@@namespace JSC { namespace DFG {
3434
3535void Edge::dump(PrintStream& out) const
3636{
37  out.print(useKindToString(useKind()), node());
 37 if (useKind() != UntypedUse)
 38 out.print(useKind(), ":");
 39 out.print(node());
3840}
3941
4042} } // namespace JSC::DFG
143562

Source/JavaScriptCore/dfg/DFGEdge.h

3131#if ENABLE(DFG_JIT)
3232
3333#include "DFGCommon.h"
 34#include "DFGUseKind.h"
3435
3536namespace JSC { namespace DFG {
3637

@@public:
6263 m_encodedWord = makeWord(node, useKind());
6364 }
6465
65  UseKind useKind() const
 66 UseKind useKindUnchecked() const
6667 {
67  ASSERT(node());
6868 unsigned masked = m_encodedWord & (((1 << shift()) - 1));
6969 ASSERT(masked < LastUseKind);
70  return static_cast<UseKind>(masked);
 70 UseKind result = static_cast<UseKind>(masked);
 71 ASSERT(node() || result == UntypedUse);
 72 return result;
 73 }
 74 UseKind useKind() const
 75 {
 76 ASSERT(node());
 77 return useKindUnchecked();
7178 }
7279 void setUseKind(UseKind useKind)
7380 {

@@public:
96103private:
97104 friend class AdjacencyList;
98105
99  static uint32_t shift() { return 2; }
 106 static uint32_t shift() { return 4; }
100107
101108 static uintptr_t makeWord(Node* node, UseKind useKind)
102109 {
143562

Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

@@public:
4545
4646 bool run()
4747 {
 48 ASSERT(m_graph.m_fixpointState == BeforeFixpoint);
 49 ASSERT(m_graph.m_form == ThreadedCPS);
 50
4851 for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex)
4952 fixupBlock(m_graph.m_blocks[blockIndex].get());
5053 return true;

@@private:
7679#endif
7780
7881 switch (op) {
79  case GetById: {
80  if (m_graph.m_fixpointState > BeforeFixpoint)
 82 case SetLocal: {
 83 VariableAccessData* variable = node->variableAccessData();
 84
 85 if (variable->isCaptured()
 86 || m_graph.isCreatedThisArgument(variable->local()))
8187 break;
8288
83  if (!isInt32Speculation(node->prediction()))
 89 if (variable->shouldUseDoubleFormat()) {
 90 fixDoubleEdge(node->child1(), NumberUse, ForwardSpeculation);
8491 break;
85  if (codeBlock()->identifier(node->identifierNumber()) != globalData().propertyNames->length)
 92 }
 93
 94 SpeculatedType predictedType = variable->argumentAwarePrediction();
 95 if (isInt32Speculation(predictedType))
 96 node->child1().setUseKind(Int32Use);
 97 else if (isCellSpeculation(predictedType))
 98 node->child1().setUseKind(CellUse);
 99 else if (isBooleanSpeculation(predictedType))
 100 node->child1().setUseKind(BooleanUse);
 101 break;
 102 }
 103
 104 case BitAnd:
 105 case BitOr:
 106 case BitXor:
 107 case BitRShift:
 108 case BitLShift:
 109 case BitURShift: {
 110 fixIntEdge(node->child1());
 111 fixIntEdge(node->child2());
 112 break;
 113 }
 114
 115 case UInt32ToNumber: {
 116 node->child1().setUseKind(KnownInt32Use);
 117 break;
 118 }
 119
 120 case DoubleAsInt32: {
 121 RELEASE_ASSERT_NOT_REACHED();
 122 break;
 123 }
 124
 125 case ValueToInt32: {
 126 if (node->child1()->shouldSpeculateInteger()) {
 127 node->child1().setUseKind(Int32Use);
86128 break;
87  ArrayProfile* arrayProfile =
88  m_graph.baselineCodeBlockFor(node->codeOrigin)->getArrayProfile(
89  node->codeOrigin.bytecodeIndex);
90  ArrayMode arrayMode = ArrayMode(Array::SelectUsingPredictions);
91  if (arrayProfile) {
92  arrayProfile->computeUpdatedPrediction(m_graph.baselineCodeBlockFor(node->codeOrigin));
93  arrayMode = ArrayMode::fromObserved(arrayProfile, Array::Read, false);
94  arrayMode = arrayMode.refine(
95  node->child1()->prediction(), node->prediction());
96  if (arrayMode.supportsLength() && arrayProfile->hasDefiniteStructure()) {
97  m_insertionSet.insertNode(
98  m_indexInBlock, RefChildren, DontRefNode, SpecNone, CheckStructure,
99  node->codeOrigin, OpInfo(m_graph.addStructureSet(arrayProfile->expectedStructure())),
100  node->child1().node());
 129 }
 130
 131 if (node->child1()->shouldSpeculateNumber()) {
 132 node->child1().setUseKind(NumberUse);
 133 break;
 134 }
 135
 136 if (node->child1()->shouldSpeculateBoolean()) {
 137 node->child1().setUseKind(BooleanUse);
 138 break;
 139 }
 140
 141 node->child1().setUseKind(NotCellUse);
 142 break;
 143 }
 144
 145 case Int32ToDouble: {
 146 RELEASE_ASSERT_NOT_REACHED();
 147 break;
 148 }
 149
 150 case ValueAdd: {
 151 if (attemptToMakeIntegerAdd(node))
 152 break;
 153 if (Node::shouldSpeculateNumberExpectingDefined(node->child1().node(), node->child2().node())) {
 154 fixDoubleEdge(node->child1());
 155 fixDoubleEdge(node->child2());
 156 break;
 157 }
 158 break;
 159 }
 160
 161 case ArithAdd:
 162 case ArithSub: {
 163 if (attemptToMakeIntegerAdd(node))
 164 break;
 165 fixDoubleEdge(node->child1());
 166 fixDoubleEdge(node->child2());
 167 break;
 168 }
 169
 170 case ArithNegate: {
 171 if (m_graph.negateShouldSpeculateInteger(node)) {
 172 node->child1().setUseKind(Int32Use);
 173 break;
 174 }
 175 fixDoubleEdge(node->child1());
 176 break;
 177 }
 178
 179 case ArithMul: {
 180 if (m_graph.mulShouldSpeculateInteger(node)) {
 181 node->child1().setUseKind(Int32Use);
 182 node->child2().setUseKind(Int32Use);
 183 break;
 184 }
 185 fixDoubleEdge(node->child1());
 186 fixDoubleEdge(node->child2());
 187 break;
 188 }
 189
 190 case ArithDiv: {
 191 if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node())
 192 && node->canSpeculateInteger()) {
 193 if (isX86() || isARMv7s()) {
 194 node->child1().setUseKind(Int32Use);
 195 node->child2().setUseKind(Int32Use);
 196 break;
101197 }
102  } else
103  arrayMode = arrayMode.refine(node->child1()->prediction(), node->prediction());
104  if (!arrayMode.supportsLength())
 198 injectInt32ToDoubleNode(node->child1());
 199 injectInt32ToDoubleNode(node->child2());
 200
 201 // We don't need to do ref'ing on the children because we're stealing them from
 202 // the original division.
 203 Node* newDivision = m_insertionSet.insertNode(
 204 m_indexInBlock, DontRefChildren, RefNode, SpecDouble, *node);
 205
 206 node->setOp(DoubleAsInt32);
 207 node->children.initialize(Edge(newDivision, KnownNumberUse), Edge(), Edge());
105208 break;
106  node->setOp(GetArrayLength);
107  ASSERT(node->flags() & NodeMustGenerate);
108  node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
109  m_graph.deref(node);
110  node->setArrayMode(arrayMode);
 209 }
 210 fixDoubleEdge(node->child1());
 211 fixDoubleEdge(node->child2());
 212 break;
 213 }
111214
112  Node* storage = checkArray(arrayMode, node->codeOrigin, node->child1().node(), 0, lengthNeedsStorage, node->shouldGenerate());
113  if (!storage)
 215 case ArithMin:
 216 case ArithMax:
 217 case ArithMod: {
 218 if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node())
 219 && node->canSpeculateInteger()) {
 220 node->child1().setUseKind(Int32Use);
 221 node->child2().setUseKind(Int32Use);
 222 break;
 223 }
 224 fixDoubleEdge(node->child1());
 225 fixDoubleEdge(node->child2());
 226 break;
 227 }
 228
 229 case ArithAbs: {
 230 if (node->child1()->shouldSpeculateIntegerForArithmetic()
 231 && node->canSpeculateInteger()) {
 232 node->child1().setUseKind(Int32Use);
114233 break;
 234 }
 235 fixDoubleEdge(node->child1());
 236 break;
 237 }
115238
116  node->children.child2() = Edge(storage);
 239 case ArithSqrt: {
 240 fixDoubleEdge(node->child1());
 241 break;
 242 }
 243
 244 case LogicalNot: {
 245 if (node->child1()->shouldSpeculateBoolean())
 246 node->child1().setUseKind(BooleanUse);
 247 else if (node->child1()->shouldSpeculateObjectOrOther())
 248 node->child1().setUseKind(ObjectOrOtherUse);
 249 else if (node->child1()->shouldSpeculateInteger())
 250 node->child1().setUseKind(Int32Use);
 251 else if (node->child1()->shouldSpeculateNumber())
 252 fixDoubleEdge(node->child1());
117253 break;
118254 }
119  case GetIndexedPropertyStorage: {
120  ASSERT(node->arrayMode().canCSEStorage());
 255
 256 case TypeOf: {
 257 if (node->child1()->shouldSpeculateString())
 258 node->child1().setUseKind(StringUse);
 259 else if (node->child1()->shouldSpeculateCell())
 260 node->child1().setUseKind(CellUse);
121261 break;
122262 }
 263
 264 case CompareEq:
 265 case CompareEqConstant:
 266 case CompareLess:
 267 case CompareLessEq:
 268 case CompareGreater:
 269 case CompareGreaterEq: {
 270 if (node->op() == CompareEqConstant)
 271 break;
 272 if (Node::shouldSpeculateInteger(node->child1().node(), node->child2().node())) {
 273 node->child1().setUseKind(Int32Use);
 274 node->child2().setUseKind(Int32Use);
 275 break;
 276 }
 277 if (Node::shouldSpeculateNumber(node->child1().node(), node->child2().node())) {
 278 fixDoubleEdge(node->child1());
 279 fixDoubleEdge(node->child2());
 280 break;
 281 }
 282 if (node->op() != CompareEq)
 283 break;
 284 if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString())
 285 break;
 286 if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
 287 node->child1().setUseKind(ObjectUse);
 288 node->child2().setUseKind(ObjectUse);
 289 break;
 290 }
 291 if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObjectOrOther()) {
 292 node->child1().setUseKind(ObjectUse);
 293 node->child2().setUseKind(ObjectOrOtherUse);
 294 break;
 295 }
 296 if (node->child1()->shouldSpeculateObjectOrOther() && node->child2()->shouldSpeculateObject()) {
 297 node->child1().setUseKind(ObjectOrOtherUse);
 298 node->child2().setUseKind(ObjectUse);
 299 break;
 300 }
 301 break;
 302 }
 303
 304 case CompareStrictEq:
 305 case CompareStrictEqConstant: {
 306 if (node->op() == CompareStrictEqConstant)
 307 break;
 308 if (Node::shouldSpeculateInteger(node->child1().node(), node->child2().node())) {
 309 node->child1().setUseKind(Int32Use);
 310 node->child2().setUseKind(Int32Use);
 311 break;
 312 }
 313 if (Node::shouldSpeculateNumber(node->child1().node(), node->child2().node())) {
 314 fixDoubleEdge(node->child1());
 315 fixDoubleEdge(node->child2());
 316 break;
 317 }
 318 if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString())
 319 break;
 320 if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
 321 node->child1().setUseKind(ObjectUse);
 322 node->child2().setUseKind(ObjectUse);
 323 break;
 324 }
 325 break;
 326 }
 327
 328 case StringCharAt:
 329 case StringCharCodeAt: {
 330 // Currently we have no good way of refining these.
 331 ASSERT(node->arrayMode() == ArrayMode(Array::String));
 332 blessArrayOperation(node->child1(), node->child2(), node->child3());
 333 node->child1().setUseKind(KnownCellUse);
 334 node->child2().setUseKind(Int32Use);
 335 break;
 336 }
 337
123338 case GetByVal: {
124339 node->setArrayMode(
125340 node->arrayMode().refine(

@@private:
127342 node->child2()->prediction(),
128343 SpecNone, node->flags()));
129344
130  blessArrayOperation(node->child1(), node->child2(), 2);
 345 blessArrayOperation(node->child1(), node->child2(), node->child3());
131346
132347 ArrayMode arrayMode = node->arrayMode();
133348 if (arrayMode.type() == Array::Double

@@private:
138353 && !(node->flags() & NodeUsedAsOther))
139354 node->setArrayMode(arrayMode.withSpeculation(Array::SaneChain));
140355
 356 switch (node->arrayMode().type()) {
 357 case Array::SelectUsingPredictions:
 358 case Array::Unprofiled:
 359 case Array::Undecided:
 360 RELEASE_ASSERT_NOT_REACHED();
 361 break;
 362 case Array::Generic:
 363#if USE(JSVALUE32_64)
 364 node->child1().setUseKind(CellUse); // Speculating cell due to register pressure on 32-bit.
 365#endif
 366 break;
 367 case Array::ForceExit:
 368 break;
 369 default:
 370 node->child1().setUseKind(KnownCellUse);
 371 node->child2().setUseKind(Int32Use);
 372 break;
 373 }
 374
141375 break;
142376 }
143  case StringCharAt:
144  case StringCharCodeAt: {
145  // Currently we have no good way of refining these.
146  ASSERT(node->arrayMode() == ArrayMode(Array::String));
147  blessArrayOperation(node->child1(), node->child2(), 2);
 377
 378 case PutByVal:
 379 case PutByValAlias: {
 380 Edge& child1 = m_graph.varArgChild(node, 0);
 381 Edge& child2 = m_graph.varArgChild(node, 1);
 382 Edge& child3 = m_graph.varArgChild(node, 2);
 383
 384 node->setArrayMode(
 385 node->arrayMode().refine(
 386 child1->prediction(),
 387 child2->prediction(),
 388 child3->prediction()));
 389
 390 blessArrayOperation(child1, child2, m_graph.varArgChild(node, 3));
 391
 392 switch (node->arrayMode().modeForPut().type()) {
 393 case Array::SelectUsingPredictions:
 394 case Array::Unprofiled:
 395 case Array::Undecided:
 396 RELEASE_ASSERT_NOT_REACHED();
 397 break;
 398 case Array::ForceExit:
 399 case Array::Generic:
 400#if USE(JSVALUE32_64)
 401 // Due to register pressure on 32-bit, we speculate cell and
 402 // ignore the base-is-not-cell case entirely by letting the
 403 // baseline JIT handle it.
 404 child1.setUseKind(CellUse);
 405#endif
 406 break;
 407 case Array::Int32:
 408 child1.setUseKind(KnownCellUse);
 409 child2.setUseKind(Int32Use);
 410 child3.setUseKind(Int32Use);
 411 break;
 412 case Array::Double:
 413 child1.setUseKind(KnownCellUse);
 414 child2.setUseKind(Int32Use);
 415 fixDoubleEdge(child3, RealNumberUse);
 416 break;
 417 case Array::Int8Array:
 418 case Array::Int16Array:
 419 case Array::Int32Array:
 420 case Array::Uint8Array:
 421 case Array::Uint8ClampedArray:
 422 case Array::Uint16Array:
 423 case Array::Uint32Array:
 424 child1.setUseKind(KnownCellUse);
 425 child2.setUseKind(Int32Use);
 426 if (child3->shouldSpeculateInteger())
 427 child3.setUseKind(Int32Use);
 428 else
 429 fixDoubleEdge(child3);
 430 break;
 431 case Array::Float32Array:
 432 case Array::Float64Array:
 433 child1.setUseKind(KnownCellUse);
 434 child2.setUseKind(Int32Use);
 435 fixDoubleEdge(child3);
 436 break;
 437 default:
 438 child1.setUseKind(KnownCellUse);
 439 child2.setUseKind(Int32Use);
 440 break;
 441 }
148442 break;
149443 }
150444

@@private:
163457 node->child1()->prediction() & SpecCell,
164458 SpecInt32,
165459 node->child2()->prediction()));
166  blessArrayOperation(node->child1(), Edge(), 2);
 460 blessArrayOperation(node->child1(), Edge(), node->child3());
 461 node->child1().setUseKind(KnownCellUse);
167462
168463 switch (node->arrayMode().type()) {
 464 case Array::Int32:
 465 node->child2().setUseKind(Int32Use);
 466 break;
169467 case Array::Double:
170  fixDoubleEdge(1);
 468 fixDoubleEdge(node->child2());
171469 break;
172470 default:
173471 break;

@@private:
176474 }
177475
178476 case ArrayPop: {
179  blessArrayOperation(node->child1(), Edge(), 1);
180  break;
181  }
182 
183  case BitAnd:
184  case BitOr:
185  case BitXor:
186  case BitRShift:
187  case BitLShift:
188  case BitURShift: {
189  fixIntEdge(node->children.child1());
190  fixIntEdge(node->children.child2());
191  break;
192  }
193 
194  case CompareEq:
195  case CompareLess:
196  case CompareLessEq:
197  case CompareGreater:
198  case CompareGreaterEq:
199  case CompareStrictEq: {
200  if (Node::shouldSpeculateInteger(node->child1().node(), node->child2().node()))
201  break;
202  if (!Node::shouldSpeculateNumber(node->child1().node(), node->child2().node()))
203  break;
204  fixDoubleEdge(0);
205  fixDoubleEdge(1);
 477 blessArrayOperation(node->child1(), Edge(), node->child2());
 478 node->child1().setUseKind(KnownCellUse);
206479 break;
207480 }
208481
209  case LogicalNot: {
210  if (node->child1()->shouldSpeculateInteger())
211  break;
212  if (!node->child1()->shouldSpeculateNumber())
213  break;
214  fixDoubleEdge(0);
 482 case RegExpExec:
 483 case RegExpTest: {
 484 node->child1().setUseKind(CellUse);
 485 node->child2().setUseKind(CellUse);
215486 break;
216487 }
217488
218489 case Branch: {
219  if (!node->child1()->shouldSpeculateInteger()
220  && node->child1()->shouldSpeculateNumber())
221  fixDoubleEdge(0);
 490 if (node->child1()->shouldSpeculateBoolean())
 491 node->child1().setUseKind(BooleanUse);
 492 else if (node->child1()->shouldSpeculateObjectOrOther())
 493 node->child1().setUseKind(ObjectOrOtherUse);
 494 else if (node->child1()->shouldSpeculateInteger())
 495 node->child1().setUseKind(Int32Use);
 496 else if (node->child1()->shouldSpeculateNumber())
 497 fixDoubleEdge(node->child1());
222498
223499 Node* logicalNot = node->child1().node();
224500 if (logicalNot->op() == LogicalNot

@@private:
261537 break;
262538 }
263539
264  case SetLocal: {
265  if (node->variableAccessData()->isCaptured())
266  break;
267  if (!node->variableAccessData()->shouldUseDoubleFormat())
268  break;
269  fixDoubleEdge(0, ForwardSpeculation);
 540 case ToPrimitive: {
 541 if (node->child1()->shouldSpeculateInteger())
 542 node->child1().setUseKind(Int32Use);
 543 // FIXME: Add string speculation here.
 544 // https://bugs.webkit.org/show_bug.cgi?id=110175
270545 break;
271546 }
272547
273  case ArithAdd:
274  case ValueAdd: {
275  if (m_graph.addShouldSpeculateInteger(node))
 548 case NewArray: {
 549 for (unsigned i = m_graph.varArgNumChildren(node); i--;) {
 550 node->setIndexingType(
 551 leastUpperBoundOfIndexingTypeAndType(
 552 node->indexingType(), m_graph.varArgChild(node, i)->prediction()));
 553 }
 554 switch (node->indexingType()) {
 555 case ALL_BLANK_INDEXING_TYPES:
 556 CRASH();
 557 break;
 558 case ALL_UNDECIDED_INDEXING_TYPES:
 559 if (node->numChildren()) {
 560 // This will only happen if the children have no type predictions. We
 561 // would have already exited by now, but insert a forced exit just to
 562 // be safe.
 563 m_insertionSet.insertNode(
 564 m_indexInBlock, DontRefChildren, DontRefNode, SpecNone, ForceOSRExit,
 565 node->codeOrigin);
 566 }
 567 break;
 568 case ALL_INT32_INDEXING_TYPES:
 569 for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
 570 m_graph.m_varArgChildren[node->firstChild() + operandIndex].setUseKind(Int32Use);
 571 break;
 572 case ALL_DOUBLE_INDEXING_TYPES:
 573 for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
 574 m_graph.m_varArgChildren[node->firstChild() + operandIndex].setUseKind(RealNumberUse);
276575 break;
277  if (!Node::shouldSpeculateNumberExpectingDefined(node->child1().node(), node->child2().node()))
 576 case ALL_CONTIGUOUS_INDEXING_TYPES:
 577 case ALL_ARRAY_STORAGE_INDEXING_TYPES:
278578 break;
279  fixDoubleEdge(0);
280  fixDoubleEdge(1);
 579 default:
 580 CRASH();
 581 break;
 582 }
281583 break;
282584 }
283585
284  case ArithSub: {
285  if (m_graph.addShouldSpeculateInteger(node)
286  && node->canSpeculateInteger())
287  break;
288  fixDoubleEdge(0);
289  fixDoubleEdge(1);
 586 case NewArrayWithSize: {
 587 node->child1().setUseKind(Int32Use);
290588 break;
291589 }
292590
293  case ArithNegate: {
294  if (m_graph.negateShouldSpeculateInteger(node))
295  break;
296  fixDoubleEdge(0);
 591 case ConvertThis: {
 592 // FIXME: Use Phantom(type check) and Identity instead.
 593 // https://bugs.webkit.org/show_bug.cgi?id=110395
 594 if (isOtherSpeculation(node->child1()->prediction()))
 595 node->child1().setUseKind(OtherUse);
 596 else if (isObjectSpeculation(node->child1()->prediction()))
 597 node->child1().setUseKind(ObjectUse);
297598 break;
298599 }
299600
300  case ArithMin:
301  case ArithMax:
302  case ArithMod: {
303  if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node())
304  && node->canSpeculateInteger())
305  break;
306  fixDoubleEdge(0);
307  fixDoubleEdge(1);
 601 case CreateThis: {
 602 node->child1().setUseKind(CellUse);
308603 break;
309604 }
310605
311  case ArithMul: {
312  if (m_graph.mulShouldSpeculateInteger(node))
313  break;
314  fixDoubleEdge(0);
315  fixDoubleEdge(1);
 606 case GetMyArgumentByVal:
 607 case GetMyArgumentByValSafe: {
 608 node->child1().setUseKind(Int32Use);
316609 break;
317610 }
318 
319  case ArithDiv: {
320  if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node())
321  && node->canSpeculateInteger()) {
322  if (isX86() || isARMv7s())
323  break;
324  injectInt32ToDoubleNode(0);
325  injectInt32ToDoubleNode(1);
326 
327  // We don't need to do ref'ing on the children because we're stealing them from
328  // the original division.
329  Node* newDivision = m_insertionSet.insertNode(
330  m_indexInBlock, DontRefChildren, RefNode, SpecDouble, *node);
331 
332  node->setOp(DoubleAsInt32);
333  node->children.initialize(Edge(newDivision, DoubleUse), Edge(), Edge());
334  break;
335  }
336  fixDoubleEdge(0);
337  fixDoubleEdge(1);
 611
 612 case GetScopeRegisters:
 613 case PutScopedVar:
 614 case SkipTopScope:
 615 case SkipScope:
 616 case SetCallee:
 617 case SetMyScope:
 618 case PutStructure:
 619 case AllocatePropertyStorage:
 620 case ReallocatePropertyStorage:
 621 case GetScope:
 622 case GetButterfly: {
 623 node->child1().setUseKind(KnownCellUse);
338624 break;
339625 }
340626
341  case ArithAbs: {
342  if (node->child1()->shouldSpeculateIntegerForArithmetic()
343  && node->canSpeculateInteger())
 627 case GetById: {
 628 if (!node->child1()->shouldSpeculateCell())
 629 break;
 630 node->child1().setUseKind(CellUse);
 631 if (!isInt32Speculation(node->prediction()))
 632 break;
 633 if (codeBlock()->identifier(node->identifierNumber()) != globalData().propertyNames->length)
344634 break;
345  fixDoubleEdge(0);
 635 ArrayProfile* arrayProfile =
 636 m_graph.baselineCodeBlockFor(node->codeOrigin)->getArrayProfile(
 637 node->codeOrigin.bytecodeIndex);
 638 ArrayMode arrayMode = ArrayMode(Array::SelectUsingPredictions);
 639 if (arrayProfile) {
 640 arrayProfile->computeUpdatedPrediction(m_graph.baselineCodeBlockFor(node->codeOrigin));
 641 arrayMode = ArrayMode::fromObserved(arrayProfile, Array::Read, false);
 642 arrayMode = arrayMode.refine(
 643 node->child1()->prediction(), node->prediction());
 644 if (arrayMode.supportsLength() && arrayProfile->hasDefiniteStructure()) {
 645 m_insertionSet.insertNode(
 646 m_indexInBlock, RefChildren, DontRefNode, SpecNone, CheckStructure,
 647 node->codeOrigin, OpInfo(m_graph.addStructureSet(arrayProfile->expectedStructure())),
 648 node->child1());
 649 }
 650 } else
 651 arrayMode = arrayMode.refine(node->child1()->prediction(), node->prediction());
 652 if (!arrayMode.supportsLength())
 653 break;
 654 node->setOp(GetArrayLength);
 655 ASSERT(node->flags() & NodeMustGenerate);
 656 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
 657 node->child1().setUseKind(KnownCellUse);
 658 m_graph.deref(node);
 659 node->setArrayMode(arrayMode);
 660
 661 Node* storage = checkArray(arrayMode, node->codeOrigin, node->child1().node(), 0, lengthNeedsStorage, node->shouldGenerate());
 662 if (!storage)
 663 break;
 664
 665 node->child2() = Edge(storage);
346666 break;
347667 }
348668
349  case ArithSqrt: {
350  fixDoubleEdge(0);
 669 case GetByIdFlush: {
 670 if (node->child1()->shouldSpeculateCell())
 671 node->child1().setUseKind(CellUse);
351672 break;
352673 }
353674
354  case PutByVal:
355  case PutByValAlias: {
356  Edge child1 = m_graph.varArgChild(node, 0);
357  Edge child2 = m_graph.varArgChild(node, 1);
358  Edge child3 = m_graph.varArgChild(node, 2);
359 
360  node->setArrayMode(
361  node->arrayMode().refine(
362  child1->prediction(),
363  child2->prediction(),
364  child3->prediction()));
365 
366  blessArrayOperation(child1, child2, 3);
 675 case CheckExecutable:
 676 case CheckStructure:
 677 case ForwardCheckStructure:
 678 case StructureTransitionWatchpoint:
 679 case ForwardStructureTransitionWatchpoint:
 680 case CheckFunction:
 681 case PutById:
 682 case PutByIdDirect:
 683 case CheckHasInstance: {
 684 node->child1().setUseKind(CellUse);
 685 break;
 686 }
367687
368  switch (node->arrayMode().modeForPut().type()) {
369  case Array::Double:
370  fixDoubleEdge(2);
371  break;
372  case Array::Int8Array:
373  case Array::Int16Array:
374  case Array::Int32Array:
375  case Array::Uint8Array:
376  case Array::Uint8ClampedArray:
377  case Array::Uint16Array:
378  case Array::Uint32Array:
379  if (!child3->shouldSpeculateInteger())
380  fixDoubleEdge(2);
381  break;
382  case Array::Float32Array:
383  case Array::Float64Array:
384  fixDoubleEdge(2);
 688 case CheckArray: {
 689 switch (node->arrayMode().type()) {
 690 case Array::String:
 691 node->child1().setUseKind(StringUse);
385692 break;
386693 default:
 694 node->child1().setUseKind(CellUse);
387695 break;
388696 }
389697 break;
390698 }
391699
392  case NewArray: {
393  for (unsigned i = m_graph.varArgNumChildren(node); i--;) {
394  node->setIndexingType(
395  leastUpperBoundOfIndexingTypeAndType(
396  node->indexingType(), m_graph.varArgChild(node, i)->prediction()));
397  }
398  if (node->indexingType() == ArrayWithDouble) {
399  for (unsigned i = m_graph.varArgNumChildren(node); i--;)
400  fixDoubleEdge(i);
401  }
 700 case Arrayify:
 701 case ArrayifyToStructure: {
 702 node->child1().setUseKind(CellUse);
 703 if (node->child2())
 704 node->child2().setUseKind(Int32Use);
 705 break;
 706 }
 707
 708 case GetByOffset: {
 709 if (!node->child1()->hasStorageResult())
 710 node->child1().setUseKind(KnownCellUse);
 711 break;
 712 }
 713
 714 case PutByOffset: {
 715 if (!node->child1()->hasStorageResult())
 716 node->child1().setUseKind(KnownCellUse);
 717 node->child2().setUseKind(KnownCellUse);
 718 break;
 719 }
 720
 721 case InstanceOf: {
 722 // FIXME: This appears broken: CheckHasInstance already does an unconditional cell
 723 // check. https://bugs.webkit.org/show_bug.cgi?id=107479
 724 if (!(node->child1()->prediction() & ~SpecCell))
 725 node->child1().setUseKind(CellUse);
 726 node->child2().setUseKind(CellUse);
402727 break;
403728 }
404729
 730 case GetArrayLength:
 731 case Identity:
 732 case Nop:
 733 case Phi:
 734 case ForwardInt32ToDouble:
 735 case PhantomPutStructure:
 736 case GetIndexedPropertyStorage:
 737 case LastNodeType:
 738 RELEASE_ASSERT_NOT_REACHED();
 739 break;
 740
 741#if !ASSERT_DISABLED
 742 // Have these no-op cases here to ensure that nobody forgets to add handlers for new opcodes.
 743 case SetArgument:
 744 case Phantom:
 745 case JSConstant:
 746 case WeakJSConstant:
 747 case GetLocal:
 748 case GetCallee:
 749 case Flush:
 750 case PhantomLocal:
 751 case GetLocalUnlinked:
 752 case InlineStart:
 753 case GetMyScope:
 754 case GetScopedVar:
 755 case GetGlobalVar:
 756 case PutGlobalVar:
 757 case GlobalVarWatchpoint:
 758 case PutGlobalVarCheck:
 759 case AllocationProfileWatchpoint:
 760 case Call:
 761 case Construct:
 762 case NewObject:
 763 case NewArrayBuffer:
 764 case NewRegexp:
 765 case Resolve:
 766 case ResolveBase:
 767 case ResolveBaseStrictPut:
 768 case ResolveGlobal:
 769 case Breakpoint:
 770 case IsUndefined:
 771 case IsBoolean:
 772 case IsNumber:
 773 case IsString:
 774 case IsObject:
 775 case IsFunction:
 776 case StrCat:
 777 case CreateActivation:
 778 case TearOffActivation:
 779 case CreateArguments:
 780 case PhantomArguments:
 781 case TearOffArguments:
 782 case GetMyArgumentsLength:
 783 case GetMyArgumentsLengthSafe:
 784 case CheckArgumentsNotCreated:
 785 case NewFunction:
 786 case NewFunctionNoCheck:
 787 case NewFunctionExpression:
 788 case Jump:
 789 case Return:
 790 case Throw:
 791 case ThrowReferenceError:
 792 case GarbageValue:
 793 case CountExecution:
 794 case ForceOSRExit:
 795 break;
 796#else
405797 default:
406798 break;
 799#endif
407800 }
408801
409802#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)

@@private:
421814
422815 Structure* structure = arrayMode.originalArrayStructure(m_graph, codeOrigin);
423816
 817 Edge indexEdge = index ? Edge(index, Int32Use) : Edge();
 818
424819 if (arrayMode.doesConversion()) {
425820 if (structure) {
426821 if (m_indexInBlock > 0) {

@@private:
435830
436831 m_insertionSet.insertNode(
437832 m_indexInBlock, RefChildren, DontRefNode, SpecNone, ArrayifyToStructure, codeOrigin,
438  OpInfo(structure), OpInfo(arrayMode.asWord()), array, index);
 833 OpInfo(structure), OpInfo(arrayMode.asWord()), Edge(array, CellUse), indexEdge);
439834 } else {
440835 m_insertionSet.insertNode(
441836 m_indexInBlock, RefChildren, DontRefNode, SpecNone, Arrayify, codeOrigin,
442  OpInfo(arrayMode.asWord()), array, index);
 837 OpInfo(arrayMode.asWord()), Edge(array, CellUse), indexEdge);
443838 }
444839 } else {
445840 if (structure) {
446841 m_insertionSet.insertNode(
447842 m_indexInBlock, RefChildren, DontRefNode, SpecNone, CheckStructure, codeOrigin,
448  OpInfo(m_graph.addStructureSet(structure)), array);
 843 OpInfo(m_graph.addStructureSet(structure)), Edge(array, CellUse));
449844 } else {
450845 m_insertionSet.insertNode(
451846 m_indexInBlock, RefChildren, DontRefNode, SpecNone, CheckArray, codeOrigin,
452  OpInfo(arrayMode.asWord()), array);
 847 OpInfo(arrayMode.asWord()), Edge(array, CellUse));
453848 }
454849 }
455850

@@private:
461856 m_indexInBlock,
462857 shouldGenerate ? RefChildren : DontRefChildren,
463858 shouldGenerate ? RefNode : DontRefNode,
464  SpecNone, GetButterfly, codeOrigin, array);
 859 SpecNone, GetButterfly, codeOrigin, Edge(array, KnownCellUse));
465860 }
466861
467862 return m_insertionSet.insertNode(
468863 m_indexInBlock,
469864 shouldGenerate ? RefChildren : DontRefChildren,
470865 shouldGenerate ? RefNode : DontRefNode,
471  SpecNone, GetIndexedPropertyStorage, codeOrigin, OpInfo(arrayMode.asWord()), array);
 866 SpecNone, GetIndexedPropertyStorage, codeOrigin, OpInfo(arrayMode.asWord()), Edge(array, KnownCellUse));
472867 }
473868
474  void blessArrayOperation(Edge base, Edge index, unsigned storageChildIdx)
 869 void blessArrayOperation(Edge base, Edge index, Edge& storageChild)
475870 {
476  if (m_graph.m_fixpointState > BeforeFixpoint)
477  return;
478 
479871 Node* node = m_currentNode;
480872
481873 switch (node->arrayMode().type()) {

@@private:
499891 if (!storage)
500892 return;
501893
502  m_graph.child(node, storageChildIdx) = Edge(storage);
 894 storageChild = Edge(storage);
503895 return;
504896 } }
505897 }

@@private:
507899 void fixIntEdge(Edge& edge)
508900 {
509901 Node* node = edge.node();
510  if (node->op() != ValueToInt32)
511  return;
512 
513  if (!node->child1()->shouldSpeculateInteger())
 902 if (node->op() != ValueToInt32) {
 903 edge.setUseKind(KnownInt32Use);
514904 return;
 905 }
515906
516907 Edge oldEdge = edge;
517908 Edge newEdge = node->child1();
518909
 910 if (newEdge.useKind() != Int32Use) {
 911 edge.setUseKind(KnownInt32Use);
 912 return;
 913 }
 914
 915 ASSERT(newEdge->shouldSpeculateInteger());
 916
519917 m_graph.ref(newEdge);
520918 m_graph.deref(oldEdge);
521919
522920 edge = newEdge;
523921 }
524922
525  void fixDoubleEdge(unsigned childIndex, SpeculationDirection direction = BackwardSpeculation)
 923 void fixDoubleEdge(Edge& edge, UseKind useKind = NumberUse, SpeculationDirection direction = BackwardSpeculation)
526924 {
527  Node* source = m_currentNode;
528  Edge& edge = m_graph.child(source, childIndex);
529 
530925 if (edge->prediction() & SpecDouble) {
531  edge.setUseKind(DoubleUse);
 926 edge.setUseKind(useKind);
532927 return;
533928 }
534929
535  injectInt32ToDoubleNode(childIndex, direction);
 930 injectInt32ToDoubleNode(edge, useKind, direction);
536931 }
537932
538  void injectInt32ToDoubleNode(unsigned childIndex, SpeculationDirection direction = BackwardSpeculation)
 933 void injectInt32ToDoubleNode(Edge& edge, UseKind useKind = NumberUse, SpeculationDirection direction = BackwardSpeculation)
539934 {
540935 Node* result = m_insertionSet.insertNode(
541936 m_indexInBlock, DontRefChildren, RefNode, SpecDouble,
542937 direction == BackwardSpeculation ? Int32ToDouble : ForwardInt32ToDouble,
543  m_currentNode->codeOrigin, m_graph.child(m_currentNode, childIndex).node());
 938 m_currentNode->codeOrigin, Edge(edge.node(), NumberUse));
544939
545940#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
546941 dataLogF(
547942 "(replacing @%u->@%u with @%u->@%u) ",
548  m_currentNode->index(), m_graph.child(m_currentNode, childIndex)->index(), m_currentNode->index(), result->index());
 943 m_currentNode->index(), edge->index(), m_currentNode->index(), result->index());
549944#endif
550945
551  m_graph.child(m_currentNode, childIndex) = Edge(result, DoubleUse);
 946 edge = Edge(result, useKind);
 947 }
 948
 949 void truncateConstantToInt32(Edge& edge)
 950 {
 951 Node* oldNode = edge.node();
 952
 953 ASSERT(oldNode->hasConstant());
 954 JSValue value = m_graph.valueOfJSConstant(oldNode);
 955 if (value.isInt32())
 956 return;
 957
 958 value = jsNumber(JSC::toInt32(value.asNumber()));
 959 ASSERT(value.isInt32());
 960 edge.setNode(m_insertionSet.insertNode(
 961 m_indexInBlock, DontRefChildren, RefNode, SpecInt32, JSConstant,
 962 m_currentNode->codeOrigin, OpInfo(codeBlock()->addOrFindConstant(value))));
 963 m_graph.deref(oldNode);
 964 }
 965
 966 void truncateConstantsIfNecessary(Node* node, AddSpeculationMode mode)
 967 {
 968 if (mode != SpeculateIntegerAndTruncateConstants)
 969 return;
 970
 971 ASSERT(node->child1()->hasConstant() || node->child2()->hasConstant());
 972 if (node->child1()->hasConstant())
 973 truncateConstantToInt32(node->child1());
 974 else
 975 truncateConstantToInt32(node->child2());
 976 }
 977
 978 bool attemptToMakeIntegerAdd(Node* node)
 979 {
 980 AddSpeculationMode mode = m_graph.addSpeculationMode(node);
 981 if (mode == DontSpeculateInteger)
 982 return false;
 983
 984 truncateConstantsIfNecessary(node, mode);
 985 node->child1().setUseKind(Int32Use);
 986 node->child2().setUseKind(Int32Use);
 987 return true;
552988 }
553989
554990 BasicBlock* m_block;
143562

Source/JavaScriptCore/dfg/DFGGraph.cpp

@@void Graph::dump(PrintStream& out)
346346 }
347347}
348348
349 // FIXME: Convert this to be iterative, not recursive.
350 #define DO_TO_CHILDREN(node, thingToDo) do { \
351  Node* _node = (node); \
352  if (_node->flags() & NodeHasVarArgs) { \
353  for (unsigned _childIdx = _node->firstChild(); \
354  _childIdx < _node->firstChild() + _node->numChildren(); \
355  _childIdx++) { \
356  if (!!m_varArgChildren[_childIdx]) \
357  thingToDo(m_varArgChildren[_childIdx]); \
358  } \
359  } else { \
360  if (!_node->child1()) { \
361  ASSERT( \
362  !_node->child2() \
363  && !_node->child3()); \
364  break; \
365  } \
366  thingToDo(_node->child1()); \
367  \
368  if (!_node->child2()) { \
369  ASSERT(!_node->child3()); \
370  break; \
371  } \
372  thingToDo(_node->child2()); \
373  \
374  if (!_node->child3()) \
375  break; \
376  thingToDo(_node->child3()); \
377  } \
378  } while (false)
379 
380349void Graph::refChildren(Node* op)
381350{
382  DO_TO_CHILDREN(op, ref);
 351 DFG_NODE_DO_TO_CHILDREN(*this, op, ref);
383352}
384353
385354void Graph::derefChildren(Node* op)
386355{
387  DO_TO_CHILDREN(op, deref);
 356 DFG_NODE_DO_TO_CHILDREN(*this, op, deref);
388357}
389358
390359void Graph::dethread()
143562

Source/JavaScriptCore/dfg/DFGGraph.h

@@struct PutToBaseOperationData {
7777
7878enum AddSpeculationMode {
7979 DontSpeculateInteger,
80  SpeculateIntegerButAlwaysWatchOverflow,
 80 SpeculateIntegerAndTruncateConstants,
8181 SpeculateInteger
8282};
8383

@@public:
100100 refChildren(node);
101101 return node;
102102 }
103  Edge ref(Edge nodeUse)
 103 Edge ref(Edge edge)
104104 {
105  ref(nodeUse.node());
106  return nodeUse;
 105 ref(edge.node());
 106 return edge;
 107 }
 108 Edge ref(Node*, Edge edge)
 109 {
 110 return ref(edge);
107111 }
108112
109113 void deref(Node* node)

@@public:
115119 if (node->postfixDeref() == 1)
116120 derefChildren(node);
117121 }
118  void deref(Edge nodeUse)
 122 void deref(Edge edge)
119123 {
120  deref(nodeUse.node());
 124 deref(edge.node());
 125 }
 126 void deref(Node*, Edge edge)
 127 {
 128 deref(edge);
121129 }
122130
123131 // When a node's refCount goes from 0 to 1, it must (logically) recursively ref all of its children, and vice versa.

@@public:
174182 for (unsigned childIdx = node->firstChild(); childIdx < node->firstChild() + node->numChildren(); childIdx++)
175183 performSubstitutionForEdge(m_varArgChildren[childIdx], shouldGenerate);
176184 } else {
177  performSubstitutionForEdge(node->children.child1(), shouldGenerate);
178  performSubstitutionForEdge(node->children.child2(), shouldGenerate);
179  performSubstitutionForEdge(node->children.child3(), shouldGenerate);
 185 performSubstitutionForEdge(node->child1(), shouldGenerate);
 186 performSubstitutionForEdge(node->child2(), shouldGenerate);
 187 performSubstitutionForEdge(node->child3(), shouldGenerate);
180188 }
181189 }
182190

@@public:
530538
531539 bool isPredictedNumerical(Node* node)
532540 {
533  SpeculatedType left = node->child1()->prediction();
534  SpeculatedType right = node->child2()->prediction();
535  return isNumberSpeculation(left) && isNumberSpeculation(right);
 541 return isNumerical(node->child1().useKind()) && isNumerical(node->child2().useKind());
536542 }
537543
538544 // Note that a 'true' return does not actually mean that the ByVal access clobbers nothing.

@@private:
781787 if (doubleImmediate < -twoToThe48 || doubleImmediate > twoToThe48)
782788 return DontSpeculateInteger;
783789
784  return nodeCanTruncateInteger(add->arithNodeFlags()) ? SpeculateIntegerButAlwaysWatchOverflow : DontSpeculateInteger;
 790 return nodeCanTruncateInteger(add->arithNodeFlags()) ? SpeculateIntegerAndTruncateConstants : DontSpeculateInteger;
785791 }
786792
787793 bool mulImmediateShouldSpeculateInteger(Node* mul, Node* variable, Node* immediate)

@@inline BlockIndex Graph::blockIndexForBy
830836 return *binarySearch<BlockIndex, unsigned>(linkingTargets, linkingTargets.size(), bytecodeBegin, GetBytecodeBeginForBlock(*this));
831837}
832838
 839#define DFG_NODE_DO_TO_CHILDREN(graph, node, thingToDo) do { \
 840 Node* _node = (node); \
 841 if (_node->flags() & NodeHasVarArgs) { \
 842 for (unsigned _childIdx = _node->firstChild(); \
 843 _childIdx < _node->firstChild() + _node->numChildren(); \
 844 _childIdx++) { \
 845 if (!!(graph).m_varArgChildren[_childIdx]) \
 846 thingToDo(_node, (graph).m_varArgChildren[_childIdx]); \
 847 } \
 848 } else { \
 849 if (!_node->child1()) { \
 850 ASSERT( \
 851 !_node->child2() \
 852 && !_node->child3()); \
 853 break; \
 854 } \
 855 thingToDo(_node, _node->child1()); \
 856 \
 857 if (!_node->child2()) { \
 858 ASSERT(!_node->child3()); \
 859 break; \
 860 } \
 861 thingToDo(_node, _node->child2()); \
 862 \
 863 if (!_node->child3()) \
 864 break; \
 865 thingToDo(_node, _node->child3()); \
 866 } \
 867 } while (false)
 868
833869} } // namespace JSC::DFG
834870
835871#endif
143562

Source/JavaScriptCore/dfg/DFGNode.h

@@struct Node {
9595 , m_prediction(SpecNone)
9696 {
9797 setOpAndDefaultFlags(op);
98  ASSERT(!!(m_flags & NodeHasVarArgs) == (children.kind() == AdjacencyList::Variable));
9998 }
10099
101100 // Construct a node with up to 3 children, no immediate value.
102  Node(NodeType op, CodeOrigin codeOrigin, Node* child1 = 0, Node* child2 = 0, Node* child3 = 0)
 101 Node(NodeType op, CodeOrigin codeOrigin, Edge child1 = Edge(), Edge child2 = Edge(), Edge child3 = Edge())
103102 : codeOrigin(codeOrigin)
104103 , children(AdjacencyList::Fixed, child1, child2, child3)
105104 , m_virtualRegister(InvalidVirtualRegister)

@@struct Node {
111110 }
112111
113112 // Construct a node with up to 3 children and an immediate value.
114  Node(NodeType op, CodeOrigin codeOrigin, OpInfo imm, Node* child1 = 0, Node* child2 = 0, Node* child3 = 0)
 113 Node(NodeType op, CodeOrigin codeOrigin, OpInfo imm, Edge child1 = Edge(), Edge child2 = Edge(), Edge child3 = Edge())
115114 : codeOrigin(codeOrigin)
116115 , children(AdjacencyList::Fixed, child1, child2, child3)
117116 , m_virtualRegister(InvalidVirtualRegister)

@@struct Node {
124123 }
125124
126125 // Construct a node with up to 3 children and two immediate values.
127  Node(NodeType op, CodeOrigin codeOrigin, OpInfo imm1, OpInfo imm2, Node* child1 = 0, Node* child2 = 0, Node* child3 = 0)
 126 Node(NodeType op, CodeOrigin codeOrigin, OpInfo imm1, OpInfo imm2, Edge child1 = Edge(), Edge child2 = Edge(), Edge child3 = Edge())
128127 : codeOrigin(codeOrigin)
129128 , children(AdjacencyList::Fixed, child1, child2, child3)
130129 , m_virtualRegister(InvalidVirtualRegister)

@@struct Node {
294293 convertToStructureTransitionWatchpoint(structureSet().singletonStructure());
295294 }
296295
297  void convertToGetByOffset(unsigned storageAccessDataIndex, Node* storage)
 296 void convertToGetByOffset(unsigned storageAccessDataIndex, Edge storage)
298297 {
299298 ASSERT(m_op == GetById || m_op == GetByIdFlush);
300299 m_opInfo = storageAccessDataIndex;
301  children.setChild1(Edge(storage));
 300 children.setChild1(storage);
302301 m_op = GetByOffset;
303302 m_flags &= ~NodeClobbersWorld;
304303 }
305304
306  void convertToPutByOffset(unsigned storageAccessDataIndex, Node* storage)
 305 void convertToPutByOffset(unsigned storageAccessDataIndex, Edge storage)
307306 {
308307 ASSERT(m_op == PutById || m_op == PutByIdDirect);
309308 m_opInfo = storageAccessDataIndex;
310309 children.setChild3(children.child2());
311310 children.setChild2(children.child1());
312  children.setChild1(Edge(storage));
 311 children.setChild1(storage);
313312 m_op = PutByOffset;
314313 m_flags &= ~NodeClobbersWorld;
315314 }

@@struct Node {
949948 case DoubleAsInt32:
950949 case PhantomArguments:
951950 return true;
952  case Phantom:
953951 case Nop:
954952 return false;
 953 case Phantom:
 954 return child1().useKindUnchecked() != UntypedUse || child2().useKindUnchecked() != UntypedUse || child3().useKindUnchecked() != UntypedUse;
955955 default:
956956 return shouldGenerate();
957957 }

@@struct Node {
995995 return m_refCount--;
996996 }
997997
998  Edge child1()
 998 Edge& child1()
999999 {
10001000 ASSERT(!(m_flags & NodeHasVarArgs));
10011001 return children.child1();

@@struct Node {
10091009 return children.child1Unchecked();
10101010 }
10111011
1012  Edge child2()
 1012 Edge& child2()
10131013 {
10141014 ASSERT(!(m_flags & NodeHasVarArgs));
10151015 return children.child2();
10161016 }
10171017
1018  Edge child3()
 1018 Edge& child3()
10191019 {
10201020 ASSERT(!(m_flags & NodeHasVarArgs));
10211021 return children.child3();

@@struct Node {
10331033 return children.numChildren();
10341034 }
10351035
 1036 UseKind binaryUseKind()
 1037 {
 1038 ASSERT(child1().useKind() == child2().useKind());
 1039 return child1().useKind();
 1040 }
 1041
 1042 bool isBinaryUseKind(UseKind useKind)
 1043 {
 1044 return child1().useKind() == useKind && child2().useKind() == useKind;
 1045 }
 1046
10361047 SpeculatedType prediction()
10371048 {
10381049 return m_prediction;
143562

Source/JavaScriptCore/dfg/DFGNodeAllocator.h

3535
3636namespace JSC { namespace DFG {
3737
38 typedef Allocator<Node> NodeAllocator;
 38#if USE(JSVALUE64)
 39typedef Allocator<Node, 112> NodeAllocator;
 40#else
 41typedef Allocator<Node, 80> NodeAllocator;
 42#endif
3943
4044} } // namespace JSC::DFG
4145
143562

Source/JavaScriptCore/dfg/DFGNodeFlags.cpp

@@namespace JSC { namespace DFG {
3434
3535const char* nodeFlagsAsString(NodeFlags flags)
3636{
37  if (!flags)
 37 if (!(flags ^ NodeDoesNotExit))
3838 return "<empty>";
3939
4040 static const int size = 128;
143562

Source/JavaScriptCore/dfg/DFGNodeType.h

@@namespace JSC { namespace DFG {
9696 macro(ForwardInt32ToDouble, NodeResultNumber) \
9797 /* Used to speculate that a double value is actually an integer. */\
9898 macro(DoubleAsInt32, NodeResultInt32) \
99  /* Used to record places where we must check if a value is a number. */\
100  macro(CheckNumber, NodeMustGenerate) \
10199 \
102100 /* Nodes for arithmetic operations. */\
103101 macro(ArithAdd, NodeResultNumber | NodeMustGenerate) \
143562

Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

@@private:
805805 case PutStructure:
806806 case TearOffActivation:
807807 case TearOffArguments:
808  case CheckNumber:
809808 case CheckArgumentsNotCreated:
810809 case GlobalVarWatchpoint:
811810 case GarbageValue:
143562

Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

@@namespace JSC { namespace DFG {
4040
4141#if USE(JSVALUE32_64)
4242
43 GPRReg SpeculativeJIT::fillInteger(Node* node, DataFormat& returnFormat)
 43GPRReg SpeculativeJIT::fillInteger(Edge edge, DataFormat& returnFormat)
4444{
45  VirtualRegister virtualRegister = node->virtualRegister();
 45 ASSERT(!needsTypeCheck(edge, SpecInt32));
 46
 47 VirtualRegister virtualRegister = edge->virtualRegister();
4648 GenerationInfo& info = m_generationInfo[virtualRegister];
4749
4850 if (info.registerFormat() == DataFormatNone) {
4951 GPRReg gpr = allocate();
5052
51  if (node->hasConstant()) {
 53 if (edge->hasConstant()) {
5254 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
53  if (isInt32Constant(node))
54  m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(node)), gpr);
55  else if (isNumberConstant(node))
 55 if (isInt32Constant(edge.node()))
 56 m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(edge.node())), gpr);
 57 else if (isNumberConstant(edge.node()))
5658 RELEASE_ASSERT_NOT_REACHED();
5759 else {
58  ASSERT(isJSConstant(node));
59  JSValue jsValue = valueOfJSConstant(node);
 60 ASSERT(isJSConstant(edge.node()));
 61 JSValue jsValue = valueOfJSConstant(edge.node());
6062 m_jit.move(MacroAssembler::Imm32(jsValue.payload()), gpr);
6163 }
6264 } else {

@@GPRReg SpeculativeJIT::fillInteger(Node*
113115 }
114116}
115117
116 bool SpeculativeJIT::fillJSValue(Node* node, GPRReg& tagGPR, GPRReg& payloadGPR, FPRReg& fpr)
 118bool SpeculativeJIT::fillJSValue(Edge edge, GPRReg& tagGPR, GPRReg& payloadGPR, FPRReg& fpr)
117119{
118120 // FIXME: For double we could fill with a FPR.
119121 UNUSED_PARAM(fpr);
120122
121  VirtualRegister virtualRegister = node->virtualRegister();
 123 VirtualRegister virtualRegister = edge->virtualRegister();
122124 GenerationInfo& info = m_generationInfo[virtualRegister];
123125
124126 switch (info.registerFormat()) {
125127 case DataFormatNone: {
126128
127  if (node->hasConstant()) {
 129 if (edge->hasConstant()) {
128130 tagGPR = allocate();
129131 payloadGPR = allocate();
130  m_jit.move(Imm32(valueOfJSConstant(node).tag()), tagGPR);
131  m_jit.move(Imm32(valueOfJSConstant(node).payload()), payloadGPR);
 132 m_jit.move(Imm32(valueOfJSConstant(edge.node()).tag()), tagGPR);
 133 m_jit.move(Imm32(valueOfJSConstant(edge.node()).payload()), payloadGPR);
132134 m_gprs.retain(tagGPR, virtualRegister, SpillOrderConstant);
133135 m_gprs.retain(payloadGPR, virtualRegister, SpillOrderConstant);
134  info.fillJSValue(*m_stream, tagGPR, payloadGPR, isInt32Constant(node) ? DataFormatJSInteger : DataFormatJS);
 136 info.fillJSValue(*m_stream, tagGPR, payloadGPR, isInt32Constant(edge.node()) ? DataFormatJSInteger : DataFormatJS);
135137 } else {
136138 DataFormat spillFormat = info.spillFormat();
137139 ASSERT(spillFormat != DataFormatNone && spillFormat != DataFormatStorage);

@@void SpeculativeJIT::emitCall(Node* node
844846}
845847
846848template<bool strict>
847 GPRReg SpeculativeJIT::fillSpeculateIntInternal(Node* node, DataFormat& returnFormat, SpeculationDirection direction)
 849GPRReg SpeculativeJIT::fillSpeculateIntInternal(Edge edge, DataFormat& returnFormat, SpeculationDirection direction)
848850{
849851#if DFG_ENABLE(DEBUG_VERBOSE)
850  dataLogF("SpecInt@%d ", node->index());
 852 dataLogF("SpecInt@%d ", edge->index());
851853#endif
852  SpeculatedType type = m_state.forNode(node).m_type;
853  VirtualRegister virtualRegister = node->virtualRegister();
 854 AbstractValue& value = m_state.forNode(edge);
 855 SpeculatedType type = value.m_type;
 856 ASSERT(edge.useKind() != KnownInt32Use || !(value.m_type & ~SpecInt32));
 857 value.filter(SpecInt32);
 858 VirtualRegister virtualRegister = edge->virtualRegister();
854859 GenerationInfo& info = m_generationInfo[virtualRegister];
855860
856861 switch (info.registerFormat()) {
857862 case DataFormatNone: {
858  if ((node->hasConstant() && !isInt32Constant(node)) || info.spillFormat() == DataFormatDouble) {
 863 if ((edge->hasConstant() && !isInt32Constant(edge.node())) || info.spillFormat() == DataFormatDouble) {
859864 terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0, direction);
860865 returnFormat = DataFormatInteger;
861866 return allocate();
862867 }
863868
864  if (node->hasConstant()) {
865  ASSERT(isInt32Constant(node));
 869 if (edge->hasConstant()) {
 870 ASSERT(isInt32Constant(edge.node()));
866871 GPRReg gpr = allocate();
867  m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(node)), gpr);
 872 m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(edge.node())), gpr);
868873 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
869874 info.fillInteger(*m_stream, gpr);
870875 returnFormat = DataFormatInteger;

@@GPRReg SpeculativeJIT::fillSpeculateIntI
875880 ASSERT_UNUSED(spillFormat, (spillFormat & DataFormatJS) || spillFormat == DataFormatInteger);
876881
877882 // If we know this was spilled as an integer we can fill without checking.
878  if (!isInt32Speculation(type))
879  speculationCheck(BadType, JSValueSource(JITCompiler::addressFor(virtualRegister)), node, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::Int32Tag)), direction);
 883 if (type & ~SpecInt32)
 884 speculationCheck(BadType, JSValueSource(JITCompiler::addressFor(virtualRegister)), edge, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::Int32Tag)), direction);
880885
881886 GPRReg gpr = allocate();
882887 m_jit.load32(JITCompiler::payloadFor(virtualRegister), gpr);

@@GPRReg SpeculativeJIT::fillSpeculateIntI
893898 GPRReg payloadGPR = info.payloadGPR();
894899 m_gprs.lock(tagGPR);
895900 m_gprs.lock(payloadGPR);
896  if (!isInt32Speculation(type))
897  speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), node, m_jit.branch32(MacroAssembler::NotEqual, tagGPR, TrustedImm32(JSValue::Int32Tag)), direction);
 901 if (type & ~SpecInt32)
 902 speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), edge, m_jit.branch32(MacroAssembler::NotEqual, tagGPR, TrustedImm32(JSValue::Int32Tag)), direction);
898903 m_gprs.unlock(tagGPR);
899904 m_gprs.release(tagGPR);
900905 m_gprs.release(payloadGPR);

@@GPRReg SpeculativeJIT::fillSpeculateIntI
929934 }
930935}
931936
932 GPRReg SpeculativeJIT::fillSpeculateInt(Node* node, DataFormat& returnFormat, SpeculationDirection direction)
 937GPRReg SpeculativeJIT::fillSpeculateInt(Edge edge, DataFormat& returnFormat, SpeculationDirection direction)
933938{
934  return fillSpeculateIntInternal<false>(node, returnFormat, direction);
 939 return fillSpeculateIntInternal<false>(edge, returnFormat, direction);
935940}
936941
937 GPRReg SpeculativeJIT::fillSpeculateIntStrict(Node* node)
 942GPRReg SpeculativeJIT::fillSpeculateIntStrict(Edge edge)
938943{
939944 DataFormat mustBeDataFormatInteger;
940  GPRReg result = fillSpeculateIntInternal<true>(node, mustBeDataFormatInteger, BackwardSpeculation);
 945 GPRReg result = fillSpeculateIntInternal<true>(edge, mustBeDataFormatInteger, BackwardSpeculation);
941946 ASSERT(mustBeDataFormatInteger == DataFormatInteger);
942947 return result;
943948}
944949
945 FPRReg SpeculativeJIT::fillSpeculateDouble(Node* node, SpeculationDirection direction)
 950FPRReg SpeculativeJIT::fillSpeculateDouble(Edge edge, SpeculationDirection direction)
946951{
947952#if DFG_ENABLE(DEBUG_VERBOSE)
948  dataLogF("SpecDouble@%d ", node->index());
 953 dataLogF("SpecDouble@%d ", edge->index());
949954#endif
950  SpeculatedType type = m_state.forNode(node).m_type;
951  VirtualRegister virtualRegister = node->virtualRegister();
 955 AbstractValue& value = m_state.forNode(edge);
 956 SpeculatedType type = value.m_type;
 957 ASSERT(edge.useKind() != KnownNumberUse || !(value.m_type & ~SpecNumber));
 958 value.filter(SpecNumber);
 959 VirtualRegister virtualRegister = edge->virtualRegister();
952960 GenerationInfo& info = m_generationInfo[virtualRegister];
953961
954962 if (info.registerFormat() == DataFormatNone) {
955963
956  if (node->hasConstant()) {
957  if (isInt32Constant(node)) {
 964 if (edge->hasConstant()) {
 965 if (isInt32Constant(edge.node())) {
958966 GPRReg gpr = allocate();
959  m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(node)), gpr);
 967 m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(edge.node())), gpr);
960968 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
961969 info.fillInteger(*m_stream, gpr);
962970 unlock(gpr);
963  } else if (isNumberConstant(node)) {
 971 } else if (isNumberConstant(edge.node())) {
964972 FPRReg fpr = fprAllocate();
965  m_jit.loadDouble(addressOfDoubleConstant(node), fpr);
 973 m_jit.loadDouble(addressOfDoubleConstant(edge.node()), fpr);
966974 m_fprs.retain(fpr, virtualRegister, SpillOrderConstant);
967975 info.fillDouble(*m_stream, fpr);
968976 return fpr;

@@FPRReg SpeculativeJIT::fillSpeculateDoub
986994
987995 if (spillFormat != DataFormatJSInteger && spillFormat != DataFormatInteger) {
988996 JITCompiler::Jump isInteger = m_jit.branch32(MacroAssembler::Equal, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::Int32Tag));
989  if (!isNumberSpeculation(type))
990  speculationCheck(BadType, JSValueSource(JITCompiler::addressFor(virtualRegister)), node, m_jit.branch32(MacroAssembler::AboveOrEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::LowestTag)), direction);
 997 if (type & ~SpecNumber)
 998 speculationCheck(BadType, JSValueSource(JITCompiler::addressFor(virtualRegister)), edge, m_jit.branch32(MacroAssembler::AboveOrEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::LowestTag)), direction);
991999 m_jit.loadDouble(JITCompiler::addressFor(virtualRegister), fpr);
9921000 hasUnboxedDouble = m_jit.jump();
9931001

@@FPRReg SpeculativeJIT::fillSpeculateDoub
10211029 if (info.registerFormat() != DataFormatJSInteger) {
10221030 FPRTemporary scratch(this);
10231031 JITCompiler::Jump isInteger = m_jit.branch32(MacroAssembler::Equal, tagGPR, TrustedImm32(JSValue::Int32Tag));
1024  if (!isNumberSpeculation(type))
1025  speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), node, m_jit.branch32(MacroAssembler::AboveOrEqual, tagGPR, TrustedImm32(JSValue::LowestTag)), direction);
 1032 if (type & ~SpecNumber)
 1033 speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), edge, m_jit.branch32(MacroAssembler::AboveOrEqual, tagGPR, TrustedImm32(JSValue::LowestTag)), direction);
10261034 unboxDouble(tagGPR, payloadGPR, fpr, scratch.fpr());
10271035 hasUnboxedDouble = m_jit.jump();
10281036 isInteger.link(&m_jit);

@@FPRReg SpeculativeJIT::fillSpeculateDoub
10761084 }
10771085}
10781086
1079 GPRReg SpeculativeJIT::fillSpeculateCell(Node* node, SpeculationDirection direction)
 1087GPRReg SpeculativeJIT::fillSpeculateCell(Edge edge, SpeculationDirection direction)
10801088{
10811089#if DFG_ENABLE(DEBUG_VERBOSE)
1082  dataLogF("SpecCell@%d ", node->index());
 1090 dataLogF("SpecCell@%d ", edge->index());
10831091#endif
1084  SpeculatedType type = m_state.forNode(node).m_type;
1085  VirtualRegister virtualRegister = node->virtualRegister();
 1092 AbstractValue& value = m_state.forNode(edge);
 1093 SpeculatedType type = value.m_type;
 1094 ASSERT(edge.useKind() != KnownCellUse || !(value.m_type & ~SpecCell));
 1095 value.filter(SpecCell);
 1096 VirtualRegister virtualRegister = edge->virtualRegister();
10861097 GenerationInfo& info = m_generationInfo[virtualRegister];
10871098
10881099 switch (info.registerFormat()) {
10891100 case DataFormatNone: {
10901101
1091  if (node->hasConstant()) {
1092  JSValue jsValue = valueOfJSConstant(node);
 1102 if (edge->hasConstant()) {
 1103 JSValue jsValue = valueOfJSConstant(edge.node());
10931104 GPRReg gpr = allocate();
10941105 if (jsValue.isCell()) {
10951106 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);

@@GPRReg SpeculativeJIT::fillSpeculateCell
11021113 }
11031114
11041115 ASSERT((info.spillFormat() & DataFormatJS) || info.spillFormat() == DataFormatCell);
1105  if (!isCellSpeculation(type))
1106  speculationCheck(BadType, JSValueSource(JITCompiler::addressFor(virtualRegister)), node, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::CellTag)), direction);
 1116 if (type & ~SpecCell)
 1117 speculationCheck(BadType, JSValueSource(JITCompiler::addressFor(virtualRegister)), edge, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::CellTag)), direction);
11071118 GPRReg gpr = allocate();
11081119 m_jit.load32(JITCompiler::payloadFor(virtualRegister), gpr);
11091120 m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);

@@GPRReg SpeculativeJIT::fillSpeculateCell
11231134 GPRReg payloadGPR = info.payloadGPR();
11241135 m_gprs.lock(tagGPR);
11251136 m_gprs.lock(payloadGPR);
1126  if (!isCellSpeculation(type))
1127  speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), node, m_jit.branch32(MacroAssembler::NotEqual, tagGPR, TrustedImm32(JSValue::CellTag)), direction);
 1137 if (type & ~SpecCell)
 1138 speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), edge, m_jit.branch32(MacroAssembler::NotEqual, tagGPR, TrustedImm32(JSValue::CellTag)), direction);
11281139 m_gprs.unlock(tagGPR);
11291140 m_gprs.release(tagGPR);
11301141 m_gprs.release(payloadGPR);

@@GPRReg SpeculativeJIT::fillSpeculateCell
11511162 }
11521163}
11531164
1154 GPRReg SpeculativeJIT::fillSpeculateBoolean(Node* node, SpeculationDirection direction)
 1165GPRReg SpeculativeJIT::fillSpeculateBoolean(Edge edge, SpeculationDirection direction)
11551166{
11561167#if DFG_ENABLE(DEBUG_VERBOSE)
11571168 dataLogF("SpecBool@%d ", node->index());
11581169#endif
1159  SpeculatedType type = m_state.forNode(node).m_type;
1160  VirtualRegister virtualRegister = node->virtualRegister();
 1170 AbstractValue& value = m_state.forNode(edge);
 1171 SpeculatedType type = value.m_type;
 1172 value.filter(SpecBoolean);
 1173 VirtualRegister virtualRegister = edge->virtualRegister();
11611174 GenerationInfo& info = m_generationInfo[virtualRegister];
11621175
11631176 switch (info.registerFormat()) {

@@GPRReg SpeculativeJIT::fillSpeculateBool
11671180 return allocate();
11681181 }
11691182
1170  if (node->hasConstant()) {
1171  JSValue jsValue = valueOfJSConstant(node);
 1183 if (edge->hasConstant()) {
 1184 JSValue jsValue = valueOfJSConstant(edge.node());
11721185 GPRReg gpr = allocate();
11731186 if (jsValue.isBoolean()) {
11741187 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);

@@GPRReg SpeculativeJIT::fillSpeculateBool
11821195
11831196 ASSERT((info.spillFormat() & DataFormatJS) || info.spillFormat() == DataFormatBoolean);
11841197
1185  if (!isBooleanSpeculation(type))
1186  speculationCheck(BadType, JSValueSource(JITCompiler::addressFor(virtualRegister)), node, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::BooleanTag)), direction);
 1198 if (type & ~SpecBoolean)
 1199 speculationCheck(BadType, JSValueSource(JITCompiler::addressFor(virtualRegister)), edge, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::BooleanTag)), direction);
11871200
11881201 GPRReg gpr = allocate();
11891202 m_jit.load32(JITCompiler::payloadFor(virtualRegister), gpr);

@@GPRReg SpeculativeJIT::fillSpeculateBool
12041217 GPRReg payloadGPR = info.payloadGPR();
12051218 m_gprs.lock(tagGPR);
12061219 m_gprs.lock(payloadGPR);
1207  if (!isBooleanSpeculation(type))
1208  speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), node, m_jit.branch32(MacroAssembler::NotEqual, tagGPR, TrustedImm32(JSValue::BooleanTag)), direction);
 1220 if (type & ~SpecBoolean)
 1221 speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), edge, m_jit.branch32(MacroAssembler::NotEqual, tagGPR, TrustedImm32(JSValue::BooleanTag)), direction);
12091222
12101223 m_gprs.unlock(tagGPR);
12111224 m_gprs.release(tagGPR);

@@void SpeculativeJIT::compileObjectEquali
12591272 GPRReg op2GPR = op2.gpr();
12601273
12611274 if (m_jit.graph().globalObjectFor(node->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
1262  m_jit.graph().globalObjectFor(node->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
1263  if (m_state.forNode(node->child1()).m_type & ~SpecObject) {
1264  speculationCheck(
1265  BadType, JSValueSource::unboxedCell(op1GPR), node->child1(),
1266  m_jit.branchPtr(
1267  MacroAssembler::Equal,
1268  MacroAssembler::Address(op1GPR, JSCell::structureOffset()),
1269  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1270  }
1271  if (m_state.forNode(node->child2()).m_type & ~SpecObject) {
1272  speculationCheck(
1273  BadType, JSValueSource::unboxedCell(op2GPR), node->child2(),
1274  m_jit.branchPtr(
1275  MacroAssembler::Equal,
1276  MacroAssembler::Address(op2GPR, JSCell::structureOffset()),
1277  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1278  }
 1275 m_jit.graph().globalObjectFor(node->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
 1276 DFG_TYPE_CHECK(
 1277 JSValueSource::unboxedCell(op1GPR), node->child1(), SpecObject, m_jit.branchPtr(
 1278 MacroAssembler::Equal,
 1279 MacroAssembler::Address(op1GPR, JSCell::structureOffset()),
 1280 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
 1281 DFG_TYPE_CHECK(
 1282 JSValueSource::unboxedCell(op2GPR), node->child2(), SpecObject, m_jit.branchPtr(
 1283 MacroAssembler::Equal,
 1284 MacroAssembler::Address(op2GPR, JSCell::structureOffset()),
 1285 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
12791286 } else {
12801287 GPRTemporary structure(this);
12811288 GPRReg structureGPR = structure.gpr();
12821289
12831290 m_jit.loadPtr(MacroAssembler::Address(op1GPR, JSCell::structureOffset()), structureGPR);
1284  if (m_state.forNode(node->child1()).m_type & ~SpecObject) {
1285  speculationCheck(
1286  BadType, JSValueSource::unboxedCell(op1GPR), node->child1(),
1287  m_jit.branchPtr(
1288  MacroAssembler::Equal,
1289  structureGPR,
1290  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1291  }
 1291 DFG_TYPE_CHECK(
 1292 JSValueSource::unboxedCell(op1GPR), node->child1(), SpecObject, m_jit.branchPtr(
 1293 MacroAssembler::Equal,
 1294 structureGPR,
 1295 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
12921296 speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), node->child1(),
12931297 m_jit.branchTest8(
12941298 MacroAssembler::NonZero,

@@void SpeculativeJIT::compileObjectEquali
12961300 MacroAssembler::TrustedImm32(MasqueradesAsUndefined)));
12971301
12981302 m_jit.loadPtr(MacroAssembler::Address(op2GPR, JSCell::structureOffset()), structureGPR);
1299  if (m_state.forNode(node->child2()).m_type & ~SpecObject) {
1300  speculationCheck(
1301  BadType, JSValueSource::unboxedCell(op2GPR), node->child2(),
1302  m_jit.branchPtr(
1303  MacroAssembler::Equal,
1304  structureGPR,
1305  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1306  }
 1303 DFG_TYPE_CHECK(
 1304 JSValueSource::unboxedCell(op2GPR), node->child2(), SpecObject, m_jit.branchPtr(
 1305 MacroAssembler::Equal,
 1306 structureGPR,
 1307 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
13071308 speculationCheck(BadType, JSValueSource::unboxedCell(op2GPR), node->child2(),
13081309 m_jit.branchTest8(
13091310 MacroAssembler::NonZero,

@@void SpeculativeJIT::compileObjectEquali
13271328void SpeculativeJIT::compileObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild)
13281329{
13291330 SpeculateCellOperand op1(this, leftChild);
1330  JSValueOperand op2(this, rightChild);
 1331 JSValueOperand op2(this, rightChild, ManualOperandSpeculation);
13311332 GPRTemporary result(this);
13321333
13331334 GPRReg op1GPR = op1.gpr();

@@void SpeculativeJIT::compileObjectToObje
13371338
13381339 if (m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
13391340 m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
1340  if (m_state.forNode(leftChild).m_type & ~SpecObject) {
1341  speculationCheck(
1342  BadType, JSValueSource::unboxedCell(op1GPR), leftChild,
1343  m_jit.branchPtr(
1344  MacroAssembler::Equal,
1345  MacroAssembler::Address(op1GPR, JSCell::structureOffset()),
1346  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1347  }
 1341 DFG_TYPE_CHECK(
 1342 JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchPtr(
 1343 MacroAssembler::Equal,
 1344 MacroAssembler::Address(op1GPR, JSCell::structureOffset()),
 1345 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
13481346 } else {
13491347 GPRTemporary structure(this);
13501348 GPRReg structureGPR = structure.gpr();
13511349
13521350 m_jit.loadPtr(MacroAssembler::Address(op1GPR, JSCell::structureOffset()), structureGPR);
1353  if (m_state.forNode(leftChild).m_type & ~SpecObject) {
1354  speculationCheck(
1355  BadType, JSValueSource::unboxedCell(op1GPR), leftChild,
1356  m_jit.branchPtr(
1357  MacroAssembler::Equal,
1358  structureGPR,
1359  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1360  }
 1351 DFG_TYPE_CHECK(
 1352 JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchPtr(
 1353 MacroAssembler::Equal,
 1354 structureGPR,
 1355 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
13611356 speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), leftChild,
13621357 m_jit.branchTest8(
13631358 MacroAssembler::NonZero,

@@void SpeculativeJIT::compileObjectToObje
13741369 // We know that within this branch, rightChild must be a cell.
13751370 if (m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
13761371 m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
1377  if ((m_state.forNode(rightChild).m_type & SpecCell) & ~SpecObject) {
1378  speculationCheck(
1379  BadType, JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild,
1380  m_jit.branchPtr(
1381  MacroAssembler::Equal,
1382  MacroAssembler::Address(op2PayloadGPR, JSCell::structureOffset()),
1383  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1384  }
 1372 DFG_TYPE_CHECK(
 1373 JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, (~SpecCell) | SpecObject,
 1374 m_jit.branchPtr(
 1375 MacroAssembler::Equal,
 1376 MacroAssembler::Address(op2PayloadGPR, JSCell::structureOffset()),
 1377 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
13851378 } else {
13861379 GPRTemporary structure(this);
13871380 GPRReg structureGPR = structure.gpr();
13881381
13891382 m_jit.loadPtr(MacroAssembler::Address(op2PayloadGPR, JSCell::structureOffset()), structureGPR);
1390  if ((m_state.forNode(rightChild).m_type & SpecCell) & ~SpecObject) {
1391  speculationCheck(
1392  BadType, JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild,
1393  m_jit.branchPtr(
1394  MacroAssembler::Equal,
1395  structureGPR,
1396  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1397  }
 1383 DFG_TYPE_CHECK(
 1384 JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, (~SpecCell) | SpecObject,
 1385 m_jit.branchPtr(
 1386 MacroAssembler::Equal,
 1387 structureGPR,
 1388 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
13981389 speculationCheck(BadType, JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild,
13991390 m_jit.branchTest8(
14001391 MacroAssembler::NonZero,

@@void SpeculativeJIT::compileObjectToObje
14121403
14131404 // We know that within this branch, rightChild must not be a cell. Check if that is enough to
14141405 // prove that it is either null or undefined.
1415  if ((m_state.forNode(rightChild).m_type & ~SpecCell) & ~SpecOther) {
 1406 if (needsTypeCheck(rightChild, SpecCell | SpecOther)) {
14161407 m_jit.move(op2TagGPR, resultGPR);
14171408 m_jit.or32(TrustedImm32(1), resultGPR);
14181409
1419  speculationCheck(
1420  BadType, JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild,
 1410 typeCheck(
 1411 JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, SpecCell | SpecOther,
14211412 m_jit.branch32(
14221413 MacroAssembler::NotEqual, resultGPR,
14231414 MacroAssembler::TrustedImm32(JSValue::NullTag)));

@@void SpeculativeJIT::compilePeepHoleObje
14391430 BlockIndex notTaken = branchNode->notTakenBlockIndex();
14401431
14411432 SpeculateCellOperand op1(this, leftChild);
1442  JSValueOperand op2(this, rightChild);
 1433 JSValueOperand op2(this, rightChild, ManualOperandSpeculation);
14431434 GPRTemporary result(this);
14441435
14451436 GPRReg op1GPR = op1.gpr();

@@void SpeculativeJIT::compilePeepHoleObje
14491440
14501441 if (m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
14511442 m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
1452  if (m_state.forNode(leftChild).m_type & ~SpecObject) {
1453  speculationCheck(
1454  BadType, JSValueSource::unboxedCell(op1GPR), leftChild,
1455  m_jit.branchPtr(
1456  MacroAssembler::Equal,
1457  MacroAssembler::Address(op1GPR, JSCell::structureOffset()),
1458  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1459  }
 1443 DFG_TYPE_CHECK(
 1444 JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchPtr(
 1445 MacroAssembler::Equal,
 1446 MacroAssembler::Address(op1GPR, JSCell::structureOffset()),
 1447 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
14601448 } else {
14611449 GPRTemporary structure(this);
14621450 GPRReg structureGPR = structure.gpr();
14631451
14641452 m_jit.loadPtr(MacroAssembler::Address(op1GPR, JSCell::structureOffset()), structureGPR);
1465  if (m_state.forNode(leftChild).m_type & ~SpecObject) {
1466  speculationCheck(
1467  BadType, JSValueSource::unboxedCell(op1GPR), leftChild,
1468  m_jit.branchPtr(
1469  MacroAssembler::Equal,
1470  structureGPR,
1471  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1472  }
 1453 DFG_TYPE_CHECK(
 1454 JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchPtr(
 1455 MacroAssembler::Equal,
 1456 structureGPR,
 1457 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
14731458 speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), leftChild,
14741459 m_jit.branchTest8(
14751460 MacroAssembler::NonZero,

@@void SpeculativeJIT::compilePeepHoleObje
14851470 // We know that within this branch, rightChild must be a cell.
14861471 if (m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
14871472 m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
1488  if ((m_state.forNode(rightChild).m_type & SpecCell) & ~SpecObject) {
1489  speculationCheck(
1490  BadType, JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild,
1491  m_jit.branchPtr(
1492  MacroAssembler::Equal,
1493  MacroAssembler::Address(op2PayloadGPR, JSCell::structureOffset()),
1494  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1495  }
 1473 DFG_TYPE_CHECK(
 1474 JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, (~SpecCell) | SpecObject,
 1475 m_jit.branchPtr(
 1476 MacroAssembler::Equal,
 1477 MacroAssembler::Address(op2PayloadGPR, JSCell::structureOffset()),
 1478 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
14961479 } else {
14971480 GPRTemporary structure(this);
14981481 GPRReg structureGPR = structure.gpr();
14991482
15001483 m_jit.loadPtr(MacroAssembler::Address(op2PayloadGPR, JSCell::structureOffset()), structureGPR);
1501  if ((m_state.forNode(rightChild).m_type & SpecCell) & ~SpecObject) {
1502  speculationCheck(
1503  BadType, JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild,
1504  m_jit.branchPtr(
1505  MacroAssembler::Equal,
1506  structureGPR,
1507  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1508  }
 1484 DFG_TYPE_CHECK(
 1485 JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, (~SpecCell) | SpecObject,
 1486 m_jit.branchPtr(
 1487 MacroAssembler::Equal,
 1488 structureGPR,
 1489 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
15091490 speculationCheck(BadType, JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild,
15101491 m_jit.branchTest8(
15111492 MacroAssembler::NonZero,

@@void SpeculativeJIT::compilePeepHoleObje
15201501
15211502 // We know that within this branch, rightChild must not be a cell. Check if that is enough to
15221503 // prove that it is either null or undefined.
1523  if ((m_state.forNode(rightChild).m_type & ~SpecCell) & ~SpecOther)
 1504 if (!needsTypeCheck(rightChild, SpecCell | SpecOther))
15241505 rightNotCell.link(&m_jit);
15251506 else {
15261507 jump(notTaken, ForceJump);

@@void SpeculativeJIT::compilePeepHoleObje
15291510 m_jit.move(op2TagGPR, resultGPR);
15301511 m_jit.or32(TrustedImm32(1), resultGPR);
15311512
1532  speculationCheck(
1533  BadType, JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild,
 1513 typeCheck(
 1514 JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, SpecCell | SpecOther,
15341515 m_jit.branch32(
15351516 MacroAssembler::NotEqual, resultGPR,
15361517 MacroAssembler::TrustedImm32(JSValue::NullTag)));

@@void SpeculativeJIT::compileValueAdd(Nod
15871568 jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
15881569}
15891570
1590 void SpeculativeJIT::compileObjectOrOtherLogicalNot(Edge nodeUse, bool needSpeculationCheck)
 1571void SpeculativeJIT::compileObjectOrOtherLogicalNot(Edge nodeUse)
15911572{
1592  JSValueOperand value(this, nodeUse);
 1573 JSValueOperand value(this, nodeUse, ManualOperandSpeculation);
15931574 GPRTemporary resultPayload(this);
15941575 GPRReg valueTagGPR = value.tagGPR();
15951576 GPRReg valuePayloadGPR = value.payloadGPR();

@@void SpeculativeJIT::compileObjectOrOthe
15991580 if (m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
16001581 m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
16011582
1602  if (needSpeculationCheck) {
1603  speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse,
1604  m_jit.branchPtr(
1605  MacroAssembler::Equal,
1606  MacroAssembler::Address(valuePayloadGPR, JSCell::structureOffset()),
1607  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1608  }
 1583 DFG_TYPE_CHECK(
 1584 JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, (~SpecCell) | SpecObject,
 1585 m_jit.branchPtr(
 1586 MacroAssembler::Equal,
 1587 MacroAssembler::Address(valuePayloadGPR, JSCell::structureOffset()),
 1588 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
16091589 } else {
16101590 GPRTemporary structure(this);
16111591 GPRReg structureGPR = structure.gpr();
16121592
16131593 m_jit.loadPtr(MacroAssembler::Address(valuePayloadGPR, JSCell::structureOffset()), structureGPR);
16141594
1615  if (needSpeculationCheck) {
1616  speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse,
1617  m_jit.branchPtr(
1618  MacroAssembler::Equal,
1619  structureGPR,
1620  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1621  }
 1595 DFG_TYPE_CHECK(
 1596 JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, (~SpecCell) | SpecObject,
 1597 m_jit.branchPtr(
 1598 MacroAssembler::Equal,
 1599 structureGPR,
 1600 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
16221601
16231602 MacroAssembler::Jump isNotMasqueradesAsUndefined =
16241603 m_jit.branchTest8(

@@void SpeculativeJIT::compileObjectOrOthe
16401619 notCell.link(&m_jit);
16411620
16421621 COMPILE_ASSERT((JSValue::UndefinedTag | 1) == JSValue::NullTag, UndefinedTag_OR_1_EQUALS_NullTag);
1643  if (needSpeculationCheck) {
 1622 if (needsTypeCheck(nodeUse, SpecCell | SpecOther)) {
16441623 m_jit.move(valueTagGPR, resultPayloadGPR);
16451624 m_jit.or32(TrustedImm32(1), resultPayloadGPR);
1646  speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse,
 1625 typeCheck(
 1626 JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, SpecCell | SpecOther,
16471627 m_jit.branch32(
16481628 MacroAssembler::NotEqual,
16491629 resultPayloadGPR,

@@void SpeculativeJIT::compileObjectOrOthe
16581638
16591639void SpeculativeJIT::compileLogicalNot(Node* node)
16601640{
1661  if (node->child1()->shouldSpeculateBoolean()) {
 1641 switch (node->child1().useKind()) {
 1642 case BooleanUse: {
16621643 SpeculateBooleanOperand value(this, node->child1());
16631644 GPRTemporary result(this, value);
16641645 m_jit.xor32(TrustedImm32(1), value.gpr(), result.gpr());
16651646 booleanResult(result.gpr(), node);
16661647 return;
16671648 }
1668  if (node->child1()->shouldSpeculateObjectOrOther()) {
1669  compileObjectOrOtherLogicalNot(node->child1(),
1670  !isObjectOrOtherSpeculation(m_state.forNode(node->child1()).m_type));
 1649
 1650 case ObjectOrOtherUse: {
 1651 compileObjectOrOtherLogicalNot(node->child1());
16711652 return;
16721653 }
1673  if (node->child1()->shouldSpeculateInteger()) {
 1654
 1655 case Int32Use: {
16741656 SpeculateIntegerOperand value(this, node->child1());
16751657 GPRTemporary resultPayload(this, value);
16761658 m_jit.compare32(MacroAssembler::Equal, value.gpr(), MacroAssembler::TrustedImm32(0), resultPayload.gpr());
16771659 booleanResult(resultPayload.gpr(), node);
16781660 return;
16791661 }
1680  if (node->child1()->shouldSpeculateNumber()) {
 1662
 1663 case NumberUse: {
16811664 SpeculateDoubleOperand value(this, node->child1());
16821665 FPRTemporary scratch(this);
16831666 GPRTemporary resultPayload(this);

@@void SpeculativeJIT::compileLogicalNot(N
16891672 return;
16901673 }
16911674
1692  JSValueOperand arg1(this, node->child1());
1693  GPRTemporary resultPayload(this, arg1, false);
1694  GPRReg arg1TagGPR = arg1.tagGPR();
1695  GPRReg arg1PayloadGPR = arg1.payloadGPR();
1696  GPRReg resultPayloadGPR = resultPayload.gpr();
 1675 case UntypedUse: {
 1676 JSValueOperand arg1(this, node->child1());
 1677 GPRTemporary resultPayload(this, arg1, false);
 1678 GPRReg arg1TagGPR = arg1.tagGPR();
 1679 GPRReg arg1PayloadGPR = arg1.payloadGPR();
 1680 GPRReg resultPayloadGPR = resultPayload.gpr();
16971681
1698  arg1.use();
 1682 arg1.use();
16991683
1700  JITCompiler::Jump slowCase = m_jit.branch32(JITCompiler::NotEqual, arg1TagGPR, TrustedImm32(JSValue::BooleanTag));
 1684 JITCompiler::Jump slowCase = m_jit.branch32(JITCompiler::NotEqual, arg1TagGPR, TrustedImm32(JSValue::BooleanTag));
17011685
1702  m_jit.move(arg1PayloadGPR, resultPayloadGPR);
 1686 m_jit.move(arg1PayloadGPR, resultPayloadGPR);
17031687
1704  addSlowPathGenerator(
1705  slowPathCall(
1706  slowCase, this, dfgConvertJSValueToBoolean, resultPayloadGPR, arg1TagGPR,
1707  arg1PayloadGPR));
 1688 addSlowPathGenerator(
 1689 slowPathCall(
 1690 slowCase, this, dfgConvertJSValueToBoolean, resultPayloadGPR, arg1TagGPR,
 1691 arg1PayloadGPR));
17081692
1709  m_jit.xor32(TrustedImm32(1), resultPayloadGPR);
1710  booleanResult(resultPayloadGPR, node, UseChildrenCalledExplicitly);
 1693 m_jit.xor32(TrustedImm32(1), resultPayloadGPR);
 1694 booleanResult(resultPayloadGPR, node, UseChildrenCalledExplicitly);
 1695 return;
 1696 }
 1697
 1698 default:
 1699 RELEASE_ASSERT_NOT_REACHED();
 1700 break;
 1701 }
17111702}
17121703
1713 void SpeculativeJIT::emitObjectOrOtherBranch(Edge nodeUse, BlockIndex taken, BlockIndex notTaken, bool needSpeculationCheck)
 1704void SpeculativeJIT::emitObjectOrOtherBranch(Edge nodeUse, BlockIndex taken, BlockIndex notTaken)
17141705{
1715  JSValueOperand value(this, nodeUse);
 1706 JSValueOperand value(this, nodeUse, ManualOperandSpeculation);
17161707 GPRTemporary scratch(this);
17171708 GPRReg valueTagGPR = value.tagGPR();
17181709 GPRReg valuePayloadGPR = value.payloadGPR();

@@void SpeculativeJIT::emitObjectOrOtherBr
17221713 if (m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
17231714 m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
17241715
1725  if (needSpeculationCheck) {
1726  speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse,
1727  m_jit.branchPtr(
1728  MacroAssembler::Equal,
1729  MacroAssembler::Address(valuePayloadGPR, JSCell::structureOffset()),
1730  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1731  }
 1716 DFG_TYPE_CHECK(
 1717 JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, (~SpecCell) | SpecObject,
 1718 m_jit.branchPtr(
 1719 MacroAssembler::Equal,
 1720 MacroAssembler::Address(valuePayloadGPR, JSCell::structureOffset()),
 1721 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
17321722 } else {
17331723 m_jit.loadPtr(MacroAssembler::Address(valuePayloadGPR, JSCell::structureOffset()), scratchGPR);
17341724
1735  if (needSpeculationCheck) {
1736  speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse,
1737  m_jit.branchPtr(
1738  MacroAssembler::Equal,
1739  scratchGPR,
1740  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1741  }
 1725 DFG_TYPE_CHECK(
 1726 JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, (~SpecCell) | SpecObject,
 1727 m_jit.branchPtr(
 1728 MacroAssembler::Equal,
 1729 scratchGPR,
 1730 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
17421731
17431732 JITCompiler::Jump isNotMasqueradesAsUndefined = m_jit.branchTest8(JITCompiler::Zero, MacroAssembler::Address(scratchGPR, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined));
17441733

@@void SpeculativeJIT::emitObjectOrOtherBr
17551744 notCell.link(&m_jit);
17561745
17571746 COMPILE_ASSERT((JSValue::UndefinedTag | 1) == JSValue::NullTag, UndefinedTag_OR_1_EQUALS_NullTag);
1758  if (needSpeculationCheck) {
 1747 if (needsTypeCheck(nodeUse, SpecCell | SpecOther)) {
17591748 m_jit.move(valueTagGPR, scratchGPR);
17601749 m_jit.or32(TrustedImm32(1), scratchGPR);
1761  speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, m_jit.branch32(MacroAssembler::NotEqual, scratchGPR, TrustedImm32(JSValue::NullTag)));
 1750 typeCheck(
 1751 JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, SpecCell | SpecOther,
 1752 m_jit.branch32(MacroAssembler::NotEqual, scratchGPR, TrustedImm32(JSValue::NullTag)));
17621753 }
17631754
17641755 jump(notTaken);

@@void SpeculativeJIT::emitBranch(Node* no
17711762 BlockIndex taken = node->takenBlockIndex();
17721763 BlockIndex notTaken = node->notTakenBlockIndex();
17731764
1774  if (node->shouldSpeculateBoolean()) {
 1765 switch (node->child1().useKind()) {
 1766 case BooleanUse: {
17751767 SpeculateBooleanOperand value(this, node->child1());
17761768 MacroAssembler::ResultCondition condition = MacroAssembler::NonZero;
17771769

@@void SpeculativeJIT::emitBranch(Node* no
17891781 return;
17901782 }
17911783
1792  if (node->child1()->shouldSpeculateObjectOrOther()) {
1793  emitObjectOrOtherBranch(node->child1(), taken, notTaken,
1794  !isObjectOrOtherSpeculation(m_state.forNode(node->child1()).m_type));
 1784 case ObjectOrOtherUse: {
 1785 emitObjectOrOtherBranch(node->child1(), taken, notTaken);
17951786 return;
17961787 }
17971788
1798  if (node->child1()->shouldSpeculateNumber()) {
1799  if (node->child1()->shouldSpeculateInteger()) {
 1789 case NumberUse:
 1790 case Int32Use: {
 1791 if (node->child1().useKind() == Int32Use) {
18001792 bool invert = false;
18011793
18021794 if (taken == nextBlock()) {

@@void SpeculativeJIT::emitBranch(Node* no
18201812 return;
18211813 }
18221814
1823  JSValueOperand value(this, node->child1());
1824  value.fill();
1825  GPRReg valueTagGPR = value.tagGPR();
1826  GPRReg valuePayloadGPR = value.payloadGPR();
 1815 case UntypedUse: {
 1816 JSValueOperand value(this, node->child1());
 1817 value.fill();
 1818 GPRReg valueTagGPR = value.tagGPR();
 1819 GPRReg valuePayloadGPR = value.payloadGPR();
18271820
1828  GPRTemporary result(this);
1829  GPRReg resultGPR = result.gpr();
 1821 GPRTemporary result(this);
 1822 GPRReg resultGPR = result.gpr();
18301823
1831  use(node->child1());
 1824 use(node->child1());
18321825
1833  JITCompiler::Jump fastPath = m_jit.branch32(JITCompiler::Equal, valueTagGPR, JITCompiler::TrustedImm32(JSValue::Int32Tag));
1834  JITCompiler::Jump slowPath = m_jit.branch32(JITCompiler::NotEqual, valueTagGPR, JITCompiler::TrustedImm32(JSValue::BooleanTag));
1835 
1836  fastPath.link(&m_jit);
1837  branchTest32(JITCompiler::Zero, valuePayloadGPR, notTaken);
1838  jump(taken, ForceJump);
 1826 JITCompiler::Jump fastPath = m_jit.branch32(JITCompiler::Equal, valueTagGPR, JITCompiler::TrustedImm32(JSValue::Int32Tag));
 1827 JITCompiler::Jump slowPath = m_jit.branch32(JITCompiler::NotEqual, valueTagGPR, JITCompiler::TrustedImm32(JSValue::BooleanTag));
18391828
1840  slowPath.link(&m_jit);
1841  silentSpillAllRegisters(resultGPR);
1842  callOperation(dfgConvertJSValueToBoolean, resultGPR, valueTagGPR, valuePayloadGPR);
1843  silentFillAllRegisters(resultGPR);
 1829 fastPath.link(&m_jit);
 1830 branchTest32(JITCompiler::Zero, valuePayloadGPR, notTaken);
 1831 jump(taken, ForceJump);
 1832
 1833 slowPath.link(&m_jit);
 1834 silentSpillAllRegisters(resultGPR);
 1835 callOperation(dfgConvertJSValueToBoolean, resultGPR, valueTagGPR, valuePayloadGPR);
 1836 silentFillAllRegisters(resultGPR);
18441837
1845  branchTest32(JITCompiler::NonZero, resultGPR, taken);
1846  jump(notTaken);
 1838 branchTest32(JITCompiler::NonZero, resultGPR, taken);
 1839 jump(notTaken);
18471840
1848  noResult(node, UseChildrenCalledExplicitly);
 1841 noResult(node, UseChildrenCalledExplicitly);
 1842 return;
 1843 }
 1844
 1845 default:
 1846 RELEASE_ASSERT_NOT_REACHED();
 1847 break;
 1848 }
18491849}
18501850
18511851template<typename BaseOperandType, typename PropertyOperandType, typename ValueOperandType, typename TagType>

@@void SpeculativeJIT::compile(Node* node)
19301930 break;
19311931
19321932 case Identity: {
1933  // This could be done a lot better. We take the cheap way out because Identity
1934  // is only going to stick around after CSE if we had prediction weirdness.
1935  JSValueOperand operand(this, node->child1());
1936  GPRTemporary resultTag(this);
1937  GPRTemporary resultPayload(this);
1938  m_jit.move(operand.tagGPR(), resultTag.gpr());
1939  m_jit.move(operand.payloadGPR(), resultPayload.gpr());
1940  jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
 1933 RELEASE_ASSERT_NOT_REACHED();
19411934 break;
19421935 }
19431936

@@void SpeculativeJIT::compile(Node* node)
19551948 // If the CFA is tracking this variable and it found that the variable
19561949 // cannot have been assigned, then don't attempt to proceed.
19571950 if (value.isClear()) {
 1951 // FIXME: We should trap instead.
 1952 // https://bugs.webkit.org/show_bug.cgi?id=110383
19581953 terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
19591954 break;
19601955 }

@@void SpeculativeJIT::compile(Node* node)
20552050 }
20562051 SpeculatedType predictedType = node->variableAccessData()->argumentAwarePrediction();
20572052 if (m_generationInfo[node->child1()->virtualRegister()].registerFormat() == DataFormatDouble) {
2058  SpeculateDoubleOperand value(this, Edge(node->child1().node(), DoubleUse));
 2053 SpeculateDoubleOperand value(this, node->child1(), BackwardSpeculation, ManualOperandSpeculation);
20592054 m_jit.storeDouble(value.fpr(), JITCompiler::addressFor(node->local()));
20602055 noResult(node);
20612056 recordSetLocal(node->local(), ValueSource(DoubleInJSStack));

@@void SpeculativeJIT::compile(Node* node)
21832178 break;
21842179 }
21852180
2186  case CheckNumber: {
2187  if (!isNumberSpeculation(m_state.forNode(node->child1()).m_type)) {
2188  JSValueOperand op1(this, node->child1());
2189  JITCompiler::Jump isInteger = m_jit.branch32(MacroAssembler::Equal, op1.tagGPR(), TrustedImm32(JSValue::Int32Tag));
2190  speculationCheck(
2191  BadType, JSValueRegs(op1.tagGPR(), op1.payloadGPR()), node->child1(),
2192  m_jit.branch32(MacroAssembler::AboveOrEqual, op1.tagGPR(), TrustedImm32(JSValue::LowestTag)));
2193  isInteger.link(&m_jit);
2194  }
2195  noResult(node);
2196  break;
2197  }
2198 
21992181 case ValueAdd:
22002182 case ArithAdd:
22012183 compileAdd(node);

@@void SpeculativeJIT::compile(Node* node)
22142196 break;
22152197
22162198 case ArithDiv: {
2217  if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node())
2218  && node->canSpeculateInteger()) {
 2199 switch (node->binaryUseKind()) {
 2200 case Int32Use: {
22192201#if CPU(X86)
22202202 compileIntegerArithDivForX86(node);
22212203#elif CPU(APPLE_ARMV7S)

@@void SpeculativeJIT::compile(Node* node)
22252207#endif
22262208 break;
22272209 }
2228 
2229  SpeculateDoubleOperand op1(this, node->child1());
2230  SpeculateDoubleOperand op2(this, node->child2());
2231  FPRTemporary result(this, op1);
2232 
2233  FPRReg reg1 = op1.fpr();
2234  FPRReg reg2 = op2.fpr();
2235  m_jit.divDouble(reg1, reg2, result.fpr());
2236 
2237  doubleResult(result.fpr(), node);
 2210
 2211 case NumberUse: {
 2212 SpeculateDoubleOperand op1(this, node->child1());
 2213 SpeculateDoubleOperand op2(this, node->child2());
 2214 FPRTemporary result(this, op1);
 2215
 2216 FPRReg reg1 = op1.fpr();
 2217 FPRReg reg2 = op2.fpr();
 2218 m_jit.divDouble(reg1, reg2, result.fpr());
 2219
 2220 doubleResult(result.fpr(), node);
 2221 break;
 2222 }
 2223
 2224 default:
 2225 RELEASE_ASSERT_NOT_REACHED();
 2226 break;
 2227 }
22382228 break;
22392229 }
22402230

@@void SpeculativeJIT::compile(Node* node)
22442234 }
22452235
22462236 case ArithAbs: {
2247  if (node->child1()->shouldSpeculateIntegerForArithmetic()
2248  && node->canSpeculateInteger()) {
 2237 switch (node->child1().useKind()) {
 2238 case Int32Use: {
22492239 SpeculateIntegerOperand op1(this, node->child1());
22502240 GPRTemporary result(this, op1);
22512241 GPRTemporary scratch(this);

@@void SpeculativeJIT::compile(Node* node)
22592249 break;
22602250 }
22612251
2262  SpeculateDoubleOperand op1(this, node->child1());
2263  FPRTemporary result(this);
2264 
2265  m_jit.absDouble(op1.fpr(), result.fpr());
2266  doubleResult(result.fpr(), node);
 2252
 2253 case NumberUse: {
 2254 SpeculateDoubleOperand op1(this, node->child1());
 2255 FPRTemporary result(this);
 2256
 2257 m_jit.absDouble(op1.fpr(), result.fpr());
 2258 doubleResult(result.fpr(), node);
 2259 break;
 2260 }
 2261
 2262 default:
 2263 RELEASE_ASSERT_NOT_REACHED();
 2264 break;
 2265 }
22672266 break;
22682267 }
22692268
22702269 case ArithMin:
22712270 case ArithMax: {
2272  if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node())
2273  && node->canSpeculateInteger()) {
 2271 switch (node->binaryUseKind()) {
 2272 case Int32Use: {
22742273 SpeculateStrictInt32Operand op1(this, node->child1());
22752274 SpeculateStrictInt32Operand op2(this, node->child2());
22762275 GPRTemporary result(this, op1);

@@void SpeculativeJIT::compile(Node* node)
22892288 break;
22902289 }
22912290
2292  SpeculateDoubleOperand op1(this, node->child1());
2293  SpeculateDoubleOperand op2(this, node->child2());
2294  FPRTemporary result(this, op1);
 2291 case NumberUse: {
 2292 SpeculateDoubleOperand op1(this, node->child1());
 2293 SpeculateDoubleOperand op2(this, node->child2());
 2294 FPRTemporary result(this, op1);
22952295
2296  MacroAssembler::JumpList done;
 2296 MacroAssembler::JumpList done;
22972297
2298  MacroAssembler::Jump op1Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleLessThan : MacroAssembler::DoubleGreaterThan, op1.fpr(), op2.fpr());
 2298 MacroAssembler::Jump op1Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleLessThan : MacroAssembler::DoubleGreaterThan, op1.fpr(), op2.fpr());
22992299
2300  // op2 is eather the lesser one or one of then is NaN
2301  MacroAssembler::Jump op2Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleGreaterThanOrEqual : MacroAssembler::DoubleLessThanOrEqual, op1.fpr(), op2.fpr());
 2300 // op2 is eather the lesser one or one of then is NaN
 2301 MacroAssembler::Jump op2Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleGreaterThanOrEqual : MacroAssembler::DoubleLessThanOrEqual, op1.fpr(), op2.fpr());
23022302
2303  // Unordered case. We don't know which of op1, op2 is NaN. Manufacture NaN by adding
2304  // op1 + op2 and putting it into result.
2305  m_jit.addDouble(op1.fpr(), op2.fpr(), result.fpr());
2306  done.append(m_jit.jump());
 2303 // Unordered case. We don't know which of op1, op2 is NaN. Manufacture NaN by adding
 2304 // op1 + op2 and putting it into result.
 2305 m_jit.addDouble(op1.fpr(), op2.fpr(), result.fpr());
 2306 done.append(m_jit.jump());
23072307
2308  op2Less.link(&m_jit);
2309  m_jit.moveDouble(op2.fpr(), result.fpr());
 2308 op2Less.link(&m_jit);
 2309 m_jit.moveDouble(op2.fpr(), result.fpr());
23102310
2311  if (op1.fpr() != result.fpr()) {
2312  done.append(m_jit.jump());
 2311 if (op1.fpr() != result.fpr()) {
 2312 done.append(m_jit.jump());
23132313
2314  op1Less.link(&m_jit);
2315  m_jit.moveDouble(op1.fpr(), result.fpr());
2316  } else
2317  op1Less.link(&m_jit);
 2314 op1Less.link(&m_jit);
 2315 m_jit.moveDouble(op1.fpr(), result.fpr());
 2316 } else
 2317 op1Less.link(&m_jit);
23182318
2319  done.link(&m_jit);
 2319 done.link(&m_jit);
23202320
2321  doubleResult(result.fpr(), node);
 2321 doubleResult(result.fpr(), node);
 2322 break;
 2323 }
 2324
 2325 default:
 2326 RELEASE_ASSERT_NOT_REACHED();
 2327 break;
 2328 }
23222329 break;
23232330 }
23242331

@@void SpeculativeJIT::compile(Node* node)
29812988 SpeculateDoubleOperand value(this, node->child2());
29822989 FPRReg valueFPR = value.fpr();
29832990
2984  if (!isRealNumberSpeculation(m_state.forNode(node->child2()).m_type)) {
2985  // FIXME: We need a way of profiling these, and we need to hoist them into
2986  // SpeculateDoubleOperand.
2987  speculationCheck(
2988  BadType, JSValueRegs(), 0,
2989  m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, valueFPR, valueFPR));
2990  }
 2991 DFG_TYPE_CHECK(
 2992 JSValueRegs(), node->child2(), SpecRealNumber,
 2993 m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, valueFPR, valueFPR));
29912994
29922995 m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR);
29932996 MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength()));

@@void SpeculativeJIT::compile(Node* node)
32353238 }
32363239
32373240 case ToPrimitive: {
3238  if (node->child1()->shouldSpeculateInteger()) {
 3241 switch (node->child1().useKind()) {
 3242 case Int32Use: {
32393243 // It's really profitable to speculate integer, since it's really cheap,
32403244 // it means we don't have to do any real work, and we emit a lot less code.
32413245

@@void SpeculativeJIT::compile(Node* node)
32483252 integerResult(result.gpr(), node);
32493253 break;
32503254 }
 3255
 3256 case UntypedUse: {
 3257 JSValueOperand op1(this, node->child1());
 3258 GPRTemporary resultTag(this, op1);
 3259 GPRTemporary resultPayload(this, op1, false);
32513260
3252  // FIXME: Add string speculation here.
3253 
3254  JSValueOperand op1(this, node->child1());
3255  GPRTemporary resultTag(this, op1);
3256  GPRTemporary resultPayload(this, op1, false);
3257 
3258  GPRReg op1TagGPR = op1.tagGPR();
3259  GPRReg op1PayloadGPR = op1.payloadGPR();
3260  GPRReg resultTagGPR = resultTag.gpr();
3261  GPRReg resultPayloadGPR = resultPayload.gpr();
 3261 GPRReg op1TagGPR = op1.tagGPR();
 3262 GPRReg op1PayloadGPR = op1.payloadGPR();
 3263 GPRReg resultTagGPR = resultTag.gpr();
 3264 GPRReg resultPayloadGPR = resultPayload.gpr();
32623265
3263  op1.use();
 3266 op1.use();
32643267
3265  if (!(m_state.forNode(node->child1()).m_type & ~(SpecNumber | SpecBoolean))) {
3266  m_jit.move(op1TagGPR, resultTagGPR);
3267  m_jit.move(op1PayloadGPR, resultPayloadGPR);
3268  } else {
3269  MacroAssembler::Jump alreadyPrimitive = m_jit.branch32(MacroAssembler::NotEqual, op1TagGPR, TrustedImm32(JSValue::CellTag));
3270  MacroAssembler::Jump notPrimitive = m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1PayloadGPR, JSCell::structureOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get()));
 3268 if (!(m_state.forNode(node->child1()).m_type & ~(SpecNumber | SpecBoolean))) {
 3269 m_jit.move(op1TagGPR, resultTagGPR);
 3270 m_jit.move(op1PayloadGPR, resultPayloadGPR);
 3271 } else {
 3272 MacroAssembler::Jump alreadyPrimitive = m_jit.branch32(MacroAssembler::NotEqual, op1TagGPR, TrustedImm32(JSValue::CellTag));
 3273 MacroAssembler::Jump notPrimitive = m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1PayloadGPR, JSCell::structureOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get()));
32713274
3272  alreadyPrimitive.link(&m_jit);
3273  m_jit.move(op1TagGPR, resultTagGPR);
3274  m_jit.move(op1PayloadGPR, resultPayloadGPR);
 3275 alreadyPrimitive.link(&m_jit);
 3276 m_jit.move(op1TagGPR, resultTagGPR);
 3277 m_jit.move(op1PayloadGPR, resultPayloadGPR);
32753278
3276  addSlowPathGenerator(
3277  slowPathCall(
3278  notPrimitive, this, operationToPrimitive,
3279  JSValueRegs(resultTagGPR, resultPayloadGPR), op1TagGPR, op1PayloadGPR));
3280  }
 3279 addSlowPathGenerator(
 3280 slowPathCall(
 3281 notPrimitive, this, operationToPrimitive,
 3282 JSValueRegs(resultTagGPR, resultPayloadGPR), op1TagGPR, op1PayloadGPR));
 3283 }
32813284
3282  jsValueResult(resultTagGPR, resultPayloadGPR, node, UseChildrenCalledExplicitly);
 3285 jsValueResult(resultTagGPR, resultPayloadGPR, node, UseChildrenCalledExplicitly);
 3286 break;
 3287 }
 3288
 3289 default:
 3290 RELEASE_ASSERT_NOT_REACHED();
 3291 break;
 3292 }
32833293 break;
32843294 }
32853295

@@void SpeculativeJIT::compile(Node* node)
33633373 case ALL_DOUBLE_INDEXING_TYPES: {
33643374 SpeculateDoubleOperand operand(this, use);
33653375 FPRReg opFPR = operand.fpr();
3366  if (!isRealNumberSpeculation(m_state.forNode(use).m_type)) {
3367  // FIXME: We need a way of profiling these, and we need to hoist them into
3368  // SpeculateDoubleOperand.
3369  speculationCheck(
3370  BadType, JSValueRegs(), 0,
3371  m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR));
3372  }
 3376 DFG_TYPE_CHECK(
 3377 JSValueRegs(), use, SpecRealNumber,
 3378 m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR));
33733379
33743380 m_jit.storeDouble(opFPR, MacroAssembler::Address(storageGPR, sizeof(double) * operandIdx));
33753381 break;

@@void SpeculativeJIT::compile(Node* node)
34323438 case ALL_DOUBLE_INDEXING_TYPES: {
34333439 SpeculateDoubleOperand operand(this, use);
34343440 FPRReg opFPR = operand.fpr();
3435  if (!isRealNumberSpeculation(m_state.forNode(use).m_type)) {
3436  // FIXME: We need a way of profiling these, and we need to hoist them into
3437  // SpeculateDoubleOperand.
3438  speculationCheck(
3439  BadType, JSValueRegs(), 0,
3440  m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR));
3441  }
 3441 DFG_TYPE_CHECK(
 3442 JSValueRegs(), use, SpecRealNumber,
 3443 m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR));
34423444
34433445 m_jit.storeDouble(opFPR, reinterpret_cast<char*>(buffer + operandIdx));
34443446 break;

@@void SpeculativeJIT::compile(Node* node)
36393641 }
36403642
36413643 case ConvertThis: {
3642  if (isObjectSpeculation(m_state.forNode(node->child1()).m_type)) {
3643  SpeculateCellOperand thisValue(this, node->child1());
3644  GPRTemporary result(this, thisValue);
3645  m_jit.move(thisValue.gpr(), result.gpr());
3646  cellResult(result.gpr(), node);
3647  break;
3648  }
3649 
3650  if (isOtherSpeculation(node->child1()->prediction())) {
3651  JSValueOperand thisValue(this, node->child1());
 3644 switch (node->child1().useKind()) {
 3645 case OtherUse: {
 3646 JSValueOperand thisValue(this, node->child1(), ManualOperandSpeculation);
36523647 GPRTemporary scratch(this);
36533648
36543649 GPRReg thisValueTagGPR = thisValue.tagGPR();
36553650 GPRReg scratchGPR = scratch.gpr();
36563651
36573652 COMPILE_ASSERT((JSValue::UndefinedTag | 1) == JSValue::NullTag, UndefinedTag_OR_1_EQUALS_NullTag);
3658  m_jit.move(thisValueTagGPR, scratchGPR);
3659  m_jit.or32(TrustedImm32(1), scratchGPR);
3660  // This is hard. It would be better to save the value, but we can't quite do it,
3661  // since this operation does not otherwise get the payload.
3662  speculationCheck(BadType, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::NotEqual, scratchGPR, TrustedImm32(JSValue::NullTag)));
 3653 if (needsTypeCheck(node->child1(), SpecOther)) {
 3654 m_jit.move(thisValueTagGPR, scratchGPR);
 3655 m_jit.or32(TrustedImm32(1), scratchGPR);
 3656 // This is hard. It would be better to save the value, but we can't quite do it,
 3657 // since this operation does not otherwise get the payload.
 3658 typeCheck(
 3659 JSValueRegs(), node->child1(), SpecOther,
 3660 m_jit.branch32(
 3661 MacroAssembler::NotEqual, scratchGPR, TrustedImm32(JSValue::NullTag)));
 3662 }
36633663
36643664 m_jit.move(MacroAssembler::TrustedImmPtr(m_jit.globalThisObjectFor(node->codeOrigin)), scratchGPR);
36653665 cellResult(scratchGPR, node);
36663666 break;
36673667 }
36683668
3669  if (isObjectSpeculation(node->child1()->prediction())) {
 3669 case ObjectUse: {
36703670 SpeculateCellOperand thisValue(this, node->child1());
36713671 GPRReg thisValueGPR = thisValue.gpr();
36723672
3673  if (!isObjectSpeculation(m_state.forNode(node->child1()).m_type))
3674  speculationCheck(BadType, JSValueSource::unboxedCell(thisValueGPR), node->child1(), m_jit.branchPtr(JITCompiler::Equal, JITCompiler::Address(thisValueGPR, JSCell::structureOffset()), JITCompiler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
 3673 DFG_TYPE_CHECK(
 3674 JSValueSource::unboxedCell(thisValueGPR), node->child1(), SpecObject,
 3675 m_jit.branchPtr(
 3676 JITCompiler::Equal,
 3677 JITCompiler::Address(thisValueGPR, JSCell::structureOffset()),
 3678 JITCompiler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
36753679
36763680 GPRTemporary result(this, thisValue);
36773681 GPRReg resultGPR = result.gpr();

@@void SpeculativeJIT::compile(Node* node)
36803684 break;
36813685 }
36823686
3683  JSValueOperand thisValue(this, node->child1());
3684  GPRReg thisValueTagGPR = thisValue.tagGPR();
3685  GPRReg thisValuePayloadGPR = thisValue.payloadGPR();
3686 
3687  flushRegisters();
3688 
3689  GPRResult2 resultTag(this);
3690  GPRResult resultPayload(this);
3691  callOperation(operationConvertThis, resultTag.gpr(), resultPayload.gpr(), thisValueTagGPR, thisValuePayloadGPR);
3692 
3693  cellResult(resultPayload.gpr(), node);
 3687 case UntypedUse: {
 3688 JSValueOperand thisValue(this, node->child1());
 3689 GPRReg thisValueTagGPR = thisValue.tagGPR();
 3690 GPRReg thisValuePayloadGPR = thisValue.payloadGPR();
 3691
 3692 flushRegisters();
 3693
 3694 GPRResult2 resultTag(this);
 3695 GPRResult resultPayload(this);
 3696 callOperation(operationConvertThis, resultTag.gpr(), resultPayload.gpr(), thisValueTagGPR, thisValuePayloadGPR);
 3697
 3698 cellResult(resultPayload.gpr(), node);
 3699 break;
 3700 }
 3701
 3702 default:
 3703 RELEASE_ASSERT_NOT_REACHED();
 3704 break;
 3705 }
36943706 break;
36953707 }
36963708

@@void SpeculativeJIT::compile(Node* node)
39063918 break;
39073919 }
39083920
3909  if (isCellSpeculation(node->child1()->prediction())) {
 3921 switch (node->child1().useKind()) {
 3922 case CellUse: {
39103923 SpeculateCellOperand base(this, node->child1());
39113924
39123925 GPRReg baseGPR = base.gpr();

@@void SpeculativeJIT::compile(Node* node)
39263939 break;
39273940 }
39283941
3929  JSValueOperand base(this, node->child1());
3930  GPRReg baseTagGPR = base.tagGPR();
3931  GPRReg basePayloadGPR = base.payloadGPR();
 3942 case UntypedUse: {
 3943 JSValueOperand base(this, node->child1());
 3944 GPRReg baseTagGPR = base.tagGPR();
 3945 GPRReg basePayloadGPR = base.payloadGPR();
39323946
3933  GPRResult resultTag(this);
3934  GPRResult2 resultPayload(this);
3935  GPRReg resultTagGPR = resultTag.gpr();
3936  GPRReg resultPayloadGPR = resultPayload.gpr();
 3947 GPRResult resultTag(this);
 3948 GPRResult2 resultPayload(this);
 3949 GPRReg resultTagGPR = resultTag.gpr();
 3950 GPRReg resultPayloadGPR = resultPayload.gpr();
39373951
3938  base.use();
 3952 base.use();
39393953
3940  flushRegisters();
 3954 flushRegisters();
39413955
3942  JITCompiler::Jump notCell = m_jit.branch32(JITCompiler::NotEqual, baseTagGPR, TrustedImm32(JSValue::CellTag));
 3956 JITCompiler::Jump notCell = m_jit.branch32(JITCompiler::NotEqual, baseTagGPR, TrustedImm32(JSValue::CellTag));
39433957
3944  cachedGetById(node->codeOrigin, baseTagGPR, basePayloadGPR, resultTagGPR, resultPayloadGPR, node->identifierNumber(), notCell, DontSpill);
 3958 cachedGetById(node->codeOrigin, baseTagGPR, basePayloadGPR, resultTagGPR, resultPayloadGPR, node->identifierNumber(), notCell, DontSpill);
39453959
3946  jsValueResult(resultTagGPR, resultPayloadGPR, node, UseChildrenCalledExplicitly);
 3960 jsValueResult(resultTagGPR, resultPayloadGPR, node, UseChildrenCalledExplicitly);
 3961 break;
 3962 }
 3963
 3964 default:
 3965 RELEASE_ASSERT_NOT_REACHED();
 3966 break;
 3967 }
39473968 break;
39483969 }
39493970

@@void SpeculativeJIT::compile(Node* node)
39673988
39683989 case CheckStructure:
39693990 case ForwardCheckStructure: {
3970  AbstractValue& value = m_state.forNode(node->child1());
3971  if (value.m_currentKnownStructure.isSubsetOf(node->structureSet())
3972  && isCellSpeculation(value.m_type)) {
3973  noResult(node);
3974  break;
3975  }
3976 
39773991 SpeculationDirection direction = node->op() == ForwardCheckStructure ? ForwardSpeculation : BackwardSpeculation;
39783992 SpeculateCellOperand base(this, node->child1(), direction);
39793993

@@void SpeculativeJIT::compile(Node* node)
40324046 JITCompiler::Jump isOK = m_jit.branchPtr(JITCompiler::Equal, JITCompiler::Address(op1.gpr(), JSCell::structureOffset()), TrustedImmPtr(node->structure()));
40334047 m_jit.breakpoint();
40344048 isOK.link(&m_jit);
 4049#else
 4050 speculaceCell(node->child1());
40354051#endif
40364052
40374053 noResult(node);

@@void SpeculativeJIT::compile(Node* node)
40394055 }
40404056
40414057 case PhantomPutStructure: {
 4058 ASSERT(isKnownCell(node->child1().node()));
40424059 ASSERT(node->structureTransitionData().previousStructure->transitionWatchpointSetHasBeenInvalidated());
40434060 m_jit.addWeakReferenceTransition(
40444061 node->codeOrigin.codeOriginOwner(),

@@void SpeculativeJIT::compile(Node* node)
43904407
43914408 flushRegisters();
43924409
 4410 ASSERT(node->child1().useKind() == UntypedUse || node->child1().useKind() == CellUse || node->child1().useKind() == StringUse);
 4411
43934412 JITCompiler::Jump isNotCell = m_jit.branch32(JITCompiler::NotEqual, tagGPR, JITCompiler::TrustedImm32(JSValue::CellTag));
4394  if (node->child1()->shouldSpeculateCell())
 4413 if (node->child1().useKind() != UntypedUse)
43954414 speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), node->child1(), isNotCell);
43964415
4397  if (!node->child1()->shouldSpeculateObject()) {
 4416 if (!node->child1()->shouldSpeculateObject() || node->child1().useKind() == StringUse) {
43984417 m_jit.loadPtr(JITCompiler::Address(payloadGPR, JSCell::structureOffset()), tempGPR);
43994418 JITCompiler::Jump notString = m_jit.branch8(JITCompiler::NotEqual, JITCompiler::Address(tempGPR, Structure::typeInfoTypeOffset()), TrustedImm32(StringType));
4400  if (node->child1()->shouldSpeculateString())
4401  speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), node->child1(), notString);
 4419 if (node->child1().useKind() == StringUse)
 4420 DFG_TYPE_CHECK(JSValueRegs(tagGPR, payloadGPR), node->child1(), SpecString, notString);
44024421 m_jit.move(TrustedImmPtr(m_jit.globalData()->smallStrings.stringString()), resultGPR);
44034422 doneJumps.append(m_jit.jump());
4404  if (!node->child1()->shouldSpeculateString()) {
 4423 if (node->child1().useKind() != StringUse) {
44054424 notString.link(&m_jit);
44064425 callOperation(operationTypeOf, resultGPR, payloadGPR);
44074426 doneJumps.append(m_jit.jump());

@@void SpeculativeJIT::compile(Node* node)
44114430 doneJumps.append(m_jit.jump());
44124431 }
44134432
4414  if (!node->child1()->shouldSpeculateCell()) {
 4433 if (node->child1().useKind() == UntypedUse) {
44154434 isNotCell.link(&m_jit);
44164435
44174436 m_jit.add32(TrustedImm32(1), tagGPR, tempGPR);

@@void SpeculativeJIT::compile(Node* node)
49284947 break;
49294948
49304949 case Phantom:
 4950 DFG_NODE_DO_TO_CHILDREN(m_jit.graph(), node, speculate);
 4951 noResult(node);
 4952 break;
 4953
49314954 case PhantomLocal:
49324955 // This is a no-op.
49334956 noResult(node);
143562

Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

@@namespace JSC { namespace DFG {
3939
4040#if USE(JSVALUE64)
4141
42 GPRReg SpeculativeJIT::fillInteger(Node* node, DataFormat& returnFormat)
 42GPRReg SpeculativeJIT::fillInteger(Edge edge, DataFormat& returnFormat)
4343{
44  VirtualRegister virtualRegister = node->virtualRegister();
 44 ASSERT(!needsTypeCheck(edge, SpecInt32));
 45
 46 VirtualRegister virtualRegister = edge->virtualRegister();
4547 GenerationInfo& info = m_generationInfo[virtualRegister];
4648
4749 if (info.registerFormat() == DataFormatNone) {
4850 GPRReg gpr = allocate();
4951
50  if (node->hasConstant()) {
 52 if (edge->hasConstant()) {
5153 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
52  if (isInt32Constant(node)) {
53  m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(node)), gpr);
 54 if (isInt32Constant(edge.node())) {
 55 m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(edge.node())), gpr);
5456 info.fillInteger(*m_stream, gpr);
5557 returnFormat = DataFormatInteger;
5658 return gpr;
5759 }
58  if (isNumberConstant(node)) {
59  JSValue jsValue = jsNumber(valueOfNumberConstant(node));
 60 if (isNumberConstant(edge.node())) {
 61 JSValue jsValue = jsNumber(valueOfNumberConstant(edge.node()));
6062 m_jit.move(MacroAssembler::Imm64(JSValue::encode(jsValue)), gpr);
6163 } else {
62  ASSERT(isJSConstant(node));
63  JSValue jsValue = valueOfJSConstant(node);
 64 ASSERT(isJSConstant(edge.node()));
 65 JSValue jsValue = valueOfJSConstant(edge.node());
6466 m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);
6567 }
6668 } else if (info.spillFormat() == DataFormatInteger) {

@@GPRReg SpeculativeJIT::fillInteger(Node*
117119 }
118120}
119121
120 GPRReg SpeculativeJIT::fillJSValue(Node* node)
 122GPRReg SpeculativeJIT::fillJSValue(Edge edge)
121123{
122  VirtualRegister virtualRegister = node->virtualRegister();
 124 VirtualRegister virtualRegister = edge->virtualRegister();
123125 GenerationInfo& info = m_generationInfo[virtualRegister];
124126
125127 switch (info.registerFormat()) {
126128 case DataFormatNone: {
127129 GPRReg gpr = allocate();
128130
129  if (node->hasConstant()) {
130  if (isInt32Constant(node)) {
 131 if (edge->hasConstant()) {
 132 if (isInt32Constant(edge.node())) {
131133 info.fillJSValue(*m_stream, gpr, DataFormatJSInteger);
132  JSValue jsValue = jsNumber(valueOfInt32Constant(node));
 134 JSValue jsValue = jsNumber(valueOfInt32Constant(edge.node()));
133135 m_jit.move(MacroAssembler::Imm64(JSValue::encode(jsValue)), gpr);
134  } else if (isNumberConstant(node)) {
 136 } else if (isNumberConstant(edge.node())) {
135137 info.fillJSValue(*m_stream, gpr, DataFormatJSDouble);
136  JSValue jsValue(JSValue::EncodeAsDouble, valueOfNumberConstant(node));
 138 JSValue jsValue(JSValue::EncodeAsDouble, valueOfNumberConstant(edge.node()));
137139 m_jit.move(MacroAssembler::Imm64(JSValue::encode(jsValue)), gpr);
138140 } else {
139  ASSERT(isJSConstant(node));
140  JSValue jsValue = valueOfJSConstant(node);
 141 ASSERT(isJSConstant(edge.node()));
 142 JSValue jsValue = valueOfJSConstant(edge.node());
141143 m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);
142144 info.fillJSValue(*m_stream, gpr, DataFormatJS);
143145 }

@@void SpeculativeJIT::emitCall(Node* node
802804}
803805
804806template<bool strict>
805 GPRReg SpeculativeJIT::fillSpeculateIntInternal(Node* node, DataFormat& returnFormat, SpeculationDirection direction)
 807GPRReg SpeculativeJIT::fillSpeculateIntInternal(Edge edge, DataFormat& returnFormat, SpeculationDirection direction)
806808{
807809#if DFG_ENABLE(DEBUG_VERBOSE)
808  dataLogF("SpecInt@%d ", node->index());
 810 dataLogF("SpecInt@%d ", edge->index());
809811#endif
810  SpeculatedType type = m_state.forNode(node).m_type;
811  VirtualRegister virtualRegister = node->virtualRegister();
 812 AbstractValue& value = m_state.forNode(edge);
 813 SpeculatedType type = value.m_type;
 814 ASSERT(edge.useKind() != KnownInt32Use || !(value.m_type & ~SpecInt32));
 815 value.filter(SpecInt32);
 816 VirtualRegister virtualRegister = edge->virtualRegister();
812817 GenerationInfo& info = m_generationInfo[virtualRegister];
813818
814819 switch (info.registerFormat()) {
815820 case DataFormatNone: {
816  if ((node->hasConstant() && !isInt32Constant(node)) || info.spillFormat() == DataFormatDouble) {
 821 if ((edge->hasConstant() && !isInt32Constant(edge.node())) || info.spillFormat() == DataFormatDouble) {
817822 terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0, direction);
818823 returnFormat = DataFormatInteger;
819824 return allocate();

@@GPRReg SpeculativeJIT::fillSpeculateIntI
821826
822827 GPRReg gpr = allocate();
823828
824  if (node->hasConstant()) {
 829 if (edge->hasConstant()) {
825830 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
826  ASSERT(isInt32Constant(node));
827  m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(node)), gpr);
 831 ASSERT(isInt32Constant(edge.node()));
 832 m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(edge.node())), gpr);
828833 info.fillInteger(*m_stream, gpr);
829834 returnFormat = DataFormatInteger;
830835 return gpr;

@@GPRReg SpeculativeJIT::fillSpeculateIntI
864869 // Check the value is an integer.
865870 GPRReg gpr = info.gpr();
866871 m_gprs.lock(gpr);
867  if (!isInt32Speculation(type))
868  speculationCheck(BadType, JSValueRegs(gpr), node, m_jit.branch64(MacroAssembler::Below, gpr, GPRInfo::tagTypeNumberRegister), direction);
 872 if (type & ~SpecInt32)
 873 speculationCheck(BadType, JSValueRegs(gpr), edge, m_jit.branch64(MacroAssembler::Below, gpr, GPRInfo::tagTypeNumberRegister), direction);
869874 info.fillJSValue(*m_stream, gpr, DataFormatJSInteger);
870875 // If !strict we're done, return.
871876 if (!strict) {

@@GPRReg SpeculativeJIT::fillSpeculateIntI
910915
911916 case DataFormatDouble:
912917 case DataFormatJSDouble: {
913  if (node->hasConstant() && isInt32Constant(node)) {
 918 if (edge->hasConstant() && isInt32Constant(edge.node())) {
914919 GPRReg gpr = allocate();
915  ASSERT(isInt32Constant(node));
916  m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(node)), gpr);
 920 ASSERT(isInt32Constant(edge.node()));
 921 m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(edge.node())), gpr);
917922 returnFormat = DataFormatInteger;
918923 return gpr;
919924 }

@@GPRReg SpeculativeJIT::fillSpeculateIntI
936941 }
937942}
938943
939 GPRReg SpeculativeJIT::fillSpeculateInt(Node* node, DataFormat& returnFormat, SpeculationDirection direction)
 944GPRReg SpeculativeJIT::fillSpeculateInt(Edge edge, DataFormat& returnFormat, SpeculationDirection direction)
940945{
941  return fillSpeculateIntInternal<false>(node, returnFormat, direction);
 946 return fillSpeculateIntInternal<false>(edge, returnFormat, direction);
942947}
943948
944 GPRReg SpeculativeJIT::fillSpeculateIntStrict(Node* node)
 949GPRReg SpeculativeJIT::fillSpeculateIntStrict(Edge edge)
945950{
946951 DataFormat mustBeDataFormatInteger;
947  GPRReg result = fillSpeculateIntInternal<true>(node, mustBeDataFormatInteger, BackwardSpeculation);
 952 GPRReg result = fillSpeculateIntInternal<true>(edge, mustBeDataFormatInteger, BackwardSpeculation);
948953 RELEASE_ASSERT(mustBeDataFormatInteger == DataFormatInteger);
949954 return result;
950955}
951956
952 FPRReg SpeculativeJIT::fillSpeculateDouble(Node* node, SpeculationDirection direction)
 957FPRReg SpeculativeJIT::fillSpeculateDouble(Edge edge, SpeculationDirection direction)
953958{
954959#if DFG_ENABLE(DEBUG_VERBOSE)
955  dataLogF("SpecDouble@%d ", node->index());
 960 dataLogF("SpecDouble@%d ", edge->index());
956961#endif
957  SpeculatedType type = m_state.forNode(node).m_type;
958  VirtualRegister virtualRegister = node->virtualRegister();
 962 AbstractValue& value = m_state.forNode(edge);
 963 SpeculatedType type = value.m_type;
 964 ASSERT(edge.useKind() != KnownNumberUse || !(value.m_type & ~SpecNumber));
 965 value.filter(SpecNumber);
 966 VirtualRegister virtualRegister = edge->virtualRegister();
959967 GenerationInfo& info = m_generationInfo[virtualRegister];
960968
961969 if (info.registerFormat() == DataFormatNone) {
962  if (node->hasConstant()) {
 970 if (edge->hasConstant()) {
963971 GPRReg gpr = allocate();
964972
965  if (isInt32Constant(node)) {
 973 if (isInt32Constant(edge.node())) {
966974 FPRReg fpr = fprAllocate();
967  m_jit.move(MacroAssembler::Imm64(reinterpretDoubleToInt64(static_cast<double>(valueOfInt32Constant(node)))), gpr);
 975 m_jit.move(MacroAssembler::Imm64(reinterpretDoubleToInt64(static_cast<double>(valueOfInt32Constant(edge.node())))), gpr);
968976 m_jit.move64ToDouble(gpr, fpr);
969977 unlock(gpr);
970978

@@FPRReg SpeculativeJIT::fillSpeculateDoub
972980 info.fillDouble(*m_stream, fpr);
973981 return fpr;
974982 }
975  if (isNumberConstant(node)) {
 983 if (isNumberConstant(edge.node())) {
976984 FPRReg fpr = fprAllocate();
977  m_jit.move(MacroAssembler::Imm64(reinterpretDoubleToInt64(valueOfNumberConstant(node))), gpr);
 985 m_jit.move(MacroAssembler::Imm64(reinterpretDoubleToInt64(valueOfNumberConstant(edge.node()))), gpr);
978986 m_jit.move64ToDouble(gpr, fpr);
979987 unlock(gpr);
980988

@@FPRReg SpeculativeJIT::fillSpeculateDoub
10381046
10391047 JITCompiler::Jump isInteger = m_jit.branch64(MacroAssembler::AboveOrEqual, jsValueGpr, GPRInfo::tagTypeNumberRegister);
10401048
1041  if (!isNumberSpeculation(type))
1042  speculationCheck(BadType, JSValueRegs(jsValueGpr), node, m_jit.branchTest64(MacroAssembler::Zero, jsValueGpr, GPRInfo::tagTypeNumberRegister), direction);
 1049 if (type & ~SpecNumber)
 1050 speculationCheck(BadType, JSValueRegs(jsValueGpr), edge, m_jit.branchTest64(MacroAssembler::Zero, jsValueGpr, GPRInfo::tagTypeNumberRegister), direction);
10431051
10441052 // First, if we get here we have a double encoded as a JSValue
10451053 m_jit.move(jsValueGpr, tempGpr);

@@FPRReg SpeculativeJIT::fillSpeculateDoub
11021110 }
11031111}
11041112
1105 GPRReg SpeculativeJIT::fillSpeculateCell(Node* node, SpeculationDirection direction)
 1113GPRReg SpeculativeJIT::fillSpeculateCell(Edge edge, SpeculationDirection direction)
11061114{
11071115#if DFG_ENABLE(DEBUG_VERBOSE)
1108  dataLogF("SpecCell@%d ", node->index());
 1116 dataLogF("SpecCell@%d ", edge->index());
11091117#endif
1110  SpeculatedType type = m_state.forNode(node).m_type;
1111  VirtualRegister virtualRegister = node->virtualRegister();
 1118 AbstractValue& value = m_state.forNode(edge);
 1119 SpeculatedType type = value.m_type;
 1120 ASSERT(edge.useKind() != KnownCellUse || !(value.m_type & ~SpecCell));
 1121 value.filter(SpecCell);
 1122 VirtualRegister virtualRegister = edge->virtualRegister();
11121123 GenerationInfo& info = m_generationInfo[virtualRegister];
11131124
11141125 switch (info.registerFormat()) {

@@GPRReg SpeculativeJIT::fillSpeculateCell
11201131
11211132 GPRReg gpr = allocate();
11221133
1123  if (node->hasConstant()) {
1124  JSValue jsValue = valueOfJSConstant(node);
 1134 if (edge->hasConstant()) {
 1135 JSValue jsValue = valueOfJSConstant(edge.node());
11251136 if (jsValue.isCell()) {
11261137 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
11271138 m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);

@@GPRReg SpeculativeJIT::fillSpeculateCell
11361147 m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
11371148
11381149 info.fillJSValue(*m_stream, gpr, DataFormatJS);
1139  if (!isCellSpeculation(type))
1140  speculationCheck(BadType, JSValueRegs(gpr), node, m_jit.branchTest64(MacroAssembler::NonZero, gpr, GPRInfo::tagMaskRegister), direction);
 1150 if (type & ~SpecCell)
 1151 speculationCheck(BadType, JSValueRegs(gpr), edge, m_jit.branchTest64(MacroAssembler::NonZero, gpr, GPRInfo::tagMaskRegister), direction);
11411152 info.fillJSValue(*m_stream, gpr, DataFormatJSCell);
11421153 return gpr;
11431154 }

@@GPRReg SpeculativeJIT::fillSpeculateCell
11521163 case DataFormatJS: {
11531164 GPRReg gpr = info.gpr();
11541165 m_gprs.lock(gpr);
1155  if (!isCellSpeculation(type))
1156  speculationCheck(BadType, JSValueRegs(gpr), node, m_jit.branchTest64(MacroAssembler::NonZero, gpr, GPRInfo::tagMaskRegister), direction);
 1166 if (type & ~SpecCell)
 1167 speculationCheck(BadType, JSValueRegs(gpr), edge, m_jit.branchTest64(MacroAssembler::NonZero, gpr, GPRInfo::tagMaskRegister), direction);
11571168 info.fillJSValue(*m_stream, gpr, DataFormatJSCell);
11581169 return gpr;
11591170 }

@@GPRReg SpeculativeJIT::fillSpeculateCell
11771188 }
11781189}
11791190
1180 GPRReg SpeculativeJIT::fillSpeculateBoolean(Node* node, SpeculationDirection direction)
 1191GPRReg SpeculativeJIT::fillSpeculateBoolean(Edge edge, SpeculationDirection direction)
11811192{
11821193#if DFG_ENABLE(DEBUG_VERBOSE)
1183  dataLogF("SpecBool@%d ", node->index());
 1194 dataLogF("SpecBool@%d ", edge->index());
11841195#endif
1185  SpeculatedType type = m_state.forNode(node).m_type;
1186  VirtualRegister virtualRegister = node->virtualRegister();
 1196 AbstractValue& value = m_state.forNode(edge);
 1197 SpeculatedType type = value.m_type;
 1198 value.filter(SpecBoolean);
 1199 VirtualRegister virtualRegister = edge->virtualRegister();
11871200 GenerationInfo& info = m_generationInfo[virtualRegister];
11881201
11891202 switch (info.registerFormat()) {

@@GPRReg SpeculativeJIT::fillSpeculateBool
11951208
11961209 GPRReg gpr = allocate();
11971210
1198  if (node->hasConstant()) {
1199  JSValue jsValue = valueOfJSConstant(node);
 1211 if (edge->hasConstant()) {
 1212 JSValue jsValue = valueOfJSConstant(edge.node());
12001213 if (jsValue.isBoolean()) {
12011214 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
12021215 m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);

@@GPRReg SpeculativeJIT::fillSpeculateBool
12111224 m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
12121225
12131226 info.fillJSValue(*m_stream, gpr, DataFormatJS);
1214  if (!isBooleanSpeculation(type)) {
 1227 if (type & ~SpecBoolean) {
12151228 m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr);
1216  speculationCheck(BadType, JSValueRegs(gpr), node, m_jit.branchTest64(MacroAssembler::NonZero, gpr, TrustedImm32(static_cast<int32_t>(~1))), SpeculationRecovery(BooleanSpeculationCheck, gpr, InvalidGPRReg), direction);
 1229 speculationCheck(BadType, JSValueRegs(gpr), edge, m_jit.branchTest64(MacroAssembler::NonZero, gpr, TrustedImm32(static_cast<int32_t>(~1))), SpeculationRecovery(BooleanSpeculationCheck, gpr, InvalidGPRReg), direction);
12171230 m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr);
12181231 }
12191232 info.fillJSValue(*m_stream, gpr, DataFormatJSBoolean);

@@GPRReg SpeculativeJIT::fillSpeculateBool
12301243 case DataFormatJS: {
12311244 GPRReg gpr = info.gpr();
12321245 m_gprs.lock(gpr);
1233  if (!isBooleanSpeculation(type)) {
 1246 if (type & ~SpecBoolean) {
12341247 m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr);
1235  speculationCheck(BadType, JSValueRegs(gpr), node, m_jit.branchTest64(MacroAssembler::NonZero, gpr, TrustedImm32(static_cast<int32_t>(~1))), SpeculationRecovery(BooleanSpeculationCheck, gpr, InvalidGPRReg), direction);
 1248 speculationCheck(BadType, JSValueRegs(gpr), edge, m_jit.branchTest64(MacroAssembler::NonZero, gpr, TrustedImm32(static_cast<int32_t>(~1))), SpeculationRecovery(BooleanSpeculationCheck, gpr, InvalidGPRReg), direction);
12361249 m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr);
12371250 }
12381251 info.fillJSValue(*m_stream, gpr, DataFormatJSBoolean);

@@void SpeculativeJIT::compileObjectEquali
12901303
12911304 if (m_jit.graph().globalObjectFor(node->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
12921305 m_jit.graph().globalObjectFor(node->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
1293  if (m_state.forNode(node->child1()).m_type & ~SpecObject) {
1294  speculationCheck(
1295  BadType, JSValueSource::unboxedCell(op1GPR), node->child1(),
1296  m_jit.branchPtr(
1297  MacroAssembler::Equal,
1298  MacroAssembler::Address(op1GPR, JSCell::structureOffset()),
1299  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1300  }
1301  if (m_state.forNode(node->child2()).m_type & ~SpecObject) {
1302  speculationCheck(
1303  BadType, JSValueSource::unboxedCell(op2GPR), node->child2(),
1304  m_jit.branchPtr(
1305  MacroAssembler::Equal,
1306  MacroAssembler::Address(op2GPR, JSCell::structureOffset()),
1307  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1308  }
 1306 DFG_TYPE_CHECK(
 1307 JSValueSource::unboxedCell(op1GPR), node->child1(), SpecObject, m_jit.branchPtr(
 1308 MacroAssembler::Equal,
 1309 MacroAssembler::Address(op1GPR, JSCell::structureOffset()),
 1310 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
 1311 DFG_TYPE_CHECK(
 1312 JSValueSource::unboxedCell(op2GPR), node->child2(), SpecObject, m_jit.branchPtr(
 1313 MacroAssembler::Equal,
 1314 MacroAssembler::Address(op2GPR, JSCell::structureOffset()),
 1315 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
13091316 } else {
13101317 GPRTemporary structure(this);
13111318 GPRReg structureGPR = structure.gpr();
13121319
13131320 m_jit.loadPtr(MacroAssembler::Address(op1GPR, JSCell::structureOffset()), structureGPR);
1314  if (m_state.forNode(node->child1()).m_type & ~SpecObject) {
1315  speculationCheck(
1316  BadType, JSValueSource::unboxedCell(op1GPR), node->child1(),
1317  m_jit.branchPtr(
1318  MacroAssembler::Equal,
1319  structureGPR,
1320  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1321  }
 1321 DFG_TYPE_CHECK(
 1322 JSValueSource::unboxedCell(op1GPR), node->child1(), SpecObject, m_jit.branchPtr(
 1323 MacroAssembler::Equal,
 1324 structureGPR,
 1325 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
13221326 speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), node->child1(),
13231327 m_jit.branchTest8(
13241328 MacroAssembler::NonZero,

@@void SpeculativeJIT::compileObjectEquali
13261330 MacroAssembler::TrustedImm32(MasqueradesAsUndefined)));
13271331
13281332 m_jit.loadPtr(MacroAssembler::Address(op2GPR, JSCell::structureOffset()), structureGPR);
1329  if (m_state.forNode(node->child2()).m_type & ~SpecObject) {
1330  speculationCheck(
1331  BadType, JSValueSource::unboxedCell(op2GPR), node->child2(),
1332  m_jit.branchPtr(
1333  MacroAssembler::Equal,
1334  structureGPR,
1335  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1336  }
 1333 DFG_TYPE_CHECK(
 1334 JSValueSource::unboxedCell(op2GPR), node->child2(), SpecObject, m_jit.branchPtr(
 1335 MacroAssembler::Equal,
 1336 structureGPR,
 1337 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
13371338 speculationCheck(BadType, JSValueSource::unboxedCell(op2GPR), node->child2(),
13381339 m_jit.branchTest8(
13391340 MacroAssembler::NonZero,

@@void SpeculativeJIT::compileObjectEquali
13541355void SpeculativeJIT::compileObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild)
13551356{
13561357 SpeculateCellOperand op1(this, leftChild);
1357  JSValueOperand op2(this, rightChild);
 1358 JSValueOperand op2(this, rightChild, ManualOperandSpeculation);
13581359 GPRTemporary result(this);
13591360
13601361 GPRReg op1GPR = op1.gpr();

@@void SpeculativeJIT::compileObjectToObje
13631364
13641365 if (m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
13651366 m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
1366  if (m_state.forNode(leftChild).m_type & ~SpecObject) {
1367  speculationCheck(
1368  BadType, JSValueSource::unboxedCell(op1GPR), leftChild,
1369  m_jit.branchPtr(
1370  MacroAssembler::Equal,
1371  MacroAssembler::Address(op1GPR, JSCell::structureOffset()),
1372  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1373  }
 1367 DFG_TYPE_CHECK(
 1368 JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchPtr(
 1369 MacroAssembler::Equal,
 1370 MacroAssembler::Address(op1GPR, JSCell::structureOffset()),
 1371 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
13741372 } else {
13751373 GPRTemporary structure(this);
13761374 GPRReg structureGPR = structure.gpr();
13771375
13781376 m_jit.loadPtr(MacroAssembler::Address(op1GPR, JSCell::structureOffset()), structureGPR);
1379  if (m_state.forNode(leftChild).m_type & ~SpecObject) {
1380  speculationCheck(
1381  BadType, JSValueSource::unboxedCell(op1GPR), leftChild,
1382  m_jit.branchPtr(
1383  MacroAssembler::Equal,
1384  structureGPR,
1385  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1386  }
 1377 DFG_TYPE_CHECK(
 1378 JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchPtr(
 1379 MacroAssembler::Equal,
 1380 structureGPR,
 1381 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
13871382 speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), leftChild,
13881383 m_jit.branchTest8(
13891384 MacroAssembler::NonZero,

@@void SpeculativeJIT::compileObjectToObje
13991394 // We know that within this branch, rightChild must be a cell.
14001395 if (m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
14011396 m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
1402  if ((m_state.forNode(rightChild).m_type & SpecCell) & ~SpecObject) {
1403  speculationCheck(
1404  BadType, JSValueRegs(op2GPR), rightChild,
1405  m_jit.branchPtr(
1406  MacroAssembler::Equal,
1407  MacroAssembler::Address(op2GPR, JSCell::structureOffset()),
1408  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1409  }
 1397 DFG_TYPE_CHECK(
 1398 JSValueRegs(op2GPR), rightChild, (~SpecCell) | SpecObject, m_jit.branchPtr(
 1399 MacroAssembler::Equal,
 1400 MacroAssembler::Address(op2GPR, JSCell::structureOffset()),
 1401 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
14101402 } else {
14111403 GPRTemporary structure(this);
14121404 GPRReg structureGPR = structure.gpr();
14131405
14141406 m_jit.loadPtr(MacroAssembler::Address(op2GPR, JSCell::structureOffset()), structureGPR);
1415  if ((m_state.forNode(rightChild).m_type & SpecCell) & ~SpecObject) {
1416  speculationCheck(
1417  BadType, JSValueRegs(op2GPR), rightChild,
1418  m_jit.branchPtr(
1419  MacroAssembler::Equal,
1420  structureGPR,
1421  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1422  }
 1407 DFG_TYPE_CHECK(
 1408 JSValueRegs(op2GPR), rightChild, (~SpecCell) | SpecObject, m_jit.branchPtr(
 1409 MacroAssembler::Equal,
 1410 structureGPR,
 1411 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
14231412 speculationCheck(BadType, JSValueRegs(op2GPR), rightChild,
14241413 m_jit.branchTest8(
14251414 MacroAssembler::NonZero,

@@void SpeculativeJIT::compileObjectToObje
14371426
14381427 // We know that within this branch, rightChild must not be a cell. Check if that is enough to
14391428 // prove that it is either null or undefined.
1440  if ((m_state.forNode(rightChild).m_type & ~SpecCell) & ~SpecOther) {
 1429 if (needsTypeCheck(rightChild, SpecCell | SpecOther)) {
14411430 m_jit.move(op2GPR, resultGPR);
14421431 m_jit.and64(MacroAssembler::TrustedImm32(~TagBitUndefined), resultGPR);
14431432
1444  speculationCheck(
1445  BadType, JSValueRegs(op2GPR), rightChild.node(),
 1433 typeCheck(
 1434 JSValueRegs(op2GPR), rightChild, SpecCell | SpecOther,
14461435 m_jit.branch64(
14471436 MacroAssembler::NotEqual, resultGPR,
14481437 MacroAssembler::TrustedImm64(ValueNull)));

@@void SpeculativeJIT::compilePeepHoleObje
14641453 BlockIndex notTaken = branchNode->notTakenBlockIndex();
14651454
14661455 SpeculateCellOperand op1(this, leftChild);
1467  JSValueOperand op2(this, rightChild);
 1456 JSValueOperand op2(this, rightChild, ManualOperandSpeculation);
14681457 GPRTemporary result(this);
14691458
14701459 GPRReg op1GPR = op1.gpr();

@@void SpeculativeJIT::compilePeepHoleObje
14731462
14741463 if (m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
14751464 m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
1476  if (m_state.forNode(leftChild).m_type & ~SpecObject) {
1477  speculationCheck(
1478  BadType, JSValueSource::unboxedCell(op1GPR), leftChild,
1479  m_jit.branchPtr(
1480  MacroAssembler::Equal,
1481  MacroAssembler::Address(op1GPR, JSCell::structureOffset()),
1482  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1483  }
 1465 DFG_TYPE_CHECK(
 1466 JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchPtr(
 1467 MacroAssembler::Equal,
 1468 MacroAssembler::Address(op1GPR, JSCell::structureOffset()),
 1469 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
14841470 } else {
14851471 GPRTemporary structure(this);
14861472 GPRReg structureGPR = structure.gpr();
14871473
14881474 m_jit.loadPtr(MacroAssembler::Address(op1GPR, JSCell::structureOffset()), structureGPR);
1489  if (m_state.forNode(leftChild).m_type & ~SpecObject) {
1490  speculationCheck(
1491  BadType, JSValueSource::unboxedCell(op1GPR), leftChild,
1492  m_jit.branchPtr(
1493  MacroAssembler::Equal,
1494  structureGPR,
1495  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1496  }
 1475 DFG_TYPE_CHECK(
 1476 JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchPtr(
 1477 MacroAssembler::Equal,
 1478 structureGPR,
 1479 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
14971480 speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), leftChild,
14981481 m_jit.branchTest8(
14991482 MacroAssembler::NonZero,

@@void SpeculativeJIT::compilePeepHoleObje
15091492 // We know that within this branch, rightChild must be a cell.
15101493 if (m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
15111494 m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
1512  if ((m_state.forNode(rightChild).m_type & SpecCell) & ~SpecObject) {
1513  speculationCheck(
1514  BadType, JSValueRegs(op2GPR), rightChild,
1515  m_jit.branchPtr(
1516  MacroAssembler::Equal,
1517  MacroAssembler::Address(op2GPR, JSCell::structureOffset()),
1518  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1519  }
 1495 DFG_TYPE_CHECK(
 1496 JSValueRegs(op2GPR), rightChild, (~SpecCell) | SpecObject, m_jit.branchPtr(
 1497 MacroAssembler::Equal,
 1498 MacroAssembler::Address(op2GPR, JSCell::structureOffset()),
 1499 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
15201500 } else {
15211501 GPRTemporary structure(this);
15221502 GPRReg structureGPR = structure.gpr();
15231503
15241504 m_jit.loadPtr(MacroAssembler::Address(op2GPR, JSCell::structureOffset()), structureGPR);
1525  if ((m_state.forNode(rightChild).m_type & SpecCell) & ~SpecObject) {
1526  speculationCheck(
1527  BadType, JSValueRegs(op2GPR), rightChild,
1528  m_jit.branchPtr(
1529  MacroAssembler::Equal,
1530  structureGPR,
1531  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1532  }
 1505 DFG_TYPE_CHECK(
 1506 JSValueRegs(op2GPR), rightChild, (~SpecCell) | SpecObject, m_jit.branchPtr(
 1507 MacroAssembler::Equal,
 1508 structureGPR,
 1509 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
15331510 speculationCheck(BadType, JSValueRegs(op2GPR), rightChild,
15341511 m_jit.branchTest8(
15351512 MacroAssembler::NonZero,

@@void SpeculativeJIT::compilePeepHoleObje
15441521
15451522 // We know that within this branch, rightChild must not be a cell. Check if that is enough to
15461523 // prove that it is either null or undefined.
1547  if ((m_state.forNode(rightChild).m_type & ~SpecCell) & ~SpecOther)
 1524 if (!needsTypeCheck(rightChild, SpecCell | SpecOther))
15481525 rightNotCell.link(&m_jit);
15491526 else {
15501527 jump(notTaken, ForceJump);

@@void SpeculativeJIT::compilePeepHoleObje
15531530 m_jit.move(op2GPR, resultGPR);
15541531 m_jit.and64(MacroAssembler::TrustedImm32(~TagBitUndefined), resultGPR);
15551532
1556  speculationCheck(
1557  BadType, JSValueRegs(op2GPR), rightChild,
1558  m_jit.branch64(
 1533 typeCheck(
 1534 JSValueRegs(op2GPR), rightChild, SpecCell | SpecOther, m_jit.branch64(
15591535 MacroAssembler::NotEqual, resultGPR,
15601536 MacroAssembler::TrustedImm64(ValueNull)));
15611537 }

@@void SpeculativeJIT::compileValueAdd(Nod
16091585 jsValueResult(result.gpr(), node);
16101586}
16111587
1612 void SpeculativeJIT::compileObjectOrOtherLogicalNot(Edge nodeUse, bool needSpeculationCheck)
 1588void SpeculativeJIT::compileObjectOrOtherLogicalNot(Edge nodeUse)
16131589{
1614  JSValueOperand value(this, nodeUse);
 1590 JSValueOperand value(this, nodeUse, ManualOperandSpeculation);
16151591 GPRTemporary result(this);
16161592 GPRReg valueGPR = value.gpr();
16171593 GPRReg resultGPR = result.gpr();

@@void SpeculativeJIT::compileObjectOrOthe
16191595 MacroAssembler::Jump notCell = m_jit.branchTest64(MacroAssembler::NonZero, valueGPR, GPRInfo::tagMaskRegister);
16201596 if (m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
16211597 m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
1622 
1623  if (needSpeculationCheck) {
1624  speculationCheck(BadType, JSValueRegs(valueGPR), nodeUse,
1625  m_jit.branchPtr(
1626  MacroAssembler::Equal,
1627  MacroAssembler::Address(valueGPR, JSCell::structureOffset()),
1628  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1629  }
 1598 DFG_TYPE_CHECK(
 1599 JSValueRegs(valueGPR), nodeUse, (~SpecCell) | SpecObject, m_jit.branchPtr(
 1600 MacroAssembler::Equal,
 1601 MacroAssembler::Address(valueGPR, JSCell::structureOffset()),
 1602 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
16301603 } else {
16311604 GPRTemporary structure(this);
16321605 GPRReg structureGPR = structure.gpr();
16331606
16341607 m_jit.loadPtr(MacroAssembler::Address(valueGPR, JSCell::structureOffset()), structureGPR);
16351608
1636  if (needSpeculationCheck) {
1637  speculationCheck(BadType, JSValueRegs(valueGPR), nodeUse,
1638  m_jit.branchPtr(
1639  MacroAssembler::Equal,
1640  structureGPR,
1641  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1642  }
 1609 DFG_TYPE_CHECK(
 1610 JSValueRegs(valueGPR), nodeUse, (~SpecCell) | SpecObject, m_jit.branchPtr(
 1611 MacroAssembler::Equal,
 1612 structureGPR,
 1613 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
16431614
16441615 MacroAssembler::Jump isNotMasqueradesAsUndefined =
16451616 m_jit.branchTest8(

@@void SpeculativeJIT::compileObjectOrOthe
16601631
16611632 notCell.link(&m_jit);
16621633
1663  if (needSpeculationCheck) {
 1634 if (needsTypeCheck(nodeUse, SpecCell | SpecOther)) {
16641635 m_jit.move(valueGPR, resultGPR);
16651636 m_jit.and64(MacroAssembler::TrustedImm32(~TagBitUndefined), resultGPR);
1666  speculationCheck(BadType, JSValueRegs(valueGPR), nodeUse,
1667  m_jit.branch64(
 1637 typeCheck(
 1638 JSValueRegs(valueGPR), nodeUse, SpecCell | SpecOther, m_jit.branch64(
16681639 MacroAssembler::NotEqual,
16691640 resultGPR,
16701641 MacroAssembler::TrustedImm64(ValueNull)));

@@void SpeculativeJIT::compileObjectOrOthe
16781649
16791650void SpeculativeJIT::compileLogicalNot(Node* node)
16801651{
1681  if (node->child1()->shouldSpeculateObjectOrOther()) {
1682  compileObjectOrOtherLogicalNot(node->child1(),
1683  !isObjectOrOtherSpeculation(m_state.forNode(node->child1()).m_type));
 1652 switch (node->child1().useKind()) {
 1653 case ObjectOrOtherUse: {
 1654 compileObjectOrOtherLogicalNot(node->child1());
16841655 return;
16851656 }
1686  if (node->child1()->shouldSpeculateInteger()) {
 1657
 1658 case Int32Use: {
16871659 SpeculateIntegerOperand value(this, node->child1());
16881660 GPRTemporary result(this, value);
16891661 m_jit.compare32(MacroAssembler::Equal, value.gpr(), MacroAssembler::TrustedImm32(0), result.gpr());

@@void SpeculativeJIT::compileLogicalNot(N
16911663 jsValueResult(result.gpr(), node, DataFormatJSBoolean);
16921664 return;
16931665 }
1694  if (node->child1()->shouldSpeculateNumber()) {
 1666
 1667 case NumberUse: {
16951668 SpeculateDoubleOperand value(this, node->child1());
16961669 FPRTemporary scratch(this);
16971670 GPRTemporary result(this);

@@void SpeculativeJIT::compileLogicalNot(N
17031676 return;
17041677 }
17051678
1706  SpeculatedType prediction = node->child1()->prediction();
1707  if (isBooleanSpeculation(prediction)) {
1708  if (isBooleanSpeculation(m_state.forNode(node->child1()).m_type)) {
 1679 case BooleanUse: {
 1680 if (!needsTypeCheck(node->child1(), SpecBoolean)) {
17091681 SpeculateBooleanOperand value(this, node->child1());
17101682 GPRTemporary result(this, value);
17111683

@@void SpeculativeJIT::compileLogicalNot(N
17161688 return;
17171689 }
17181690
1719  JSValueOperand value(this, node->child1());
 1691 JSValueOperand value(this, node->child1(), ManualOperandSpeculation);
17201692 GPRTemporary result(this); // FIXME: We could reuse, but on speculation fail would need recovery to restore tag (akin to add).
17211693
17221694 m_jit.move(value.gpr(), result.gpr());
17231695 m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), result.gpr());
1724  speculationCheck(BadType, JSValueRegs(value.gpr()), node->child1(), m_jit.branchTest64(JITCompiler::NonZero, result.gpr(), TrustedImm32(static_cast<int32_t>(~1))));
 1696 typeCheck(
 1697 JSValueRegs(value.gpr()), node->child1(), SpecBoolean, m_jit.branchTest64(
 1698 JITCompiler::NonZero, result.gpr(), TrustedImm32(static_cast<int32_t>(~1))));
17251699 m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueTrue)), result.gpr());
17261700
17271701 // If we add a DataFormatBool, we should use it here.
17281702 jsValueResult(result.gpr(), node, DataFormatJSBoolean);
17291703 return;
17301704 }
 1705
 1706 case UntypedUse: {
 1707 JSValueOperand arg1(this, node->child1());
 1708 GPRTemporary result(this);
17311709
1732  JSValueOperand arg1(this, node->child1());
1733  GPRTemporary result(this);
1734 
1735  GPRReg arg1GPR = arg1.gpr();
1736  GPRReg resultGPR = result.gpr();
 1710 GPRReg arg1GPR = arg1.gpr();
 1711 GPRReg resultGPR = result.gpr();
17371712
1738  arg1.use();
 1713 arg1.use();
17391714
1740  m_jit.move(arg1GPR, resultGPR);
1741  m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), resultGPR);
1742  JITCompiler::Jump slowCase = m_jit.branchTest64(JITCompiler::NonZero, resultGPR, TrustedImm32(static_cast<int32_t>(~1)));
 1715 m_jit.move(arg1GPR, resultGPR);
 1716 m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), resultGPR);
 1717 JITCompiler::Jump slowCase = m_jit.branchTest64(JITCompiler::NonZero, resultGPR, TrustedImm32(static_cast<int32_t>(~1)));
17431718
1744  addSlowPathGenerator(
1745  slowPathCall(slowCase, this, dfgConvertJSValueToBoolean, resultGPR, arg1GPR));
 1719 addSlowPathGenerator(
 1720 slowPathCall(slowCase, this, dfgConvertJSValueToBoolean, resultGPR, arg1GPR));
17461721
1747  m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueTrue)), resultGPR);
1748  jsValueResult(resultGPR, node, DataFormatJSBoolean, UseChildrenCalledExplicitly);
 1722 m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueTrue)), resultGPR);
 1723 jsValueResult(resultGPR, node, DataFormatJSBoolean, UseChildrenCalledExplicitly);
 1724 return;
 1725 }
 1726
 1727 default:
 1728 RELEASE_ASSERT_NOT_REACHED();
 1729 break;
 1730 }
17491731}
17501732
1751 void SpeculativeJIT::emitObjectOrOtherBranch(Edge nodeUse, BlockIndex taken, BlockIndex notTaken, bool needSpeculationCheck)
 1733void SpeculativeJIT::emitObjectOrOtherBranch(Edge nodeUse, BlockIndex taken, BlockIndex notTaken)
17521734{
1753  JSValueOperand value(this, nodeUse);
 1735 JSValueOperand value(this, nodeUse, ManualOperandSpeculation);
17541736 GPRTemporary scratch(this);
17551737 GPRReg valueGPR = value.gpr();
17561738 GPRReg scratchGPR = scratch.gpr();

@@void SpeculativeJIT::emitObjectOrOtherBr
17591741 if (m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
17601742 m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
17611743
1762  if (needSpeculationCheck) {
1763  speculationCheck(BadType, JSValueRegs(valueGPR), nodeUse,
1764  m_jit.branchPtr(
1765  MacroAssembler::Equal,
1766  MacroAssembler::Address(valueGPR, JSCell::structureOffset()),
1767  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1768  }
 1744 DFG_TYPE_CHECK(
 1745 JSValueRegs(valueGPR), nodeUse, (~SpecCell) | SpecObject, m_jit.branchPtr(
 1746 MacroAssembler::Equal,
 1747 MacroAssembler::Address(valueGPR, JSCell::structureOffset()),
 1748 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
17691749 } else {
17701750 m_jit.loadPtr(MacroAssembler::Address(valueGPR, JSCell::structureOffset()), scratchGPR);
17711751
1772  if (needSpeculationCheck) {
1773  speculationCheck(BadType, JSValueRegs(valueGPR), nodeUse,
1774  m_jit.branchPtr(
1775  MacroAssembler::Equal,
1776  scratchGPR,
1777  MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
1778  }
 1752 DFG_TYPE_CHECK(
 1753 JSValueRegs(valueGPR), nodeUse, (~SpecCell) | SpecObject, m_jit.branchPtr(
 1754 MacroAssembler::Equal,
 1755 scratchGPR,
 1756 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
17791757
17801758 JITCompiler::Jump isNotMasqueradesAsUndefined = m_jit.branchTest8(JITCompiler::Zero, MacroAssembler::Address(scratchGPR, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined));
17811759

@@void SpeculativeJIT::emitObjectOrOtherBr
17911769
17921770 notCell.link(&m_jit);
17931771
1794  if (needSpeculationCheck) {
 1772 if (needsTypeCheck(nodeUse, SpecCell | SpecOther)) {
17951773 m_jit.move(valueGPR, scratchGPR);
17961774 m_jit.and64(MacroAssembler::TrustedImm32(~TagBitUndefined), scratchGPR);
1797  speculationCheck(BadType, JSValueRegs(valueGPR), nodeUse, m_jit.branch64(MacroAssembler::NotEqual, scratchGPR, MacroAssembler::TrustedImm64(ValueNull)));
 1775 typeCheck(
 1776 JSValueRegs(valueGPR), nodeUse, SpecCell | SpecOther, m_jit.branch64(
 1777 MacroAssembler::NotEqual, scratchGPR, MacroAssembler::TrustedImm64(ValueNull)));
17981778 }
17991779 jump(notTaken);
18001780

@@void SpeculativeJIT::emitBranch(Node* no
18061786 BlockIndex taken = node->takenBlockIndex();
18071787 BlockIndex notTaken = node->notTakenBlockIndex();
18081788
1809  if (node->child1()->shouldSpeculateObjectOrOther()) {
1810  emitObjectOrOtherBranch(node->child1(), taken, notTaken,
1811  !isObjectOrOtherSpeculation(m_state.forNode(node->child1()).m_type));
 1789 switch (node->child1().useKind()) {
 1790 case ObjectOrOtherUse: {
 1791 emitObjectOrOtherBranch(node->child1(), taken, notTaken);
18121792 return;
18131793 }
1814 
1815  if (node->child1()->shouldSpeculateNumber()) {
1816  if (node->child1()->shouldSpeculateInteger()) {
 1794
 1795 case Int32Use:
 1796 case NumberUse: {
 1797 if (node->child1().useKind() == Int32Use) {
18171798 bool invert = false;
18181799
18191800 if (taken == nextBlock()) {

@@void SpeculativeJIT::emitBranch(Node* no
18371818 return;
18381819 }
18391820
1840  JSValueOperand value(this, node->child1());
1841  GPRReg valueGPR = value.gpr();
 1821 case UntypedUse:
 1822 case BooleanUse: {
 1823 JSValueOperand value(this, node->child1(), ManualOperandSpeculation);
 1824 GPRReg valueGPR = value.gpr();
18421825
1843  bool predictBoolean = isBooleanSpeculation(node->child1()->prediction());
1844 
1845  if (predictBoolean) {
1846  if (isBooleanSpeculation(m_state.forNode(node->child1()).m_type)) {
1847  MacroAssembler::ResultCondition condition = MacroAssembler::NonZero;
 1826 if (node->child1().useKind() == BooleanUse) {
 1827 if (!needsTypeCheck(node->child1(), SpecBoolean)) {
 1828 MacroAssembler::ResultCondition condition = MacroAssembler::NonZero;
18481829
1849  if (taken == nextBlock()) {
1850  condition = MacroAssembler::Zero;
1851  BlockIndex tmp = taken;
1852  taken = notTaken;
1853  notTaken = tmp;
1854  }
 1830 if (taken == nextBlock()) {
 1831 condition = MacroAssembler::Zero;
 1832 BlockIndex tmp = taken;
 1833 taken = notTaken;
 1834 notTaken = tmp;
 1835 }
18551836
1856  branchTest32(condition, valueGPR, TrustedImm32(true), taken);
1857  jump(notTaken);
1858  } else {
1859  branch64(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImm64(JSValue::encode(jsBoolean(false))), notTaken);
1860  branch64(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImm64(JSValue::encode(jsBoolean(true))), taken);
 1837 branchTest32(condition, valueGPR, TrustedImm32(true), taken);
 1838 jump(notTaken);
 1839 } else {
 1840 branch64(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImm64(JSValue::encode(jsBoolean(false))), notTaken);
 1841 branch64(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImm64(JSValue::encode(jsBoolean(true))), taken);
18611842
1862  speculationCheck(BadType, JSValueRegs(valueGPR), node->child1(), m_jit.jump());
1863  }
1864  value.use();
1865  } else {
1866  GPRTemporary result(this);
1867  GPRReg resultGPR = result.gpr();
1868 
1869  if (node->child1()->prediction() & SpecInt32) {
1870  branch64(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(0))), notTaken);
1871  branch64(MacroAssembler::AboveOrEqual, valueGPR, GPRInfo::tagTypeNumberRegister, taken);
1872  }
 1843 typeCheck(JSValueRegs(valueGPR), node->child1(), SpecBoolean, m_jit.jump());
 1844 }
 1845 value.use();
 1846 } else {
 1847 GPRTemporary result(this);
 1848 GPRReg resultGPR = result.gpr();
 1849
 1850 if (node->child1()->prediction() & SpecInt32) {
 1851 branch64(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(0))), notTaken);
 1852 branch64(MacroAssembler::AboveOrEqual, valueGPR, GPRInfo::tagTypeNumberRegister, taken);
 1853 }
18731854
1874  if (node->child1()->prediction() & SpecBoolean) {
1875  branch64(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImm64(JSValue::encode(jsBoolean(false))), notTaken);
1876  branch64(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImm64(JSValue::encode(jsBoolean(true))), taken);
1877  }
 1855 if (node->child1()->prediction() & SpecBoolean) {
 1856 branch64(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImm64(JSValue::encode(jsBoolean(false))), notTaken);
 1857 branch64(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImm64(JSValue::encode(jsBoolean(true))), taken);
 1858 }
18781859
1879  value.use();
 1860 value.use();
18801861
1881  silentSpillAllRegisters(resultGPR);
1882  callOperation(dfgConvertJSValueToBoolean, resultGPR, valueGPR);
1883  silentFillAllRegisters(resultGPR);
 1862 silentSpillAllRegisters(resultGPR);
 1863 callOperation(dfgConvertJSValueToBoolean, resultGPR, valueGPR);
 1864 silentFillAllRegisters(resultGPR);
18841865
1885  branchTest32(MacroAssembler::NonZero, resultGPR, taken);
1886  jump(notTaken);
 1866 branchTest32(MacroAssembler::NonZero, resultGPR, taken);
 1867 jump(notTaken);
 1868 }
 1869
 1870 noResult(node, UseChildrenCalledExplicitly);
 1871 return;
18871872 }
18881873
1889  noResult(node, UseChildrenCalledExplicitly);
 1874 default:
 1875 RELEASE_ASSERT_NOT_REACHED();
 1876 }
18901877}
18911878
18921879void SpeculativeJIT::compile(Node* node)

@@void SpeculativeJIT::compile(Node* node)
19081895 break;
19091896
19101897 case Identity: {
1911  // This could be done a lot better. We take the cheap way out because Identity
1912  // is only going to stick around after CSE if we had prediction weirdness.
1913  JSValueOperand operand(this, node->child1());
1914  GPRTemporary result(this, operand);
1915  m_jit.move(operand.gpr(), result.gpr());
1916  jsValueResult(result.gpr(), node);
 1898 // CSE should always eliminate this.
 1899 RELEASE_ASSERT_NOT_REACHED();
19171900 break;
19181901 }
19191902

@@void SpeculativeJIT::compile(Node* node)
19311914 // If the CFA is tracking this variable and it found that the variable
19321915 // cannot have been assigned, then don't attempt to proceed.
19331916 if (value.isClear()) {
 1917 // FIXME: We should trap instead.
 1918 // https://bugs.webkit.org/show_bug.cgi?id=110383
19341919 terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
19351920 break;
19361921 }

@@void SpeculativeJIT::compile(Node* node)
21312116 break;
21322117 }
21332118
2134  case CheckNumber: {
2135  if (!isNumberSpeculation(m_state.forNode(node->child1()).m_type)) {
2136  JSValueOperand op1(this, node->child1());
2137  JITCompiler::Jump isInteger = m_jit.branch64(MacroAssembler::AboveOrEqual, op1.gpr(), GPRInfo::tagTypeNumberRegister);
2138  speculationCheck(
2139  BadType, JSValueRegs(op1.gpr()), node->child1().node(),
2140  m_jit.branchTest64(MacroAssembler::Zero, op1.gpr(), GPRInfo::tagTypeNumberRegister));
2141  isInteger.link(&m_jit);
2142  }
2143  noResult(node);
2144  break;
2145  }
2146 
21472119 case ValueAdd:
21482120 case ArithAdd:
21492121 compileAdd(node);

@@void SpeculativeJIT::compile(Node* node)
21622134 break;
21632135
21642136 case ArithDiv: {
2165  if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node())
2166  && node->canSpeculateInteger()) {
 2137 switch (node->binaryUseKind()) {
 2138 case Int32Use: {
21672139 compileIntegerArithDivForX86(node);
21682140 break;
21692141 }
2170 
2171  SpeculateDoubleOperand op1(this, node->child1());
2172  SpeculateDoubleOperand op2(this, node->child2());
2173  FPRTemporary result(this, op1);
2174 
2175  FPRReg reg1 = op1.fpr();
2176  FPRReg reg2 = op2.fpr();
2177  m_jit.divDouble(reg1, reg2, result.fpr());
2178 
2179  doubleResult(result.fpr(), node);
 2142
 2143 case NumberUse: {
 2144 SpeculateDoubleOperand op1(this, node->child1());
 2145 SpeculateDoubleOperand op2(this, node->child2());
 2146 FPRTemporary result(this, op1);
 2147
 2148 FPRReg reg1 = op1.fpr();
 2149 FPRReg reg2 = op2.fpr();
 2150 m_jit.divDouble(reg1, reg2, result.fpr());
 2151
 2152 doubleResult(result.fpr(), node);
 2153 break;
 2154 }
 2155
 2156 default:
 2157 RELEASE_ASSERT_NOT_REACHED();
 2158 break;
 2159 }
21802160 break;
21812161 }
21822162

@@void SpeculativeJIT::compile(Node* node)
21862166 }
21872167
21882168 case ArithAbs: {
2189  if (node->child1()->shouldSpeculateIntegerForArithmetic()
2190  && node->canSpeculateInteger()) {
 2169 switch (node->child1().useKind()) {
 2170 case Int32Use: {
21912171 SpeculateIntegerOperand op1(this, node->child1());
21922172 GPRTemporary result(this);
21932173 GPRTemporary scratch(this);

@@void SpeculativeJIT::compile(Node* node)
22012181 break;
22022182 }
22032183
2204  SpeculateDoubleOperand op1(this, node->child1());
2205  FPRTemporary result(this);
2206 
2207  m_jit.absDouble(op1.fpr(), result.fpr());
2208  doubleResult(result.fpr(), node);
 2184 case NumberUse: {
 2185 SpeculateDoubleOperand op1(this, node->child1());
 2186 FPRTemporary result(this);
 2187
 2188 m_jit.absDouble(op1.fpr(), result.fpr());
 2189 doubleResult(result.fpr(), node);
 2190 break;
 2191 }
 2192
 2193 default:
 2194 RELEASE_ASSERT_NOT_REACHED();
 2195 break;
 2196 }
22092197 break;
22102198 }
22112199
22122200 case ArithMin:
22132201 case ArithMax: {
2214  if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node())
2215  && node->canSpeculateInteger()) {
 2202 switch (node->binaryUseKind()) {
 2203 case Int32Use: {
22162204 SpeculateStrictInt32Operand op1(this, node->child1());
22172205 SpeculateStrictInt32Operand op2(this, node->child2());
22182206 GPRTemporary result(this, op1);

@@void SpeculativeJIT::compile(Node* node)
22312219 break;
22322220 }
22332221
2234  SpeculateDoubleOperand op1(this, node->child1());
2235  SpeculateDoubleOperand op2(this, node->child2());
2236  FPRTemporary result(this, op1);
 2222 case NumberUse: {
 2223 SpeculateDoubleOperand op1(this, node->child1());
 2224 SpeculateDoubleOperand op2(this, node->child2());
 2225 FPRTemporary result(this, op1);
22372226
2238  MacroAssembler::JumpList done;
 2227 MacroAssembler::JumpList done;
22392228
2240  MacroAssembler::Jump op1Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleLessThan : MacroAssembler::DoubleGreaterThan, op1.fpr(), op2.fpr());
 2229 MacroAssembler::Jump op1Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleLessThan : MacroAssembler::DoubleGreaterThan, op1.fpr(), op2.fpr());
22412230
2242  // op2 is eather the lesser one or one of then is NaN
2243  MacroAssembler::Jump op2Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleGreaterThanOrEqual : MacroAssembler::DoubleLessThanOrEqual, op1.fpr(), op2.fpr());
 2231 // op2 is eather the lesser one or one of then is NaN
 2232 MacroAssembler::Jump op2Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleGreaterThanOrEqual : MacroAssembler::DoubleLessThanOrEqual, op1.fpr(), op2.fpr());
22442233
2245  // Unordered case. We don't know which of op1, op2 is NaN. Manufacture NaN by adding
2246  // op1 + op2 and putting it into result.
2247  m_jit.addDouble(op1.fpr(), op2.fpr(), result.fpr());
2248  done.append(m_jit.jump());
 2234 // Unordered case. We don't know which of op1, op2 is NaN. Manufacture NaN by adding
 2235 // op1 + op2 and putting it into result.
 2236 m_jit.addDouble(op1.fpr(), op2.fpr(), result.fpr());
 2237 done.append(m_jit.jump());
22492238
2250  op2Less.link(&m_jit);
2251  m_jit.moveDouble(op2.fpr(), result.fpr());
 2239 op2Less.link(&m_jit);
 2240 m_jit.moveDouble(op2.fpr(), result.fpr());
22522241
2253  if (op1.fpr() != result.fpr()) {
2254  done.append(m_jit.jump());
 2242 if (op1.fpr() != result.fpr()) {
 2243 done.append(m_jit.jump());
22552244
2256  op1Less.link(&m_jit);
2257  m_jit.moveDouble(op1.fpr(), result.fpr());
2258  } else
2259  op1Less.link(&m_jit);
 2245 op1Less.link(&m_jit);
 2246 m_jit.moveDouble(op1.fpr(), result.fpr());
 2247 } else
 2248 op1Less.link(&m_jit);
22602249
2261  done.link(&m_jit);
 2250 done.link(&m_jit);
22622251
2263  doubleResult(result.fpr(), node);
 2252 doubleResult(result.fpr(), node);
 2253 break;
 2254 }
 2255
 2256 default:
 2257 RELEASE_ASSERT_NOT_REACHED();
 2258 break;
 2259 }
22642260 break;
22652261 }
22662262

@@void SpeculativeJIT::compile(Node* node)
26172613 switch (arrayMode.type()) {
26182614 case Array::Int32:
26192615 case Array::Contiguous: {
2620  JSValueOperand value(this, child3);
 2616 JSValueOperand value(this, child3, ManualOperandSpeculation);
26212617
26222618 GPRReg valueReg = value.gpr();
26232619
26242620 if (!m_compileOkay)
26252621 return;
26262622
2627  if (arrayMode.type() == Array::Int32
2628  && !isInt32Speculation(m_state.forNode(child3).m_type)) {
2629  speculationCheck(
2630  BadType, JSValueRegs(valueReg), child3,
2631  m_jit.branch64(MacroAssembler::Below, valueReg, GPRInfo::tagTypeNumberRegister));
 2623 if (arrayMode.type() == Array::Int32) {
 2624 DFG_TYPE_CHECK(
 2625 JSValueRegs(valueReg), child3, SpecInt32,
 2626 m_jit.branch64(
 2627 MacroAssembler::Below, valueReg, GPRInfo::tagTypeNumberRegister));
26322628 }
26332629
26342630 if (arrayMode.type() == Array::Contiguous && Heap::isWriteBarrierEnabled()) {

@@void SpeculativeJIT::compile(Node* node)
29282924 switch (node->arrayMode().type()) {
29292925 case Array::Int32:
29302926 case Array::Contiguous: {
2931  JSValueOperand value(this, node->child2());
 2927 JSValueOperand value(this, node->child2(), ManualOperandSpeculation);
29322928 GPRReg valueGPR = value.gpr();
29332929
2934  if (node->arrayMode().type() == Array::Int32 && !isInt32Speculation(m_state.forNode(node->child2()).m_type)) {
2935  speculationCheck(
2936  BadType, JSValueRegs(valueGPR), node->child2(),
2937  m_jit.branch64(MacroAssembler::Below, valueGPR, GPRInfo::tagTypeNumberRegister));
 2930 if (node->arrayMode().type() == Array::Int32) {
 2931 DFG_TYPE_CHECK(
 2932 JSValueRegs(valueGPR), node->child2(), SpecInt32,
 2933 m_jit.branch64(
 2934 MacroAssembler::Below, valueGPR, GPRInfo::tagTypeNumberRegister));
29382935 }
29392936
29402937 if (node->arrayMode().type() != Array::Int32 && Heap::isWriteBarrierEnabled()) {

@@void SpeculativeJIT::compile(Node* node)
29622959 SpeculateDoubleOperand value(this, node->child2());
29632960 FPRReg valueFPR = value.fpr();
29642961
2965  if (!isRealNumberSpeculation(m_state.forNode(node->child2()).m_type)) {
2966  // FIXME: We need a way of profiling these, and we need to hoist them into
2967  // SpeculateDoubleOperand.
2968  speculationCheck(
2969  BadType, JSValueRegs(), 0,
2970  m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, valueFPR, valueFPR));
2971  }
 2962 DFG_TYPE_CHECK(
 2963 JSValueRegs(), node->child2(), SpecRealNumber,
 2964 m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, valueFPR, valueFPR));
29722965
29732966 m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR);
29742967 MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength()));

@@void SpeculativeJIT::compile(Node* node)
31713164 }
31723165
31733166 case ToPrimitive: {
3174  if (node->child1()->shouldSpeculateInteger()) {
 3167 switch (node->child1().useKind()) {
 3168 case Int32Use: {
31753169 // It's really profitable to speculate integer, since it's really cheap,
31763170 // it means we don't have to do any real work, and we emit a lot less code.
31773171

@@void SpeculativeJIT::compile(Node* node)
31863180 break;
31873181 }
31883182
3189  // FIXME: Add string speculation here.
3190 
3191  JSValueOperand op1(this, node->child1());
3192  GPRTemporary result(this, op1);
 3183 case UntypedUse: {
 3184 JSValueOperand op1(this, node->child1());
 3185 GPRTemporary result(this, op1);
31933186
3194  GPRReg op1GPR = op1.gpr();
3195  GPRReg resultGPR = result.gpr();
 3187 GPRReg op1GPR = op1.gpr();
 3188 GPRReg resultGPR = result.gpr();
31963189
3197  op1.use();
 3190 op1.use();
31983191
3199  if (!(m_state.forNode(node->child1()).m_type & ~(SpecNumber | SpecBoolean)))
3200  m_jit.move(op1GPR, resultGPR);
3201  else {
3202  MacroAssembler::Jump alreadyPrimitive = m_jit.branchTest64(MacroAssembler::NonZero, op1GPR, GPRInfo::tagMaskRegister);
3203  MacroAssembler::Jump notPrimitive = m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR, JSCell::structureOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get()));
 3192 if (!(m_state.forNode(node->child1()).m_type & ~(SpecNumber | SpecBoolean)))
 3193 m_jit.move(op1GPR, resultGPR);
 3194 else {
 3195 MacroAssembler::Jump alreadyPrimitive = m_jit.branchTest64(MacroAssembler::NonZero, op1GPR, GPRInfo::tagMaskRegister);
 3196 MacroAssembler::Jump notPrimitive = m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR, JSCell::structureOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get()));
32043197
3205  alreadyPrimitive.link(&m_jit);
3206  m_jit.move(op1GPR, resultGPR);
 3198 alreadyPrimitive.link(&m_jit);
 3199 m_jit.move(op1GPR, resultGPR);
32073200
3208  addSlowPathGenerator(
3209  slowPathCall(notPrimitive, this, operationToPrimitive, resultGPR, op1GPR));
3210  }
 3201 addSlowPathGenerator(
 3202 slowPathCall(notPrimitive, this, operationToPrimitive, resultGPR, op1GPR));
 3203 }
32113204
3212  jsValueResult(resultGPR, node, UseChildrenCalledExplicitly);
 3205 jsValueResult(resultGPR, node, UseChildrenCalledExplicitly);
 3206 break;
 3207 }
 3208
 3209 default:
 3210 RELEASE_ASSERT_NOT_REACHED();
 3211 break;
 3212 }
32133213 break;
32143214 }
32153215

@@void SpeculativeJIT::compile(Node* node)
32513251 case ALL_DOUBLE_INDEXING_TYPES: {
32523252 SpeculateDoubleOperand operand(this, use);
32533253 FPRReg opFPR = operand.fpr();
3254  if (!isRealNumberSpeculation(m_state.forNode(use).m_type)) {
3255  // FIXME: We need a way of profiling these, and we need to hoist them into
3256  // SpeculateDoubleOperand.
3257  speculationCheck(
3258  BadType, JSValueRegs(), 0,
3259  m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR));
3260  }
3261 
 3254 DFG_TYPE_CHECK(
 3255 JSValueRegs(), use, SpecRealNumber,
 3256 m_jit.branchDouble(
 3257 MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR));
32623258 m_jit.storeDouble(opFPR, MacroAssembler::Address(storageGPR, sizeof(double) * operandIdx));
32633259 break;
32643260 }
32653261 case ALL_INT32_INDEXING_TYPES:
32663262 case ALL_CONTIGUOUS_INDEXING_TYPES: {
3267  JSValueOperand operand(this, use);
 3263 JSValueOperand operand(this, use, ManualOperandSpeculation);
32683264 GPRReg opGPR = operand.gpr();
3269  if (hasInt32(node->indexingType()) && !isInt32Speculation(m_state.forNode(use).m_type)) {
3270  speculationCheck(
3271  BadType, JSValueRegs(opGPR), use,
3272  m_jit.branch64(MacroAssembler::Below, opGPR, GPRInfo::tagTypeNumberRegister));
 3265 if (hasInt32(node->indexingType())) {
 3266 DFG_TYPE_CHECK(
 3267 JSValueRegs(opGPR), use, SpecInt32,
 3268 m_jit.branch64(
 3269 MacroAssembler::Below, opGPR, GPRInfo::tagTypeNumberRegister));
32733270 }
32743271 m_jit.store64(opGPR, MacroAssembler::Address(storageGPR, sizeof(JSValue) * operandIdx));
32753272 break;

@@void SpeculativeJIT::compile(Node* node)
33193316 GPRTemporary scratch(this);
33203317 FPRReg opFPR = operand.fpr();
33213318 GPRReg scratchGPR = scratch.gpr();
3322  if (!isRealNumberSpeculation(m_state.forNode(use).m_type)) {
3323  // FIXME: We need a way of profiling these, and we need to hoist them into
3324  // SpeculateDoubleOperand.
3325  speculationCheck(
3326  BadType, JSValueRegs(), 0,
3327  m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR));
3328  }
3329 
 3319 DFG_TYPE_CHECK(
 3320 JSValueRegs(), use, SpecRealNumber,
 3321 m_jit.branchDouble(
 3322 MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR));
33303323 m_jit.boxDouble(opFPR, scratchGPR);
33313324 m_jit.store64(scratchGPR, buffer + operandIdx);
33323325 break;
33333326 }
33343327 case ALL_INT32_INDEXING_TYPES: {
3335  JSValueOperand operand(this, use);
 3328 JSValueOperand operand(this, use, ManualOperandSpeculation);
33363329 GPRReg opGPR = operand.gpr();
3337  if (hasInt32(node->indexingType()) && !isInt32Speculation(m_state.forNode(use).m_type)) {
3338  speculationCheck(
3339  BadType, JSValueRegs(opGPR), use,
3340  m_jit.branch64(MacroAssembler::Below, opGPR, GPRInfo::tagTypeNumberRegister));
 3330 if (hasInt32(node->indexingType())) {
 3331 DFG_TYPE_CHECK(
 3332 JSValueRegs(opGPR), use, SpecInt32,
 3333 m_jit.branch64(
 3334 MacroAssembler::Below, opGPR, GPRInfo::tagTypeNumberRegister));
33413335 }
33423336 m_jit.store64(opGPR, buffer + operandIdx);
33433337 break;

@@void SpeculativeJIT::compile(Node* node)
35593553 }
35603554
35613555 case ConvertThis: {
3562  if (isObjectSpeculation(m_state.forNode(node->child1()).m_type)) {
3563  SpeculateCellOperand thisValue(this, node->child1());
3564  GPRTemporary result(this, thisValue);
3565  m_jit.move(thisValue.gpr(), result.gpr());
3566  cellResult(result.gpr(), node);
3567  break;
3568  }
3569 
3570  if (isOtherSpeculation(node->child1()->prediction())) {
3571  JSValueOperand thisValue(this, node->child1());
 3556 switch (node->child1().useKind()) {
 3557 case OtherUse: {
 3558 JSValueOperand thisValue(this, node->child1(), ManualOperandSpeculation);
35723559 GPRTemporary scratch(this);
35733560 GPRReg thisValueGPR = thisValue.gpr();
35743561 GPRReg scratchGPR = scratch.gpr();
35753562
3576  if (!isOtherSpeculation(m_state.forNode(node->child1()).m_type)) {
 3563 if (needsTypeCheck(node->child1(), SpecOther)) {
35773564 m_jit.move(thisValueGPR, scratchGPR);
35783565 m_jit.and64(MacroAssembler::TrustedImm32(~TagBitUndefined), scratchGPR);
3579  speculationCheck(BadType, JSValueRegs(thisValueGPR), node->child1(), m_jit.branch64(MacroAssembler::NotEqual, scratchGPR, MacroAssembler::TrustedImm64(ValueNull)));
 3566 typeCheck(
 3567 JSValueRegs(thisValueGPR), node->child1(), SpecOther,
 3568 m_jit.branch64(
 3569 MacroAssembler::NotEqual, scratchGPR,
 3570 MacroAssembler::TrustedImm64(ValueNull)));
35803571 }
35813572
35823573 m_jit.move(MacroAssembler::TrustedImmPtr(m_jit.globalThisObjectFor(node->codeOrigin)), scratchGPR);

@@void SpeculativeJIT::compile(Node* node)
35843575 break;
35853576 }
35863577
3587  if (isObjectSpeculation(node->child1()->prediction())) {
 3578 case ObjectUse: {
35883579 SpeculateCellOperand thisValue(this, node->child1());
35893580 GPRTemporary result(this, thisValue);
35903581 GPRReg thisValueGPR = thisValue.gpr();
35913582 GPRReg resultGPR = result.gpr();
35923583
3593  if (!isObjectSpeculation(m_state.forNode(node->child1()).m_type))
3594  speculationCheck(BadType, JSValueSource::unboxedCell(thisValueGPR), node->child1(), m_jit.branchPtr(JITCompiler::Equal, JITCompiler::Address(thisValueGPR, JSCell::structureOffset()), JITCompiler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
 3584 DFG_TYPE_CHECK(
 3585 JSValueSource::unboxedCell(thisValueGPR), node->child1(), SpecObject,
 3586 m_jit.branchPtr(
 3587 JITCompiler::Equal,
 3588 JITCompiler::Address(thisValueGPR, JSCell::structureOffset()),
 3589 JITCompiler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
35953590
35963591 m_jit.move(thisValueGPR, resultGPR);
35973592
35983593 cellResult(resultGPR, node);
35993594 break;
36003595 }
3601 
3602  JSValueOperand thisValue(this, node->child1());
3603  GPRReg thisValueGPR = thisValue.gpr();
3604 
3605  flushRegisters();
3606 
3607  GPRResult result(this);
3608  callOperation(operationConvertThis, result.gpr(), thisValueGPR);
3609 
3610  cellResult(result.gpr(), node);
 3596
 3597 case UntypedUse: {
 3598 JSValueOperand thisValue(this, node->child1());
 3599 GPRReg thisValueGPR = thisValue.gpr();
 3600
 3601 flushRegisters();
 3602
 3603 GPRResult result(this);
 3604 callOperation(operationConvertThis, result.gpr(), thisValueGPR);
 3605
 3606 cellResult(result.gpr(), node);
 3607 break;
 3608 }
 3609
 3610 default:
 3611 RELEASE_ASSERT_NOT_REACHED();
 3612 break;
 3613 }
36113614 break;
36123615 }
36133616

@@void SpeculativeJIT::compile(Node* node)
37763779 terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
37773780 break;
37783781 }
3779 
3780  if (isCellSpeculation(node->child1()->prediction())) {
 3782
 3783 switch (node->child1().useKind()) {
 3784 case CellUse: {
37813785 SpeculateCellOperand base(this, node->child1());
37823786 GPRTemporary result(this, base);
37833787

@@void SpeculativeJIT::compile(Node* node)
37923796 break;
37933797 }
37943798
3795  JSValueOperand base(this, node->child1());
3796  GPRTemporary result(this, base);
3797 
3798  GPRReg baseGPR = base.gpr();
3799  GPRReg resultGPR = result.gpr();
 3799 case UntypedUse: {
 3800 JSValueOperand base(this, node->child1());
 3801 GPRTemporary result(this, base);
38003802
3801  base.use();
 3803 GPRReg baseGPR = base.gpr();
 3804 GPRReg resultGPR = result.gpr();
38023805
3803  JITCompiler::Jump notCell = m_jit.branchTest64(JITCompiler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
 3806 base.use();
38043807
3805  cachedGetById(node->codeOrigin, baseGPR, resultGPR, node->identifierNumber(), notCell);
 3808 JITCompiler::Jump notCell = m_jit.branchTest64(JITCompiler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
38063809
3807  jsValueResult(resultGPR, node, UseChildrenCalledExplicitly);
 3810 cachedGetById(node->codeOrigin, baseGPR, resultGPR, node->identifierNumber(), notCell);
38083811
 3812 jsValueResult(resultGPR, node, UseChildrenCalledExplicitly);
 3813 break;
 3814 }
 3815
 3816 default:
 3817 RELEASE_ASSERT_NOT_REACHED();
 3818 break;
 3819 }
38093820 break;
38103821 }
38113822

@@void SpeculativeJIT::compile(Node* node)
38143825 terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
38153826 break;
38163827 }
3817 
3818  if (isCellSpeculation(node->child1()->prediction())) {
 3828
 3829 switch (node->child1().useKind()) {
 3830 case CellUse: {
38193831 SpeculateCellOperand base(this, node->child1());
38203832 GPRReg baseGPR = base.gpr();
38213833

@@void SpeculativeJIT::compile(Node* node)
38333845 break;
38343846 }
38353847
3836  JSValueOperand base(this, node->child1());
3837  GPRReg baseGPR = base.gpr();
 3848 case UntypedUse: {
 3849 JSValueOperand base(this, node->child1());
 3850 GPRReg baseGPR = base.gpr();
38383851
3839  GPRResult result(this);
3840  GPRReg resultGPR = result.gpr();
 3852 GPRResult result(this);
 3853 GPRReg resultGPR = result.gpr();
38413854
3842  base.use();
3843  flushRegisters();
 3855 base.use();
 3856 flushRegisters();
38443857
3845  JITCompiler::Jump notCell = m_jit.branchTest64(JITCompiler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
 3858 JITCompiler::Jump notCell = m_jit.branchTest64(JITCompiler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
38463859
3847  cachedGetById(node->codeOrigin, baseGPR, resultGPR, node->identifierNumber(), notCell, DontSpill);
 3860 cachedGetById(node->codeOrigin, baseGPR, resultGPR, node->identifierNumber(), notCell, DontSpill);
38483861
3849  jsValueResult(resultGPR, node, UseChildrenCalledExplicitly);
3850 
 3862 jsValueResult(resultGPR, node, UseChildrenCalledExplicitly);
 3863 break;
 3864 }
 3865
 3866 default:
 3867 RELEASE_ASSERT_NOT_REACHED();
 3868 break;
 3869 }
38513870 break;
38523871 }
38533872

@@void SpeculativeJIT::compile(Node* node)
38713890
38723891 case CheckStructure:
38733892 case ForwardCheckStructure: {
3874  AbstractValue& value = m_state.forNode(node->child1());
3875  if (value.m_currentKnownStructure.isSubsetOf(node->structureSet())
3876  && isCellSpeculation(value.m_type)) {
3877  noResult(node);
3878  break;
3879  }
3880 
38813893 SpeculationDirection direction = node->op() == ForwardCheckStructure ? ForwardSpeculation : BackwardSpeculation;
38823894 SpeculateCellOperand base(this, node->child1(), direction);
38833895

@@void SpeculativeJIT::compile(Node* node)
39423954 JITCompiler::Jump isOK = m_jit.branchPtr(JITCompiler::Equal, JITCompiler::Address(op1.gpr(), JSCell::structureOffset()), TrustedImmPtr(node->structure()));
39433955 m_jit.breakpoint();
39443956 isOK.link(&m_jit);
 3957#else
 3958 speculateCell(node->child1());
39453959#endif
39463960
39473961 noResult(node);

@@void SpeculativeJIT::compile(Node* node)
39493963 }
39503964
39513965 case PhantomPutStructure: {
 3966 ASSERT(isKnownCell(node->child1().node()));
 3967
39523968 ASSERT(node->structureTransitionData().previousStructure->transitionWatchpointSetHasBeenInvalidated());
39533969 m_jit.addWeakReferenceTransition(
39543970 node->codeOrigin.codeOriginOwner(),

@@void SpeculativeJIT::compile(Node* node)
42714287 }
42724288
42734289 case TypeOf: {
4274  JSValueOperand value(this, node->child1());
 4290 JSValueOperand value(this, node->child1(), ManualOperandSpeculation);
42754291 GPRReg valueGPR = value.gpr();
42764292 GPRTemporary temp(this);
42774293 GPRReg tempGPR = temp.gpr();

@@void SpeculativeJIT::compile(Node* node)
42804296 JITCompiler::JumpList doneJumps;
42814297
42824298 flushRegisters();
 4299
 4300 ASSERT(node->child1().useKind() == UntypedUse || node->child1().useKind() == CellUse || node->child1().useKind() == StringUse);
42834301
42844302 JITCompiler::Jump isNotCell = m_jit.branchTest64(JITCompiler::NonZero, valueGPR, GPRInfo::tagMaskRegister);
4285  if (node->child1()->shouldSpeculateCell())
4286  speculationCheck(BadType, JSValueSource(valueGPR), node->child1(), isNotCell);
 4303 if (node->child1().useKind() != UntypedUse)
 4304 DFG_TYPE_CHECK(JSValueSource(valueGPR), node->child1(), SpecCell, isNotCell);
42874305
4288  if (!node->child1()->shouldSpeculateObject()) {
 4306 if (!node->child1()->shouldSpeculateObject() || node->child1().useKind() == StringUse) {
42894307 m_jit.loadPtr(JITCompiler::Address(valueGPR, JSCell::structureOffset()), tempGPR);
42904308 JITCompiler::Jump notString = m_jit.branch8(JITCompiler::NotEqual, JITCompiler::Address(tempGPR, Structure::typeInfoTypeOffset()), TrustedImm32(StringType));
4291  if (node->child1()->shouldSpeculateString())
4292  speculationCheck(BadType, JSValueSource(valueGPR), node->child1(), notString);
 4309 if (node->child1().useKind() == StringUse)
 4310 DFG_TYPE_CHECK(JSValueSource(valueGPR), node->child1(), SpecString, notString);
42934311 m_jit.move(TrustedImmPtr(m_jit.globalData()->smallStrings.stringString()), resultGPR);
42944312 doneJumps.append(m_jit.jump());
4295  if (!node->child1()->shouldSpeculateString()) {
 4313 if (node->child1().useKind() != StringUse) {
42964314 notString.link(&m_jit);
42974315 callOperation(operationTypeOf, resultGPR, valueGPR);
42984316 doneJumps.append(m_jit.jump());

@@void SpeculativeJIT::compile(Node* node)
43024320 doneJumps.append(m_jit.jump());
43034321 }
43044322
4305  if (!node->child1()->shouldSpeculateCell()) {
 4323 if (node->child1().useKind() == UntypedUse) {
43064324 isNotCell.link(&m_jit);
43074325 JITCompiler::Jump notNumber = m_jit.branchTest64(JITCompiler::Zero, valueGPR, GPRInfo::tagTypeNumberRegister);
43084326 m_jit.move(TrustedImmPtr(m_jit.globalData()->smallStrings.numberString()), resultGPR);

@@void SpeculativeJIT::compile(Node* node)
47714789 }
47724790
47734791 case Phantom:
 4792 DFG_NODE_DO_TO_CHILDREN(m_jit.graph(), node, speculate);
 4793 noResult(node);
 4794 break;
 4795
47744796 case PhantomLocal:
47754797 // This is a no-op.
47764798 noResult(node);
143562

Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

@@void SpeculativeJIT::speculationCheck(Ex
108108{
109109 if (!m_compileOkay)
110110 return;
111  ASSERT(m_isCheckingArgumentTypes || m_currentNode->canExit());
 111 ASSERT(m_isCheckingArgumentTypes || m_canExit);
112112 m_jit.appendExitInfo(jumpToFail);
113113 m_jit.codeBlock()->appendOSRExit(OSRExit(kind, jsValueSource, m_jit.graph().methodOfGettingAValueProfileFor(node), this, m_stream->size()));
114114}
115115
116116void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Edge nodeUse, MacroAssembler::Jump jumpToFail)
117117{
118  ASSERT(m_isCheckingArgumentTypes || m_currentNode->canExit());
 118 ASSERT(m_isCheckingArgumentTypes || m_canExit);
119119 speculationCheck(kind, jsValueSource, nodeUse.node(), jumpToFail);
120120}
121121

@@OSRExitJumpPlaceholder SpeculativeJIT::s
123123{
124124 if (!m_compileOkay)
125125 return OSRExitJumpPlaceholder();
126  ASSERT(m_isCheckingArgumentTypes || m_currentNode->canExit());
 126 ASSERT(m_isCheckingArgumentTypes || m_canExit);
127127 unsigned index = m_jit.codeBlock()->numberOfOSRExits();
128128 m_jit.appendExitInfo();
129129 m_jit.codeBlock()->appendOSRExit(OSRExit(kind, jsValueSource, m_jit.graph().methodOfGettingAValueProfileFor(node), this, m_stream->size()));

@@OSRExitJumpPlaceholder SpeculativeJIT::s
132132
133133OSRExitJumpPlaceholder SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Edge nodeUse)
134134{
135  ASSERT(m_isCheckingArgumentTypes || m_currentNode->canExit());
 135 ASSERT(m_isCheckingArgumentTypes || m_canExit);
136136 return speculationCheck(kind, jsValueSource, nodeUse.node());
137137}
138138

@@void SpeculativeJIT::speculationCheck(Ex
140140{
141141 if (!m_compileOkay)
142142 return;
143  ASSERT(m_isCheckingArgumentTypes || m_currentNode->canExit());
 143 ASSERT(m_isCheckingArgumentTypes || m_canExit);
144144 m_jit.appendExitInfo(jumpsToFail);
145145 m_jit.codeBlock()->appendOSRExit(OSRExit(kind, jsValueSource, m_jit.graph().methodOfGettingAValueProfileFor(node), this, m_stream->size()));
146146}
147147
148148void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Edge nodeUse, const MacroAssembler::JumpList& jumpsToFail)
149149{
150  ASSERT(m_isCheckingArgumentTypes || m_currentNode->canExit());
 150 ASSERT(m_isCheckingArgumentTypes || m_canExit);
151151 speculationCheck(kind, jsValueSource, nodeUse.node(), jumpsToFail);
152152}
153153

@@void SpeculativeJIT::speculationCheck(Ex
155155{
156156 if (!m_compileOkay)
157157 return;
158  ASSERT(m_isCheckingArgumentTypes || m_currentNode->canExit());
 158 ASSERT(m_isCheckingArgumentTypes || m_canExit);
159159 m_jit.codeBlock()->appendSpeculationRecovery(recovery);
160160 m_jit.appendExitInfo(jumpToFail);
161161 m_jit.codeBlock()->appendOSRExit(OSRExit(kind, jsValueSource, m_jit.graph().methodOfGettingAValueProfileFor(node), this, m_stream->size(), m_jit.codeBlock()->numberOfSpeculationRecoveries()));

@@void SpeculativeJIT::speculationCheck(Ex
163163
164164void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Edge nodeUse, MacroAssembler::Jump jumpToFail, const SpeculationRecovery& recovery)
165165{
166  ASSERT(m_isCheckingArgumentTypes || m_currentNode->canExit());
 166 ASSERT(m_isCheckingArgumentTypes || m_canExit);
167167 speculationCheck(kind, jsValueSource, nodeUse.node(), jumpToFail, recovery);
168168}
169169

@@void SpeculativeJIT::speculationCheck(Ex
174174 convertLastOSRExitToForward();
175175}
176176
 177void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Edge edge, MacroAssembler::Jump jumpToFail, const SpeculationRecovery& recovery, SpeculationDirection direction)
 178{
 179 speculationCheck(kind, jsValueSource, edge.node(), jumpToFail, recovery, direction);
 180}
 181
177182JumpReplacementWatchpoint* SpeculativeJIT::speculationWatchpoint(ExitKind kind, JSValueSource jsValueSource, Node* node)
178183{
179184 if (!m_compileOkay)
180185 return 0;
181  ASSERT(m_isCheckingArgumentTypes || m_currentNode->canExit());
 186 ASSERT(m_isCheckingArgumentTypes || m_canExit);
182187 m_jit.appendExitInfo(JITCompiler::JumpList());
183188 OSRExit& exit = m_jit.codeBlock()->osrExit(
184189 m_jit.codeBlock()->appendOSRExit(OSRExit(

@@JumpReplacementWatchpoint* SpeculativeJI
280285
281286void SpeculativeJIT::forwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node, MacroAssembler::Jump jumpToFail, const ValueRecovery& valueRecovery)
282287{
283  ASSERT(m_isCheckingArgumentTypes || m_currentNode->canExit());
 288 ASSERT(m_isCheckingArgumentTypes || m_canExit);
284289 speculationCheck(kind, jsValueSource, node, jumpToFail);
285290 convertLastOSRExitToForward(valueRecovery);
286291}
287292
288293void SpeculativeJIT::forwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node, const MacroAssembler::JumpList& jumpsToFail, const ValueRecovery& valueRecovery)
289294{
290  ASSERT(m_isCheckingArgumentTypes || m_currentNode->canExit());
 295 ASSERT(m_isCheckingArgumentTypes || m_canExit);
291296 speculationCheck(kind, jsValueSource, node, jumpsToFail);
292297 convertLastOSRExitToForward(valueRecovery);
293298}

@@void SpeculativeJIT::speculationCheck(Ex
300305 speculationCheck(kind, jsValueSource, node, jumpToFail);
301306}
302307
 308void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Edge edge, MacroAssembler::Jump jumpToFail, SpeculationDirection direction)
 309{
 310 speculationCheck(kind, jsValueSource, edge.node(), jumpToFail, direction);
 311}
 312
303313void SpeculativeJIT::terminateSpeculativeExecution(ExitKind kind, JSValueRegs jsValueRegs, Node* node)
304314{
305  ASSERT(m_isCheckingArgumentTypes || m_currentNode->canExit());
 315 ASSERT(m_isCheckingArgumentTypes || m_canExit);
306316#if DFG_ENABLE(DEBUG_VERBOSE)
307317 dataLogF("SpeculativeJIT was terminated.\n");
308318#endif

@@void SpeculativeJIT::terminateSpeculativ
314324
315325void SpeculativeJIT::terminateSpeculativeExecution(ExitKind kind, JSValueRegs jsValueRegs, Edge nodeUse)
316326{
317  ASSERT(m_isCheckingArgumentTypes || m_currentNode->canExit());
 327 ASSERT(m_isCheckingArgumentTypes || m_canExit);
318328 terminateSpeculativeExecution(kind, jsValueRegs, nodeUse.node());
319329}
320330
321331void SpeculativeJIT::terminateSpeculativeExecution(ExitKind kind, JSValueRegs jsValueRegs, Node* node, SpeculationDirection direction)
322332{
323  ASSERT(m_isCheckingArgumentTypes || m_currentNode->canExit());
 333 ASSERT(m_isCheckingArgumentTypes || m_canExit);
324334#if DFG_ENABLE(DEBUG_VERBOSE)
325335 dataLogF("SpeculativeJIT was terminated.\n");
326336#endif

@@void SpeculativeJIT::terminateSpeculativ
330340 m_compileOkay = false;
331341}
332342
 343void SpeculativeJIT::typeCheck(JSValueSource source, Edge edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail)
 344{
 345 ASSERT(needsTypeCheck(edge, typesPassedThrough));
 346 m_state.forNode(edge).filter(typesPassedThrough);
 347 speculationCheck(BadType, source, edge, jumpToFail);
 348}
 349
 350void SpeculativeJIT::forwardTypeCheck(JSValueSource source, Edge edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail, const ValueRecovery& valueRecovery)
 351{
 352 typeCheck(source, edge, typesPassedThrough, jumpToFail);
 353 convertLastOSRExitToForward(valueRecovery);
 354}
 355
 356void SpeculativeJIT::typeCheck(JSValueSource source, Edge edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail, SpeculationDirection direction)
 357{
 358 typeCheck(source, edge, typesPassedThrough, jumpToFail);
 359 if (direction == ForwardSpeculation)
 360 convertLastOSRExitToForward();
 361}
 362
333363void SpeculativeJIT::addSlowPathGenerator(PassOwnPtr<SlowPathGenerator> slowPathGenerator)
334364{
335365 m_slowPathGenerators.append(slowPathGenerator.leakPtr());

@@void SpeculativeJIT::arrayify(Node* node
872902 arrayify(node, base.gpr(), property.gpr());
873903}
874904
875 GPRReg SpeculativeJIT::fillStorage(Node* node)
 905GPRReg SpeculativeJIT::fillStorage(Edge edge)
876906{
877  VirtualRegister virtualRegister = node->virtualRegister();
 907 VirtualRegister virtualRegister = edge->virtualRegister();
878908 GenerationInfo& info = m_generationInfo[virtualRegister];
879909
880910 switch (info.registerFormat()) {

@@GPRReg SpeculativeJIT::fillStorage(Node*
888918 }
889919
890920 // Must be a cell; fill it as a cell and then return the pointer.
891  return fillSpeculateCell(node, BackwardSpeculation);
 921 return fillSpeculateCell(edge, BackwardSpeculation);
892922 }
893923
894924 case DataFormatStorage: {

@@GPRReg SpeculativeJIT::fillStorage(Node*
898928 }
899929
900930 default:
901  return fillSpeculateCell(node, BackwardSpeculation);
 931 return fillSpeculateCell(edge, BackwardSpeculation);
902932 }
903933}
904934

@@bool SpeculativeJIT::compilePeepHoleBran
15091539 // so can be no intervening nodes to also reference the compare.
15101540 ASSERT(node->adjustedRefCount() == 1);
15111541
1512  if (Node::shouldSpeculateInteger(node->child1().node(), node->child2().node()))
 1542 if (node->isBinaryUseKind(Int32Use))
15131543 compilePeepHoleIntegerBranch(node, branchNode, condition);
1514  else if (Node::shouldSpeculateNumber(node->child1().node(), node->child2().node()))
 1544 else if (node->isBinaryUseKind(NumberUse))
15151545 compilePeepHoleDoubleBranch(node, branchNode, doubleCondition);
15161546 else if (node->op() == CompareEq) {
1517  if (node->child1()->shouldSpeculateString() || node->child2()->shouldSpeculateString()) {
 1547 if (node->isBinaryUseKind(StringUse)) {
15181548 nonSpeculativePeepholeBranch(node, branchNode, condition, operation);
15191549 return true;
15201550 }
1521  if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject())
 1551 if (node->isBinaryUseKind(ObjectUse))
15221552 compilePeepHoleObjectEquality(node, branchNode);
1523  else if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObjectOrOther())
 1553 else if (node->child1().useKind() == ObjectUse && node->child2().useKind() == ObjectOrOtherUse)
15241554 compilePeepHoleObjectToObjectOrOtherEquality(node->child1(), node->child2(), branchNode);
1525  else if (node->child1()->shouldSpeculateObjectOrOther() && node->child2()->shouldSpeculateObject())
 1555 else if (node->child1().useKind() == ObjectOrOtherUse && node->child2().useKind() == ObjectUse)
15261556 compilePeepHoleObjectToObjectOrOtherEquality(node->child2(), node->child1(), branchNode);
15271557 else {
15281558 nonSpeculativePeepholeBranch(node, branchNode, condition, operation);

@@void SpeculativeJIT::compile(BasicBlock&
16451675
16461676 for (m_indexInBlock = 0; m_indexInBlock < block.size(); ++m_indexInBlock) {
16471677 m_currentNode = block[m_indexInBlock];
 1678#if !ASSERT_DISABLED
 1679 m_canExit = m_currentNode->canExit();
 1680#endif
 1681 bool shouldExecuteEffects = m_state.startExecuting(m_currentNode);
16481682 m_jit.setForNode(m_currentNode);
16491683 m_codeOriginForOSR = m_currentNode->codeOrigin;
16501684 if (!m_currentNode->shouldGenerate()) {

@@void SpeculativeJIT::compile(BasicBlock&
17111745 }
17121746 } else {
17131747
 1748 if (verboseCompilationEnabled()) {
 1749 dataLogF(
 1750 "SpeculativeJIT generating Node @%d (bc#%u) at JIT offset 0x%x",
 1751 (int)m_currentNode->index(),
 1752 m_currentNode->codeOrigin.bytecodeIndex, m_jit.debugOffset());
17141753#if DFG_ENABLE(DEBUG_VERBOSE)
1715  dataLogF("SpeculativeJIT generating Node @%d (bc#%u) at JIT offset 0x%x ", (int)m_currentNode->index(), m_currentNode->codeOrigin.bytecodeIndex, m_jit.debugOffset());
 1754 dataLog(" ");
 1755#else
 1756 dataLog("\n");
17161757#endif
 1758 }
17171759#if DFG_ENABLE(JIT_BREAK_ON_EVERY_NODE)
17181760 m_jit.breakpoint();
17191761#endif

@@void SpeculativeJIT::compile(BasicBlock&
17591801#endif
17601802
17611803 // Make sure that the abstract state is rematerialized for the next node.
1762  m_state.execute(m_indexInBlock);
 1804 if (shouldExecuteEffects)
 1805 m_state.executeEffects(m_indexInBlock);
17631806
17641807 if (m_currentNode->shouldGenerate())
17651808 checkConsistency();

@@void SpeculativeJIT::compileDoublePutByV
19061949
19071950 FPRReg valueReg = value.fpr();
19081951
1909  if (!isRealNumberSpeculation(m_state.forNode(child3).m_type)) {
1910  // FIXME: We need a way of profiling these, and we need to hoist them into
1911  // SpeculateDoubleOperand.
1912  speculationCheck(
1913  BadType, JSValueRegs(), 0,
1914  m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, valueReg, valueReg));
1915  }
 1952 DFG_TYPE_CHECK(
 1953 JSValueRegs(), child3, SpecRealNumber,
 1954 m_jit.branchDouble(
 1955 MacroAssembler::DoubleNotEqualOrUnordered, valueReg, valueReg));
19161956
19171957 if (!m_compileOkay)
19181958 return;

@@GeneratedOperandType SpeculativeJIT::che
21042144
21052145void SpeculativeJIT::compileValueToInt32(Node* node)
21062146{
2107  if (node->child1()->shouldSpeculateInteger()) {
 2147 switch (node->child1().useKind()) {
 2148 case Int32Use: {
21082149 SpeculateIntegerOperand op1(this, node->child1());
21092150 GPRTemporary result(this, op1);
21102151 m_jit.move(op1.gpr(), result.gpr());

@@void SpeculativeJIT::compileValueToInt32
21122153 return;
21132154 }
21142155
2115  if (node->child1()->shouldSpeculateBoolean()) {
2116  SpeculateBooleanOperand op1(this, node->child1());
2117  GPRTemporary result(this, op1);
2118 
2119  m_jit.move(op1.gpr(), result.gpr());
2120  m_jit.and32(JITCompiler::TrustedImm32(1), result.gpr());
2121 
2122  integerResult(result.gpr(), node);
2123  return;
2124  }
2125 
2126  switch (checkGeneratedTypeForToInt32(node->child1().node())) {
2127  case GeneratedOperandInteger: {
2128  SpeculateIntegerOperand op1(this, node->child1());
2129  GPRTemporary result(this, op1);
2130  m_jit.move(op1.gpr(), result.gpr());
2131  integerResult(result.gpr(), node, op1.format());
2132  return;
2133  }
2134  case GeneratedOperandDouble: {
2135  GPRTemporary result(this);
2136  SpeculateDoubleOperand op1(this, Edge(node->child1().node(), DoubleUse)); // SpeculateDoubleOperand will assert that this is a double use. We force it to think that it was a double use, since we are inferring that we ought to emit a double use quite late.
2137  FPRReg fpr = op1.fpr();
2138  GPRReg gpr = result.gpr();
2139  JITCompiler::Jump notTruncatedToInteger = m_jit.branchTruncateDoubleToInt32(fpr, gpr, JITCompiler::BranchIfTruncateFailed);
 2156 case NumberUse:
 2157 case NotCellUse: {
 2158 switch (checkGeneratedTypeForToInt32(node->child1().node())) {
 2159 case GeneratedOperandInteger: {
 2160 SpeculateIntegerOperand op1(this, node->child1(), BackwardSpeculation, ManualOperandSpeculation);
 2161 GPRTemporary result(this, op1);
 2162 m_jit.move(op1.gpr(), result.gpr());
 2163 integerResult(result.gpr(), node, op1.format());
 2164 return;
 2165 }
 2166 case GeneratedOperandDouble: {
 2167 GPRTemporary result(this);
 2168 SpeculateDoubleOperand op1(this, node->child1(), BackwardSpeculation, ManualOperandSpeculation);
 2169 FPRReg fpr = op1.fpr();
 2170 GPRReg gpr = result.gpr();
 2171 JITCompiler::Jump notTruncatedToInteger = m_jit.branchTruncateDoubleToInt32(fpr, gpr, JITCompiler::BranchIfTruncateFailed);
21402172
2141  addSlowPathGenerator(slowPathCall(notTruncatedToInteger, this, toInt32, gpr, fpr));
 2173 addSlowPathGenerator(slowPathCall(notTruncatedToInteger, this, toInt32, gpr, fpr));
21422174
2143  integerResult(gpr, node);
2144  return;
2145  }
2146  case GeneratedOperandJSValue: {
2147  GPRTemporary result(this);
 2175 integerResult(gpr, node);
 2176 return;
 2177 }
 2178 case GeneratedOperandJSValue: {
 2179 GPRTemporary result(this);
21482180#if USE(JSVALUE64)
2149  JSValueOperand op1(this, node->child1());
 2181 JSValueOperand op1(this, node->child1(), ManualOperandSpeculation);
21502182
2151  GPRReg gpr = op1.gpr();
2152  GPRReg resultGpr = result.gpr();
2153  FPRTemporary tempFpr(this);
2154  FPRReg fpr = tempFpr.fpr();
2155 
2156  JITCompiler::Jump isInteger = m_jit.branch64(MacroAssembler::AboveOrEqual, gpr, GPRInfo::tagTypeNumberRegister);
2157  JITCompiler::JumpList converted;
2158 
2159  if (!isNumberSpeculation(m_state.forNode(node->child1()).m_type)) {
2160  if (node->child1()->shouldSpeculateNumber())
2161  speculationCheck(BadType, JSValueRegs(gpr), node->child1(), m_jit.branchTest64(MacroAssembler::Zero, gpr, GPRInfo::tagTypeNumberRegister));
2162  else {
 2183 GPRReg gpr = op1.gpr();
 2184 GPRReg resultGpr = result.gpr();
 2185 FPRTemporary tempFpr(this);
 2186 FPRReg fpr = tempFpr.fpr();
 2187
 2188 JITCompiler::Jump isInteger = m_jit.branch64(MacroAssembler::AboveOrEqual, gpr, GPRInfo::tagTypeNumberRegister);
 2189 JITCompiler::JumpList converted;
 2190
 2191 if (node->child1().useKind() == NumberUse) {
 2192 DFG_TYPE_CHECK(
 2193 JSValueRegs(gpr), node->child1(), SpecNumber,
 2194 m_jit.branchTest64(
 2195 MacroAssembler::Zero, gpr, GPRInfo::tagTypeNumberRegister));
 2196 } else {
21632197 JITCompiler::Jump isNumber = m_jit.branchTest64(MacroAssembler::NonZero, gpr, GPRInfo::tagTypeNumberRegister);
21642198
2165  if (m_state.forNode(node->child1()).m_type & SpecCell)
2166  speculationCheck(BadType, JSValueRegs(gpr), node->child1(), m_jit.branchTest64(JITCompiler::Zero, gpr, GPRInfo::tagMaskRegister));
 2199 DFG_TYPE_CHECK(
 2200 JSValueRegs(gpr), node->child1(), ~SpecCell,
 2201 m_jit.branchTest64(
 2202 JITCompiler::Zero, gpr, GPRInfo::tagMaskRegister));
21672203
21682204 // It's not a cell: so true turns into 1 and all else turns into 0.
21692205 m_jit.compare64(JITCompiler::Equal, gpr, TrustedImm32(ValueTrue), resultGpr);

@@void SpeculativeJIT::compileValueToInt32
21712207
21722208 isNumber.link(&m_jit);
21732209 }
2174  }
21752210
2176  // First, if we get here we have a double encoded as a JSValue
2177  m_jit.move(gpr, resultGpr);
2178  unboxDouble(resultGpr, fpr);
 2211 // First, if we get here we have a double encoded as a JSValue
 2212 m_jit.move(gpr, resultGpr);
 2213 unboxDouble(resultGpr, fpr);
21792214
2180  silentSpillAllRegisters(resultGpr);
2181  callOperation(toInt32, resultGpr, fpr);
2182  silentFillAllRegisters(resultGpr);
 2215 silentSpillAllRegisters(resultGpr);
 2216 callOperation(toInt32, resultGpr, fpr);
 2217 silentFillAllRegisters(resultGpr);
21832218
2184  converted.append(m_jit.jump());
 2219 converted.append(m_jit.jump());
21852220
2186  isInteger.link(&m_jit);
2187  m_jit.zeroExtend32ToPtr(gpr, resultGpr);
 2221 isInteger.link(&m_jit);
 2222 m_jit.zeroExtend32ToPtr(gpr, resultGpr);
21882223
2189  converted.link(&m_jit);
 2224 converted.link(&m_jit);
21902225#else
2191  Node* childNode = node->child1().node();
2192  VirtualRegister virtualRegister = childNode->virtualRegister();
2193  GenerationInfo& info = m_generationInfo[virtualRegister];
 2226 Node* childNode = node->child1().node();
 2227 VirtualRegister virtualRegister = childNode->virtualRegister();
 2228 GenerationInfo& info = m_generationInfo[virtualRegister];
21942229
2195  JSValueOperand op1(this, node->child1());
 2230 JSValueOperand op1(this, node->child1(), ManualOperandSpeculation);
21962231
2197  GPRReg payloadGPR = op1.payloadGPR();
2198  GPRReg resultGpr = result.gpr();
 2232 GPRReg payloadGPR = op1.payloadGPR();
 2233 GPRReg resultGpr = result.gpr();
21992234
2200  JITCompiler::JumpList converted;
2201 
2202  if (info.registerFormat() == DataFormatJSInteger)
2203  m_jit.move(payloadGPR, resultGpr);
2204  else {
2205  GPRReg tagGPR = op1.tagGPR();
2206  FPRTemporary tempFpr(this);
2207  FPRReg fpr = tempFpr.fpr();
2208  FPRTemporary scratch(this);
2209 
2210  JITCompiler::Jump isInteger = m_jit.branch32(MacroAssembler::Equal, tagGPR, TrustedImm32(JSValue::Int32Tag));
 2235 JITCompiler::JumpList converted;
22112236
2212  if (!isNumberSpeculation(m_state.forNode(node->child1()).m_type)) {
2213  if (node->child1()->shouldSpeculateNumber())
2214  speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), node->child1(), m_jit.branch32(MacroAssembler::AboveOrEqual, tagGPR, TrustedImm32(JSValue::LowestTag)));
2215  else {
 2237 if (info.registerFormat() == DataFormatJSInteger)
 2238 m_jit.move(payloadGPR, resultGpr);
 2239 else {
 2240 GPRReg tagGPR = op1.tagGPR();
 2241 FPRTemporary tempFpr(this);
 2242 FPRReg fpr = tempFpr.fpr();
 2243 FPRTemporary scratch(this);
 2244
 2245 JITCompiler::Jump isInteger = m_jit.branch32(MacroAssembler::Equal, tagGPR, TrustedImm32(JSValue::Int32Tag));
 2246
 2247 if (node->child1().useKind() == NumberUse) {
 2248 DFG_TYPE_CHECK(
 2249 JSValueRegs(tagGPR, payloadGPR), node->child1(), SpecNumber,
 2250 m_jit.branch32(
 2251 MacroAssembler::AboveOrEqual, tagGPR,
 2252 TrustedImm32(JSValue::LowestTag)));
 2253 } else {
22162254 JITCompiler::Jump isNumber = m_jit.branch32(MacroAssembler::Below, tagGPR, TrustedImm32(JSValue::LowestTag));
22172255
2218  if (m_state.forNode(node->child1()).m_type & SpecCell)
2219  speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), node->child1(), m_jit.branch32(JITCompiler::Equal, tagGPR, TrustedImm32(JSValue::CellTag)));
 2256 DFG_TYPE_CHECK(
 2257 JSValueRegs(tagGPR, payloadGPR), node->child1(), ~SpecCell,
 2258 m_jit.branch32(
 2259 JITCompiler::Equal, tagGPR, TrustedImm32(JSValue::CellTag)));
22202260
22212261 // It's not a cell: so true turns into 1 and all else turns into 0.
22222262 JITCompiler::Jump isBoolean = m_jit.branch32(JITCompiler::Equal, tagGPR, TrustedImm32(JSValue::BooleanTag));

@@void SpeculativeJIT::compileValueToInt32
22292269
22302270 isNumber.link(&m_jit);
22312271 }
2232  }
22332272
2234  unboxDouble(tagGPR, payloadGPR, fpr, scratch.fpr());
 2273 unboxDouble(tagGPR, payloadGPR, fpr, scratch.fpr());
22352274
2236  silentSpillAllRegisters(resultGpr);
2237  callOperation(toInt32, resultGpr, fpr);
2238  silentFillAllRegisters(resultGpr);
 2275 silentSpillAllRegisters(resultGpr);
 2276 callOperation(toInt32, resultGpr, fpr);
 2277 silentFillAllRegisters(resultGpr);
22392278
2240  converted.append(m_jit.jump());
 2279 converted.append(m_jit.jump());
22412280
2242  isInteger.link(&m_jit);
2243  m_jit.move(payloadGPR, resultGpr);
 2281 isInteger.link(&m_jit);
 2282 m_jit.move(payloadGPR, resultGpr);
22442283
2245  converted.link(&m_jit);
2246  }
 2284 converted.link(&m_jit);
 2285 }
22472286#endif
2248  integerResult(resultGpr, node);
 2287 integerResult(resultGpr, node);
 2288 return;
 2289 }
 2290 case GeneratedOperandTypeUnknown:
 2291 RELEASE_ASSERT_NOT_REACHED();
 2292 return;
 2293 }
 2294 RELEASE_ASSERT_NOT_REACHED();
22492295 return;
22502296 }
2251  case GeneratedOperandTypeUnknown:
 2297
 2298 case BooleanUse: {
 2299 SpeculateBooleanOperand op1(this, node->child1());
 2300 GPRTemporary result(this, op1);
 2301
 2302 m_jit.move(op1.gpr(), result.gpr());
 2303 m_jit.and32(JITCompiler::TrustedImm32(1), result.gpr());
 2304
 2305 integerResult(result.gpr(), node);
 2306 return;
 2307 }
 2308
 2309 default:
22522310 ASSERT(!m_compileOkay);
2253  break;
 2311 return;
22542312 }
22552313}
22562314

@@void SpeculativeJIT::compileInt32ToDoubl
23132371 ASSERT(!isInt32Constant(node->child1().node())); // This should have been constant folded.
23142372
23152373 if (isInt32Speculation(m_state.forNode(node->child1()).m_type)) {
2316  SpeculateIntegerOperand op1(this, node->child1());
 2374 SpeculateIntegerOperand op1(this, node->child1(), BackwardSpeculation, ManualOperandSpeculation);
23172375 FPRTemporary result(this);
23182376 m_jit.convertInt32ToDouble(op1.gpr(), result.fpr());
23192377 doubleResult(result.fpr(), node);
23202378 return;
23212379 }
23222380
2323  JSValueOperand op1(this, node->child1());
 2381 JSValueOperand op1(this, node->child1(), ManualOperandSpeculation);
23242382 FPRTemporary result(this);
23252383
23262384#if USE(JSVALUE64)

@@void SpeculativeJIT::compileInt32ToDoubl
23332391 JITCompiler::Jump isInteger = m_jit.branch64(
23342392 MacroAssembler::AboveOrEqual, op1GPR, GPRInfo::tagTypeNumberRegister);
23352393
2336  if (!isNumberSpeculation(m_state.forNode(node->child1()).m_type)) {
 2394 if (needsTypeCheck(node->child1(), SpecNumber)) {
23372395 if (node->op() == ForwardInt32ToDouble) {
2338  forwardSpeculationCheck(
2339  BadType, JSValueRegs(op1GPR), node->child1().node(),
 2396 forwardTypeCheck(
 2397 JSValueRegs(op1GPR), node->child1(), SpecNumber,
23402398 m_jit.branchTest64(MacroAssembler::Zero, op1GPR, GPRInfo::tagTypeNumberRegister),
23412399 ValueRecovery::inGPR(op1GPR, DataFormatJS));
23422400 } else {
2343  speculationCheck(
2344  BadType, JSValueRegs(op1GPR), node->child1(),
 2401 typeCheck(
 2402 JSValueRegs(op1GPR), node->child1(), SpecNumber,
23452403 m_jit.branchTest64(MacroAssembler::Zero, op1GPR, GPRInfo::tagTypeNumberRegister));
23462404 }
23472405 }

@@void SpeculativeJIT::compileInt32ToDoubl
23642422 JITCompiler::Jump isInteger = m_jit.branch32(
23652423 MacroAssembler::Equal, op1TagGPR, TrustedImm32(JSValue::Int32Tag));
23662424
2367  if (!isNumberSpeculation(m_state.forNode(node->child1()).m_type)) {
 2425 if (needsTypeCheck(node->child1(), SpecNumber)) {
23682426 if (node->op() == ForwardInt32ToDouble) {
2369  forwardSpeculationCheck(
2370  BadType, JSValueRegs(op1TagGPR, op1PayloadGPR), node->child1().node(),
 2427 forwardTypeCheck(
 2428 JSValueRegs(op1TagGPR, op1PayloadGPR), node->child1(), SpecNumber,
23712429 m_jit.branch32(MacroAssembler::AboveOrEqual, op1TagGPR, TrustedImm32(JSValue::LowestTag)),
23722430 ValueRecovery::inPair(op1TagGPR, op1PayloadGPR));
23732431 } else {
2374  speculationCheck(
2375  BadType, JSValueRegs(op1TagGPR, op1PayloadGPR), node->child1(),
 2432 typeCheck(
 2433 JSValueRegs(op1TagGPR, op1PayloadGPR), node->child1(), SpecNumber,
23762434 m_jit.branch32(MacroAssembler::AboveOrEqual, op1TagGPR, TrustedImm32(JSValue::LowestTag)));
23772435 }
23782436 }

@@void SpeculativeJIT::compilePutByValForI
25252583 m_jit.move(Imm32(toInt32(d)), scratchReg);
25262584 value.adopt(scratch);
25272585 valueGPR = scratchReg;
2528  } else if (valueUse->shouldSpeculateInteger()) {
2529  SpeculateIntegerOperand valueOp(this, valueUse);
2530  GPRTemporary scratch(this);
2531  GPRReg scratchReg = scratch.gpr();
2532  m_jit.move(valueOp.gpr(), scratchReg);
2533  if (rounding == ClampRounding) {
2534  ASSERT(elementSize == 1);
2535  compileClampIntegerToByte(m_jit, scratchReg);
2536  }
2537  value.adopt(scratch);
2538  valueGPR = scratchReg;
2539  } else if (rounding == ClampRounding) {
2540  ASSERT(elementSize == 1);
2541  SpeculateDoubleOperand valueOp(this, valueUse);
2542  GPRTemporary result(this);
2543  FPRTemporary floatScratch(this);
2544  FPRReg fpr = valueOp.fpr();
2545  GPRReg gpr = result.gpr();
2546  compileClampDoubleToByte(m_jit, gpr, fpr, floatScratch.fpr());
2547  value.adopt(result);
2548  valueGPR = gpr;
25492586 } else {
2550  SpeculateDoubleOperand valueOp(this, valueUse);
2551  GPRTemporary result(this);
2552  FPRReg fpr = valueOp.fpr();
2553  GPRReg gpr = result.gpr();
2554  MacroAssembler::Jump notNaN = m_jit.branchDouble(MacroAssembler::DoubleEqual, fpr, fpr);
2555  m_jit.xorPtr(gpr, gpr);
2556  MacroAssembler::Jump fixed = m_jit.jump();
2557  notNaN.link(&m_jit);
2558 
2559  MacroAssembler::Jump failed;
2560  if (signedness == SignedTypedArray)
2561  failed = m_jit.branchTruncateDoubleToInt32(fpr, gpr, MacroAssembler::BranchIfTruncateFailed);
2562  else
2563  failed = m_jit.branchTruncateDoubleToUint32(fpr, gpr, MacroAssembler::BranchIfTruncateFailed);
2564 
2565  addSlowPathGenerator(slowPathCall(failed, this, toInt32, gpr, fpr));
2566 
2567  fixed.link(&m_jit);
2568  value.adopt(result);
2569  valueGPR = gpr;
 2587 switch (valueUse.useKind()) {
 2588 case Int32Use: {
 2589 SpeculateIntegerOperand valueOp(this, valueUse);
 2590 GPRTemporary scratch(this);
 2591 GPRReg scratchReg = scratch.gpr();
 2592 m_jit.move(valueOp.gpr(), scratchReg);
 2593 if (rounding == ClampRounding) {
 2594 ASSERT(elementSize == 1);
 2595 compileClampIntegerToByte(m_jit, scratchReg);
 2596 }
 2597 value.adopt(scratch);
 2598 valueGPR = scratchReg;
 2599 break;
 2600 }
 2601
 2602 case NumberUse: {
 2603 if (rounding == ClampRounding) {
 2604 ASSERT(elementSize == 1);
 2605 SpeculateDoubleOperand valueOp(this, valueUse);
 2606 GPRTemporary result(this);
 2607 FPRTemporary floatScratch(this);
 2608 FPRReg fpr = valueOp.fpr();
 2609 GPRReg gpr = result.gpr();
 2610 compileClampDoubleToByte(m_jit, gpr, fpr, floatScratch.fpr());
 2611 value.adopt(result);
 2612 valueGPR = gpr;
 2613 } else {
 2614 SpeculateDoubleOperand valueOp(this, valueUse);
 2615 GPRTemporary result(this);
 2616 FPRReg fpr = valueOp.fpr();
 2617 GPRReg gpr = result.gpr();
 2618 MacroAssembler::Jump notNaN = m_jit.branchDouble(MacroAssembler::DoubleEqual, fpr, fpr);
 2619 m_jit.xorPtr(gpr, gpr);
 2620 MacroAssembler::Jump fixed = m_jit.jump();
 2621 notNaN.link(&m_jit);
 2622
 2623 MacroAssembler::Jump failed;
 2624 if (signedness == SignedTypedArray)
 2625 failed = m_jit.branchTruncateDoubleToInt32(fpr, gpr, MacroAssembler::BranchIfTruncateFailed);
 2626 else
 2627 failed = m_jit.branchTruncateDoubleToUint32(fpr, gpr, MacroAssembler::BranchIfTruncateFailed);
 2628
 2629 addSlowPathGenerator(slowPathCall(failed, this, toInt32, gpr, fpr));
 2630
 2631 fixed.link(&m_jit);
 2632 value.adopt(result);
 2633 valueGPR = gpr;
 2634 }
 2635 break;
 2636 }
 2637
 2638 default:
 2639 RELEASE_ASSERT_NOT_REACHED();
 2640 break;
 2641 }
25702642 }
 2643
25712644 ASSERT_UNUSED(valueGPR, valueGPR != property);
25722645 ASSERT(valueGPR != base);
25732646 ASSERT(valueGPR != storageReg);

@@void SpeculativeJIT::compileInstanceOfFo
27092782
27102783void SpeculativeJIT::compileInstanceOf(Node* node)
27112784{
2712  if ((!!(node->child1()->prediction() & ~SpecCell) && !!(m_state.forNode(node->child1()).m_type & ~SpecCell))
2713  || node->child1()->adjustedRefCount() == 1) {
 2785 if (node->child1().useKind() == UntypedUse) {
27142786 // It might not be a cell. Speculate less aggressively.
27152787 // Or: it might only be used once (i.e. by us), so we get zero benefit
27162788 // from speculating any more aggressively than we absolutely need to.

@@void SpeculativeJIT::compileSoftModulo(N
29483020
29493021void SpeculativeJIT::compileAdd(Node* node)
29503022{
2951  if (m_jit.graph().addShouldSpeculateInteger(node)) {
 3023 switch (node->binaryUseKind()) {
 3024 case Int32Use: {
29523025 if (isNumberConstant(node->child1().node())) {
2953  int32_t imm1 = valueOfNumberConstantAsInt32(node->child1().node());
 3026 int32_t imm1 = valueOfInt32Constant(node->child1().node());
29543027 SpeculateIntegerOperand op2(this, node->child2());
29553028 GPRTemporary result(this);
29563029

@@void SpeculativeJIT::compileAdd(Node* no
29663039
29673040 if (isNumberConstant(node->child2().node())) {
29683041 SpeculateIntegerOperand op1(this, node->child1());
2969  int32_t imm2 = valueOfNumberConstantAsInt32(node->child2().node());
 3042 int32_t imm2 = valueOfInt32Constant(node->child2().node());
29703043 GPRTemporary result(this);
29713044
29723045 if (nodeCanTruncateInteger(node->arithNodeFlags())) {

@@void SpeculativeJIT::compileAdd(Node* no
30083081 integerResult(gprResult, node);
30093082 return;
30103083 }
3011 
3012  if (Node::shouldSpeculateNumberExpectingDefined(node->child1().node(), node->child2().node())) {
 3084
 3085 case NumberUse: {
30133086 SpeculateDoubleOperand op1(this, node->child1());
30143087 SpeculateDoubleOperand op2(this, node->child2());
30153088 FPRTemporary result(this, op1, op2);

@@void SpeculativeJIT::compileAdd(Node* no
30213094 doubleResult(result.fpr(), node);
30223095 return;
30233096 }
3024 
3025  if (node->op() == ValueAdd) {
 3097
 3098 case UntypedUse: {
 3099 RELEASE_ASSERT(node->op() == ValueAdd);
30263100 compileValueAdd(node);
30273101 return;
30283102 }
3029 
3030  // We don't handle this yet. :-(
3031  terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
 3103
 3104 default:
 3105 RELEASE_ASSERT_NOT_REACHED();
 3106 break;
 3107 }
30323108}
30333109
30343110void SpeculativeJIT::compileArithSub(Node* node)
30353111{
3036  if (m_jit.graph().addShouldSpeculateInteger(node)) {
 3112 switch (node->binaryUseKind()) {
 3113 case Int32Use: {
30373114 if (isNumberConstant(node->child2().node())) {
30383115 SpeculateIntegerOperand op1(this, node->child1());
3039  int32_t imm2 = valueOfNumberConstantAsInt32(node->child2().node());
 3116 int32_t imm2 = valueOfInt32Constant(node->child2().node());
30403117 GPRTemporary result(this);
30413118
30423119 if (nodeCanTruncateInteger(node->arithNodeFlags())) {

@@void SpeculativeJIT::compileArithSub(Nod
30563133 }
30573134
30583135 if (isNumberConstant(node->child1().node())) {
3059  int32_t imm1 = valueOfNumberConstantAsInt32(node->child1().node());
 3136 int32_t imm1 = valueOfInt32Constant(node->child1().node());
30603137 SpeculateIntegerOperand op2(this, node->child2());
30613138 GPRTemporary result(this);
30623139

@@void SpeculativeJIT::compileArithSub(Nod
30843161 return;
30853162 }
30863163
3087  SpeculateDoubleOperand op1(this, node->child1());
3088  SpeculateDoubleOperand op2(this, node->child2());
3089  FPRTemporary result(this, op1);
 3164 case NumberUse: {
 3165 SpeculateDoubleOperand op1(this, node->child1());
 3166 SpeculateDoubleOperand op2(this, node->child2());
 3167 FPRTemporary result(this, op1);
30903168
3091  FPRReg reg1 = op1.fpr();
3092  FPRReg reg2 = op2.fpr();
3093  m_jit.subDouble(reg1, reg2, result.fpr());
 3169 FPRReg reg1 = op1.fpr();
 3170 FPRReg reg2 = op2.fpr();
 3171 m_jit.subDouble(reg1, reg2, result.fpr());
30943172
3095  doubleResult(result.fpr(), node);
 3173 doubleResult(result.fpr(), node);
 3174 return;
 3175 }
 3176
 3177 default:
 3178 RELEASE_ASSERT_NOT_REACHED();
 3179 return;
 3180 }
30963181}
30973182
30983183void SpeculativeJIT::compileArithNegate(Node* node)
30993184{
3100  if (m_jit.graph().negateShouldSpeculateInteger(node)) {
 3185 switch (node->child1().useKind()) {
 3186 case Int32Use: {
31013187 SpeculateIntegerOperand op1(this, node->child1());
31023188 GPRTemporary result(this);
31033189

@@void SpeculativeJIT::compileArithNegate(
31153201 return;
31163202 }
31173203
3118  SpeculateDoubleOperand op1(this, node->child1());
3119  FPRTemporary result(this);
3120 
3121  m_jit.negateDouble(op1.fpr(), result.fpr());
3122 
3123  doubleResult(result.fpr(), node);
 3204 case NumberUse: {
 3205 SpeculateDoubleOperand op1(this, node->child1());
 3206 FPRTemporary result(this);
 3207
 3208 m_jit.negateDouble(op1.fpr(), result.fpr());
 3209
 3210 doubleResult(result.fpr(), node);
 3211 return;
 3212 }
 3213
 3214 default:
 3215 RELEASE_ASSERT_NOT_REACHED();
 3216 return;
 3217 }
31243218}
31253219
31263220void SpeculativeJIT::compileArithMul(Node* node)
31273221{
3128  if (m_jit.graph().mulShouldSpeculateInteger(node)) {
 3222 switch (node->binaryUseKind()) {
 3223 case Int32Use: {
31293224 SpeculateIntegerOperand op1(this, node->child1());
31303225 SpeculateIntegerOperand op2(this, node->child2());
31313226 GPRTemporary result(this);

@@void SpeculativeJIT::compileArithMul(Nod
31563251 integerResult(result.gpr(), node);
31573252 return;
31583253 }
3159 
3160  SpeculateDoubleOperand op1(this, node->child1());
3161  SpeculateDoubleOperand op2(this, node->child2());
3162  FPRTemporary result(this, op1, op2);
3163 
3164  FPRReg reg1 = op1.fpr();
3165  FPRReg reg2 = op2.fpr();
31663254
3167  m_jit.mulDouble(reg1, reg2, result.fpr());
 3255 case NumberUse: {
 3256 SpeculateDoubleOperand op1(this, node->child1());
 3257 SpeculateDoubleOperand op2(this, node->child2());
 3258 FPRTemporary result(this, op1, op2);
 3259
 3260 FPRReg reg1 = op1.fpr();
 3261 FPRReg reg2 = op2.fpr();
 3262
 3263 m_jit.mulDouble(reg1, reg2, result.fpr());
31683264
3169  doubleResult(result.fpr(), node);
 3265 doubleResult(result.fpr(), node);
 3266 return;
 3267 }
 3268
 3269 default:
 3270 RELEASE_ASSERT_NOT_REACHED();
 3271 return;
 3272 }
31703273}
31713274
31723275#if CPU(X86) || CPU(X86_64)

@@void SpeculativeJIT::compileIntegerArith
32763379
32773380void SpeculativeJIT::compileArithMod(Node* node)
32783381{
3279  if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node())
3280  && node->canSpeculateInteger()) {
 3382 switch (node->binaryUseKind()) {
 3383 case Int32Use: {
32813384 compileSoftModulo(node);
32823385 return;
32833386 }
32843387
3285  SpeculateDoubleOperand op1(this, node->child1());
3286  SpeculateDoubleOperand op2(this, node->child2());
 3388 case NumberUse: {
 3389 SpeculateDoubleOperand op1(this, node->child1());
 3390 SpeculateDoubleOperand op2(this, node->child2());
32873391
3288  FPRReg op1FPR = op1.fpr();
3289  FPRReg op2FPR = op2.fpr();
 3392 FPRReg op1FPR = op1.fpr();
 3393 FPRReg op2FPR = op2.fpr();
32903394
3291  flushRegisters();
 3395 flushRegisters();
32923396
3293  FPRResult result(this);
3294 
3295  callOperation(fmodAsDFGOperation, result.fpr(), op1FPR, op2FPR);
 3397 FPRResult result(this);
 3398
 3399 callOperation(fmodAsDFGOperation, result.fpr(), op1FPR, op2FPR);
 3400
 3401 doubleResult(result.fpr(), node);
 3402 return;
 3403 }
32963404
3297  doubleResult(result.fpr(), node);
 3405 default:
 3406 RELEASE_ASSERT_NOT_REACHED();
 3407 return;
 3408 }
32983409}
32993410
33003411// Returns true if the compare is fused with a subsequent branch.

@@bool SpeculativeJIT::compare(Node* node,
33033414 if (compilePeepHoleBranch(node, condition, doubleCondition, operation))
33043415 return true;
33053416
3306  if (Node::shouldSpeculateInteger(node->child1().node(), node->child2().node())) {
 3417 if (node->isBinaryUseKind(Int32Use)) {
33073418 compileIntegerCompare(node, condition);
33083419 return false;
33093420 }
3310 
3311  if (Node::shouldSpeculateNumber(node->child1().node(), node->child2().node())) {
 3421
 3422 if (node->isBinaryUseKind(NumberUse)) {
33123423 compileDoubleCompare(node, doubleCondition);
33133424 return false;
33143425 }
33153426
33163427 if (node->op() == CompareEq) {
3317  if (node->child1()->shouldSpeculateString() || node->child2()->shouldSpeculateString()) {
 3428 if (node->isBinaryUseKind(StringUse)) {
33183429 nonSpeculativeNonPeepholeCompare(node, condition, operation);
33193430 return false;
33203431 }
3321 
3322  if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
 3432
 3433 if (node->isBinaryUseKind(ObjectUse)) {
33233434 compileObjectEquality(node);
33243435 return false;
33253436 }
33263437
3327  if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObjectOrOther()) {
 3438 if (node->child1().useKind() == ObjectUse && node->child2().useKind() == ObjectOrOtherUse) {
33283439 compileObjectToObjectOrOtherEquality(node->child1(), node->child2());
33293440 return false;
33303441 }
33313442
3332  if (node->child1()->shouldSpeculateObjectOrOther() && node->child2()->shouldSpeculateObject()) {
 3443 if (node->child1().useKind() == ObjectOrOtherUse && node->child2().useKind() == ObjectUse) {
33333444 compileObjectToObjectOrOtherEquality(node->child2(), node->child1());
33343445 return false;
33353446 }

@@bool SpeculativeJIT::compileStrictEqForC
34173528
34183529bool SpeculativeJIT::compileStrictEq(Node* node)
34193530{
3420  if (Node::shouldSpeculateInteger(node->child1().node(), node->child2().node())) {
 3531 switch (node->binaryUseKind()) {
 3532 case Int32Use: {
34213533 unsigned branchIndexInBlock = detectPeepHoleBranch();
34223534 if (branchIndexInBlock != UINT_MAX) {
34233535 Node* branchNode = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);

@@bool SpeculativeJIT::compileStrictEq(Nod
34313543 compileIntegerCompare(node, MacroAssembler::Equal);
34323544 return false;
34333545 }
3434 
3435  if (Node::shouldSpeculateNumber(node->child1().node(), node->child2().node())) {
 3546
 3547 case NumberUse: {
34363548 unsigned branchIndexInBlock = detectPeepHoleBranch();
34373549 if (branchIndexInBlock != UINT_MAX) {
34383550 Node* branchNode = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);

@@bool SpeculativeJIT::compileStrictEq(Nod
34463558 compileDoubleCompare(node, MacroAssembler::DoubleEqual);
34473559 return false;
34483560 }
3449 
3450  if (node->child1()->shouldSpeculateString() || node->child2()->shouldSpeculateString())
 3561
 3562 case StringUse: {
34513563 return nonSpeculativeStrictEq(node);
3452  if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
 3564 }
 3565
 3566 case ObjectUse: {
34533567 unsigned branchIndexInBlock = detectPeepHoleBranch();
34543568 if (branchIndexInBlock != UINT_MAX) {
34553569 Node* branchNode = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);

@@bool SpeculativeJIT::compileStrictEq(Nod
34633577 compileObjectEquality(node);
34643578 return false;
34653579 }
3466 
3467  return nonSpeculativeStrictEq(node);
 3580
 3581 case UntypedUse: {
 3582 return nonSpeculativeStrictEq(node);
 3583 }
 3584
 3585 default:
 3586 RELEASE_ASSERT_NOT_REACHED();
 3587 return false;
 3588 }
34683589}
34693590
34703591void SpeculativeJIT::compileGetIndexedPropertyStorage(Node* node)

@@GPRReg SpeculativeJIT::temporaryRegister
38023923 return temporary.gpr();
38033924}
38043925
 3926void SpeculativeJIT::speculateInt32(Edge edge)
 3927{
 3928 if (!needsTypeCheck(edge, SpecInt32))
 3929 return;
 3930
 3931 (SpeculateIntegerOperand(this, edge)).gpr();
 3932}
 3933
 3934void SpeculativeJIT::speculateNumber(Edge edge)
 3935{
 3936 if (!needsTypeCheck(edge, SpecNumber))
 3937 return;
 3938
 3939 JSValueOperand operand(this, edge, ManualOperandSpeculation);
 3940#if USE(JSVALUE64)
 3941 JITCompiler::Jump isInteger = m_jit.branch64(MacroAssembler::AboveOrEqual, operand.gpr(), GPRInfo::tagTypeNumberRegister);
 3942 typeCheck(
 3943 JSValueRegs(operand.gpr()), edge, SpecNumber,
 3944 m_jit.branchTest64(MacroAssembler::Zero, operand.gpr(), GPRInfo::tagTypeNumberRegister));
 3945 isInteger.link(&m_jit);
 3946#else
 3947 JSValueOperand op1(this, edge);
 3948 JITCompiler::Jump isInteger = m_jit.branch32(MacroAssembler::Equal, operand.tagGPR(), TrustedImm32(JSValue::Int32Tag));
 3949 typeCheck(
 3950 JSValueRegs(operand.tagGPR(), op1.payloadGPR()), edge, SpecNumber,
 3951 m_jit.branch32(MacroAssembler::AboveOrEqual, operand.tagGPR(), TrustedImm32(JSValue::LowestTag)));
 3952 isInteger.link(&m_jit);
 3953#endif
 3954}
 3955
 3956void SpeculativeJIT::speculateRealNumber(Edge edge)
 3957{
 3958 if (!needsTypeCheck(edge, SpecRealNumber))
 3959 return;
 3960
 3961 SpeculateDoubleOperand operand(this, edge);
 3962 FPRReg fpr = operand.fpr();
 3963 DFG_TYPE_CHECK(
 3964 JSValueRegs(), edge, SpecRealNumber,
 3965 m_jit.branchDouble(
 3966 MacroAssembler::DoubleNotEqualOrUnordered, fpr, fpr));
 3967}
 3968
 3969void SpeculativeJIT::speculateBoolean(Edge edge)
 3970{
 3971 if (!needsTypeCheck(edge, SpecBoolean))
 3972 return;
 3973
 3974 (SpeculateBooleanOperand(this, edge)).gpr();
 3975}
 3976
 3977void SpeculativeJIT::speculateCell(Edge edge)
 3978{
 3979 if (!needsTypeCheck(edge, SpecCell))
 3980 return;
 3981
 3982 (SpeculateCellOperand(this, edge)).gpr();
 3983}
 3984
 3985void SpeculativeJIT::speculateObject(Edge edge)
 3986{
 3987 if (!needsTypeCheck(edge, SpecObject))
 3988 return;
 3989
 3990 SpeculateCellOperand operand(this, edge);
 3991 DFG_TYPE_CHECK(
 3992 JSValueSource::unboxedCell(operand.gpr()), edge, SpecObject, m_jit.branchPtr(
 3993 MacroAssembler::Equal,
 3994 MacroAssembler::Address(operand.gpr(), JSCell::structureOffset()),
 3995 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
 3996}
 3997
 3998void SpeculativeJIT::speculateObjectOrOther(Edge edge)
 3999{
 4000 if (!needsTypeCheck(edge, SpecObject | SpecOther))
 4001 return;
 4002
 4003 JSValueOperand operand(this, edge, ManualOperandSpeculation);
 4004 GPRTemporary temp(this);
 4005 GPRReg tempGPR = temp.gpr();
 4006#if USE(JSVALUE64)
 4007 GPRReg gpr = operand.gpr();
 4008 MacroAssembler::Jump notCell = m_jit.branchTest64(
 4009 MacroAssembler::NonZero, gpr, GPRInfo::tagMaskRegister);
 4010 DFG_TYPE_CHECK(
 4011 JSValueRegs(operand.gpr()), edge, (~SpecCell) | SpecObject, m_jit.branchPtr(
 4012 MacroAssembler::Equal,
 4013 MacroAssembler::Address(gpr, JSCell::structureOffset()),
 4014 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
 4015 MacroAssembler::Jump done = m_jit.jump();
 4016 notCell.link(&m_jit);
 4017 if (needsTypeCheck(edge, SpecCell | SpecOther)) {
 4018 m_jit.move(gpr, tempGPR);
 4019 m_jit.and64(MacroAssembler::TrustedImm32(~TagBitUndefined), tempGPR);
 4020
 4021 typeCheck(
 4022 JSValueRegs(gpr), edge, SpecCell | SpecOther,
 4023 m_jit.branch64(
 4024 MacroAssembler::NotEqual, tempGPR,
 4025 MacroAssembler::TrustedImm64(ValueNull)));
 4026 }
 4027 done.link(&m_jit);
 4028#else
 4029 GPRReg tagGPR = operand.tagGPR();
 4030 GPRReg payloadGPR = operand.payloadGPR();
 4031 MacroAssembler::Jump notCell =
 4032 m_jit.branch32(MacroAssembler::NotEqual, tagGPR, TrustedImm32(JSValue::CellTag));
 4033 DFG_TYPE_CHECK(
 4034 JSValueRegs(tagGPR, payloadGPR), edge, (~SpecCell) | SpecObject, m_jit.branchPtr(
 4035 MacroAssembler::Equal,
 4036 MacroAssembler::Address(payloadGPR, JSCell::structureOffset()),
 4037 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
 4038 MacroAssembler::Jump done = m_jit.jump();
 4039 notCell.link(&m_jit);
 4040 if (needsTypeCheck(edge, SpecCell | SpecOther)) {
 4041 m_jit.move(tagGPR, tempGPR);
 4042 m_jit.or32(TrustedImm32(1), tempGPR);
 4043
 4044 typeCheck(
 4045 JSValueRegs(tagGPR, payloadGPR), edge, SpecCell | SpecOther,
 4046 m_jit.branch32(
 4047 MacroAssembler::NotEqual, tempGPR,
 4048 MacroAssembler::TrustedImm32(JSValue::NullTag)));
 4049 }
 4050 done.link(&m_jit);
 4051#endif
 4052}
 4053
 4054void SpeculativeJIT::speculateString(Edge edge)
 4055{
 4056 if (!needsTypeCheck(edge, SpecString))
 4057 return;
 4058
 4059 SpeculateCellOperand operand(this, edge);
 4060 DFG_TYPE_CHECK(
 4061 JSValueSource::unboxedCell(operand.gpr()), edge, SpecString, m_jit.branchPtr(
 4062 MacroAssembler::NotEqual,
 4063 MacroAssembler::Address(operand.gpr(), JSCell::structureOffset()),
 4064 MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
 4065}
 4066
 4067void SpeculativeJIT::speculateNotCell(Edge edge)
 4068{
 4069 if (!needsTypeCheck(edge, ~SpecCell))
 4070 return;
 4071
 4072 JSValueOperand operand(this, edge, ManualOperandSpeculation);
 4073#if USE(JSVALUE64)
 4074 typeCheck(
 4075 JSValueRegs(operand.gpr()), edge, ~SpecCell,
 4076 m_jit.branchTest64(
 4077 JITCompiler::Zero, operand.gpr(), GPRInfo::tagMaskRegister));
 4078#else
 4079 typeCheck(
 4080 JSValueRegs(operand.tagGPR(), operand.payloadGPR()), edge, ~SpecCell,
 4081 m_jit.branch32(
 4082 JITCompiler::Equal, operand.tagGPR(), TrustedImm32(JSValue::CellTag)));
 4083#endif
 4084}
 4085
 4086void SpeculativeJIT::speculateOther(Edge edge)
 4087{
 4088 if (!needsTypeCheck(edge, SpecOther))
 4089 return;
 4090
 4091 JSValueOperand operand(this, edge, ManualOperandSpeculation);
 4092 GPRTemporary temp(this);
 4093 GPRReg tempGPR = temp.gpr();
 4094#if USE(JSVALUE64)
 4095 m_jit.move(operand.gpr(), tempGPR);
 4096 m_jit.and64(MacroAssembler::TrustedImm32(~TagBitUndefined), tempGPR);
 4097 typeCheck(
 4098 JSValueRegs(operand.gpr()), edge, SpecOther,
 4099 m_jit.branch64(
 4100 MacroAssembler::NotEqual, tempGPR,
 4101 MacroAssembler::TrustedImm64(ValueNull)));
 4102#else
 4103 m_jit.move(operand.tagGPR(), tempGPR);
 4104 m_jit.or32(TrustedImm32(1), tempGPR);
 4105 typeCheck(
 4106 JSValueRegs(operand.tagGPR(), operand.payloadGPR()), edge, SpecOther,
 4107 m_jit.branch32(MacroAssembler::NotEqual, tempGPR, TrustedImm32(JSValue::NullTag)));
 4108#endif
 4109}
 4110
 4111void SpeculativeJIT::speculate(Node*, Edge edge)
 4112{
 4113 switch (edge.useKind()) {
 4114 case UntypedUse:
 4115 break;
 4116 case KnownInt32Use:
 4117 ASSERT(!needsTypeCheck(edge, SpecInt32));
 4118 break;
 4119 case KnownNumberUse:
 4120 ASSERT(!needsTypeCheck(edge, SpecNumber));
 4121 break;
 4122 case KnownCellUse:
 4123 ASSERT(!needsTypeCheck(edge, SpecCell));
 4124 break;
 4125 case Int32Use:
 4126 speculateInt32(edge);
 4127 break;
 4128 case RealNumberUse:
 4129 speculateRealNumber(edge);
 4130 break;
 4131 case NumberUse:
 4132 speculateNumber(edge);
 4133 break;
 4134 case BooleanUse:
 4135 speculateBoolean(edge);
 4136 break;
 4137 case CellUse:
 4138 speculateCell(edge);
 4139 break;
 4140 case ObjectUse:
 4141 speculateObject(edge);
 4142 break;
 4143 case ObjectOrOtherUse:
 4144 speculateObjectOrOther(edge);
 4145 break;
 4146 case StringUse:
 4147 speculateString(edge);
 4148 break;
 4149 case NotCellUse:
 4150 speculateNotCell(edge);
 4151 break;
 4152 case OtherUse:
 4153 speculateOther(edge);
 4154 break;
 4155 default:
 4156 RELEASE_ASSERT_NOT_REACHED();
 4157 break;
 4158 }
 4159}
 4160
38054161} } // namespace JSC::DFG
38064162
38074163#endif
143562

Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

@@public:
121121 }
122122 }
123123
124  GPRReg fillInteger(Node*, DataFormat& returnFormat);
 124 GPRReg fillInteger(Edge, DataFormat& returnFormat);
125125#if USE(JSVALUE64)
126  GPRReg fillJSValue(Node*);
 126 GPRReg fillJSValue(Edge);
127127#elif USE(JSVALUE32_64)
128  bool fillJSValue(Node*, GPRReg&, GPRReg&, FPRReg&);
 128 bool fillJSValue(Edge, GPRReg&, GPRReg&, FPRReg&);
129129#endif
130  GPRReg fillStorage(Node*);
 130 GPRReg fillStorage(Edge);
131131
132132 // lock and unlock GPR & FPR registers.
133133 void lock(GPRReg reg)

@@public:
295295
296296 // Called by the speculative operand types, below, to fill operand to
297297 // machine registers, implicitly generating speculation checks as needed.
298  GPRReg fillSpeculateInt(Node*, DataFormat& returnFormat, SpeculationDirection);
299  GPRReg fillSpeculateIntStrict(Node*);
300  FPRReg fillSpeculateDouble(Node*, SpeculationDirection);
301  GPRReg fillSpeculateCell(Node*, SpeculationDirection);
302  GPRReg fillSpeculateBoolean(Node*, SpeculationDirection);
 298 GPRReg fillSpeculateInt(Edge, DataFormat& returnFormat, SpeculationDirection);
 299 GPRReg fillSpeculateIntStrict(Edge);
 300 FPRReg fillSpeculateDouble(Edge, SpeculationDirection);
 301 GPRReg fillSpeculateCell(Edge, SpeculationDirection);
 302 GPRReg fillSpeculateBoolean(Edge, SpeculationDirection);
303303 GeneratedOperandType checkGeneratedTypeForToInt32(Node*);
304304
305305 void addSlowPathGenerator(PassOwnPtr<SlowPathGenerator>);

@@public:
540540 bool isFunctionConstant(Node* node) { return m_jit.graph().isFunctionConstant(node); }
541541 int32_t valueOfInt32Constant(Node* node) { return m_jit.graph().valueOfInt32Constant(node); }
542542 double valueOfNumberConstant(Node* node) { return m_jit.graph().valueOfNumberConstant(node); }
543  int32_t valueOfNumberConstantAsInt32(Node* node)
544  {
545  if (isInt32Constant(node))
546  return valueOfInt32Constant(node);
547  return JSC::toInt32(valueOfNumberConstant(node));
548  }
549543#if USE(JSVALUE32_64)
550544 void* addressOfDoubleConstant(Node* node) { return m_jit.addressOfDoubleConstant(node); }
551545#endif

@@public:
20232017 void compileObjectEquality(Node*);
20242018 void compileObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild);
20252019 void compileValueAdd(Node*);
2026  void compileObjectOrOtherLogicalNot(Edge value, bool needSpeculationCheck);
 2020 void compileObjectOrOtherLogicalNot(Edge value);
20272021 void compileLogicalNot(Node*);
2028  void emitObjectOrOtherBranch(Edge value, BlockIndex taken, BlockIndex notTaken, bool needSpeculationCheck);
 2022 void emitObjectOrOtherBranch(Edge value, BlockIndex taken, BlockIndex notTaken);
20292023 void emitBranch(Node*);
20302024
20312025 void compileIntegerCompare(Node*, MacroAssembler::RelationalCondition);

@@public:
21782172 void forwardSpeculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail, const ValueRecovery& = ValueRecovery());
21792173 void forwardSpeculationCheck(ExitKind, JSValueSource, Node*, const MacroAssembler::JumpList& jumpsToFail, const ValueRecovery& = ValueRecovery());
21802174 void speculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail, SpeculationDirection);
 2175 void speculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail, SpeculationDirection);
21812176 void speculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&, SpeculationDirection);
 2177 void speculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&, SpeculationDirection);
21822178 // Called when we statically determine that a speculation will fail.
21832179 void terminateSpeculativeExecution(ExitKind, JSValueRegs, Node*);
21842180 void terminateSpeculativeExecution(ExitKind, JSValueRegs, Edge);

@@public:
21882184 JumpReplacementWatchpoint* forwardSpeculationWatchpoint(ExitKind = UncountableWatchpoint);
21892185 JumpReplacementWatchpoint* speculationWatchpoint(ExitKind, SpeculationDirection);
21902186
 2187 // Helpers for performing type checks on an edge stored in the given registers.
 2188 bool needsTypeCheck(Edge edge, SpeculatedType typesPassedThrough) { return m_state.forNode(edge).m_type & ~typesPassedThrough; }
 2189 void typeCheck(JSValueSource, Edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail);
 2190 void forwardTypeCheck(JSValueSource, Edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail, const ValueRecovery&);
 2191 void typeCheck(JSValueSource, Edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail, SpeculationDirection);
 2192
 2193 void speculateInt32(Edge);
 2194 void speculateNumber(Edge);
 2195 void speculateRealNumber(Edge);
 2196 void speculateBoolean(Edge);
 2197 void speculateCell(Edge);
 2198 void speculateObject(Edge);
 2199 void speculateObjectOrOther(Edge);
 2200 void speculateString(Edge);
 2201 void speculateNotCell(Edge);
 2202 void speculateOther(Edge);
 2203 void speculate(Node*, Edge);
 2204
21912205 const TypedArrayDescriptor* typedArrayDescriptor(ArrayMode);
21922206
21932207 JITCompiler::Jump jumpSlowForUnwantedArrayMode(GPRReg tempWithIndexingTypeReg, ArrayMode, IndexingType, bool invert);

@@public:
21972211 void arrayify(Node*);
21982212
21992213 template<bool strict>
2200  GPRReg fillSpeculateIntInternal(Node*, DataFormat& returnFormat, SpeculationDirection);
 2214 GPRReg fillSpeculateIntInternal(Edge, DataFormat& returnFormat, SpeculationDirection);
22012215
22022216 // It is possible, during speculative generation, to reach a situation in which we
22032217 // can statically determine a speculation will fail (for example, when two nodes

@@public:
22472261 // The current node being generated.
22482262 BlockIndex m_block;
22492263 Node* m_currentNode;
 2264#if !ASSERT_DISABLED
 2265 bool m_canExit;
 2266#endif
22502267 unsigned m_indexInBlock;
22512268 // Virtual and physical register maps.
22522269 Vector<GenerationInfo, 32> m_generationInfo;

@@public:
23052322
23062323class IntegerOperand {
23072324public:
2308  explicit IntegerOperand(SpeculativeJIT* jit, Edge use)
 2325 explicit IntegerOperand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
23092326 : m_jit(jit)
2310  , m_node(use.node())
 2327 , m_edge(edge)
23112328 , m_gprOrInvalid(InvalidGPRReg)
23122329#ifndef NDEBUG
23132330 , m_format(DataFormatNone)
23142331#endif
23152332 {
23162333 ASSERT(m_jit);
2317  ASSERT(use.useKind() != DoubleUse);
2318  if (jit->isFilled(m_node))
 2334 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == KnownInt32Use);
 2335 if (jit->isFilled(edge.node()))
23192336 gpr();
23202337 }
23212338

@@public:
23252342 m_jit->unlock(m_gprOrInvalid);
23262343 }
23272344
 2345 Edge edge() const
 2346 {
 2347 return m_edge;
 2348 }
 2349
23282350 Node* node() const
23292351 {
2330  return m_node;
 2352 return edge().node();
23312353 }
23322354
23332355 DataFormat format()

@@public:
23402362 GPRReg gpr()
23412363 {
23422364 if (m_gprOrInvalid == InvalidGPRReg)
2343  m_gprOrInvalid = m_jit->fillInteger(node(), m_format);
 2365 m_gprOrInvalid = m_jit->fillInteger(m_edge, m_format);
23442366 return m_gprOrInvalid;
23452367 }
23462368
23472369 void use()
23482370 {
2349  m_jit->use(m_node);
 2371 m_jit->use(node());
23502372 }
23512373
23522374private:
23532375 SpeculativeJIT* m_jit;
2354  Node* m_node;
 2376 Edge m_edge;
23552377 GPRReg m_gprOrInvalid;
23562378 DataFormat m_format;
23572379};
23582380
23592381class JSValueOperand {
23602382public:
2361  explicit JSValueOperand(SpeculativeJIT* jit, Edge use)
 2383 explicit JSValueOperand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
23622384 : m_jit(jit)
2363  , m_node(use.node())
 2385 , m_edge(edge)
23642386#if USE(JSVALUE64)
23652387 , m_gprOrInvalid(InvalidGPRReg)
23662388#elif USE(JSVALUE32_64)

@@public:
23682390#endif
23692391 {
23702392 ASSERT(m_jit);
2371  ASSERT(use.useKind() != DoubleUse);
 2393 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == UntypedUse);
23722394#if USE(JSVALUE64)
2373  if (jit->isFilled(m_node))
 2395 if (jit->isFilled(node()))
23742396 gpr();
23752397#elif USE(JSVALUE32_64)
23762398 m_register.pair.tagGPR = InvalidGPRReg;
23772399 m_register.pair.payloadGPR = InvalidGPRReg;
2378  if (jit->isFilled(m_node))
 2400 if (jit->isFilled(node()))
23792401 fill();
23802402#endif
23812403 }

@@public:
23962418 }
23972419#endif
23982420 }
 2421
 2422 Edge edge() const
 2423 {
 2424 return m_edge;
 2425 }
23992426
24002427 Node* node() const
24012428 {
2402  return m_node;
 2429 return edge().node();
24032430 }
24042431
24052432#if USE(JSVALUE64)
24062433 GPRReg gpr()
24072434 {
24082435 if (m_gprOrInvalid == InvalidGPRReg)
2409  m_gprOrInvalid = m_jit->fillJSValue(node());
 2436 m_gprOrInvalid = m_jit->fillJSValue(m_edge);
24102437 return m_gprOrInvalid;
24112438 }
24122439 JSValueRegs jsValueRegs()

@@public:
24192446 void fill()
24202447 {
24212448 if (m_register.pair.tagGPR == InvalidGPRReg && m_register.pair.payloadGPR == InvalidGPRReg)
2422  m_isDouble = !m_jit->fillJSValue(node(), m_register.pair.tagGPR, m_register.pair.payloadGPR, m_register.fpr);
 2449 m_isDouble = !m_jit->fillJSValue(m_edge, m_register.pair.tagGPR, m_register.pair.payloadGPR, m_register.fpr);
24232450 }
24242451
24252452 GPRReg tagGPR()

@@public:
24512478
24522479 void use()
24532480 {
2454  m_jit->use(m_node);
 2481 m_jit->use(node());
24552482 }
24562483
24572484private:
24582485 SpeculativeJIT* m_jit;
2459  Node* m_node;
 2486 Edge m_edge;
24602487#if USE(JSVALUE64)
24612488 GPRReg m_gprOrInvalid;
24622489#elif USE(JSVALUE32_64)

@@private:
24732500
24742501class StorageOperand {
24752502public:
2476  explicit StorageOperand(SpeculativeJIT* jit, Edge use)
 2503 explicit StorageOperand(SpeculativeJIT* jit, Edge edge)
24772504 : m_jit(jit)
2478  , m_node(use.node())
 2505 , m_edge(edge)
24792506 , m_gprOrInvalid(InvalidGPRReg)
24802507 {
24812508 ASSERT(m_jit);
2482  ASSERT(use.useKind() != DoubleUse);
2483  if (jit->isFilled(m_node))
 2509 ASSERT(edge.useKind() == UntypedUse || edge.useKind() == KnownCellUse);
 2510 if (jit->isFilled(node()))
24842511 gpr();
24852512 }
24862513

@@public:
24902517 m_jit->unlock(m_gprOrInvalid);
24912518 }
24922519
 2520 Edge edge() const
 2521 {
 2522 return m_edge;
 2523 }
 2524
24932525 Node* node() const
24942526 {
2495  return m_node;
 2527 return edge().node();
24962528 }
24972529
24982530 GPRReg gpr()
24992531 {
25002532 if (m_gprOrInvalid == InvalidGPRReg)
2501  m_gprOrInvalid = m_jit->fillStorage(node());
 2533 m_gprOrInvalid = m_jit->fillStorage(edge());
25022534 return m_gprOrInvalid;
25032535 }
25042536
25052537 void use()
25062538 {
2507  m_jit->use(m_node);
 2539 m_jit->use(node());
25082540 }
25092541
25102542private:
25112543 SpeculativeJIT* m_jit;
2512  Node* m_node;
 2544 Edge m_edge;
25132545 GPRReg m_gprOrInvalid;
25142546};
25152547

@@private:
26412673
26422674class SpeculateIntegerOperand {
26432675public:
2644  explicit SpeculateIntegerOperand(SpeculativeJIT* jit, Edge use, SpeculationDirection direction = BackwardSpeculation)
 2676 explicit SpeculateIntegerOperand(SpeculativeJIT* jit, Edge edge, SpeculationDirection direction = BackwardSpeculation, OperandSpeculationMode mode = AutomaticOperandSpeculation)
26452677 : m_jit(jit)
2646  , m_node(use.node())
 2678 , m_edge(edge)
26472679 , m_gprOrInvalid(InvalidGPRReg)
26482680#ifndef NDEBUG
26492681 , m_format(DataFormatNone)

@@public:
26512683 , m_direction(direction)
26522684 {
26532685 ASSERT(m_jit);
2654  ASSERT(use.useKind() != DoubleUse);
2655  if (jit->isFilled(m_node))
 2686 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || (edge.useKind() == Int32Use || edge.useKind() == KnownInt32Use));
 2687 if (jit->isFilled(node()))
26562688 gpr();
26572689 }
26582690

@@public:
26612693 ASSERT(m_gprOrInvalid != InvalidGPRReg);
26622694 m_jit->unlock(m_gprOrInvalid);
26632695 }
 2696
 2697 Edge edge() const
 2698 {
 2699 return m_edge;
 2700 }
26642701
26652702 Node* node() const
26662703 {
2667  return m_node;
 2704 return edge().node();
26682705 }
26692706
26702707 DataFormat format()

@@public:
26772714 GPRReg gpr()
26782715 {
26792716 if (m_gprOrInvalid == InvalidGPRReg)
2680  m_gprOrInvalid = m_jit->fillSpeculateInt(node(), m_format, m_direction);
 2717 m_gprOrInvalid = m_jit->fillSpeculateInt(edge(), m_format, m_direction);
26812718 return m_gprOrInvalid;
26822719 }
26832720
26842721 void use()
26852722 {
2686  m_jit->use(m_node);
 2723 m_jit->use(node());
26872724 }
26882725
26892726private:
26902727 SpeculativeJIT* m_jit;
2691  Node* m_node;
 2728 Edge m_edge;
26922729 GPRReg m_gprOrInvalid;
26932730 DataFormat m_format;
26942731 SpeculationDirection m_direction;

@@private:
26962733
26972734class SpeculateStrictInt32Operand {
26982735public:
2699  explicit SpeculateStrictInt32Operand(SpeculativeJIT* jit, Edge use)
 2736 explicit SpeculateStrictInt32Operand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
27002737 : m_jit(jit)
2701  , m_node(use.node())
 2738 , m_edge(edge)
27022739 , m_gprOrInvalid(InvalidGPRReg)
27032740 {
27042741 ASSERT(m_jit);
2705  ASSERT(use.useKind() != DoubleUse);
2706  if (jit->isFilled(m_node))
 2742 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || (edge.useKind() == Int32Use || edge.useKind() == KnownInt32Use));
 2743 if (jit->isFilled(node()))
27072744 gpr();
27082745 }
27092746

@@public:
27122749 ASSERT(m_gprOrInvalid != InvalidGPRReg);
27132750 m_jit->unlock(m_gprOrInvalid);
27142751 }
 2752
 2753 Edge edge() const
 2754 {
 2755 return m_edge;
 2756 }
27152757
27162758 Node* node() const
27172759 {
2718  return m_node;
 2760 return edge().node();
27192761 }
27202762
27212763 GPRReg gpr()
27222764 {
27232765 if (m_gprOrInvalid == InvalidGPRReg)
2724  m_gprOrInvalid = m_jit->fillSpeculateIntStrict(node());
 2766 m_gprOrInvalid = m_jit->fillSpeculateIntStrict(edge());
27252767 return m_gprOrInvalid;
27262768 }
27272769
27282770 void use()
27292771 {
2730  m_jit->use(m_node);
 2772 m_jit->use(node());
27312773 }
27322774
27332775private:
27342776 SpeculativeJIT* m_jit;
2735  Node* m_node;
 2777 Edge m_edge;
27362778 GPRReg m_gprOrInvalid;
27372779};
27382780
27392781class SpeculateDoubleOperand {
27402782public:
2741  explicit SpeculateDoubleOperand(SpeculativeJIT* jit, Edge use, SpeculationDirection direction = BackwardSpeculation)
 2783 explicit SpeculateDoubleOperand(SpeculativeJIT* jit, Edge edge, SpeculationDirection direction = BackwardSpeculation, OperandSpeculationMode mode = AutomaticOperandSpeculation)
27422784 : m_jit(jit)
2743  , m_node(use.node())
 2785 , m_edge(edge)
27442786 , m_fprOrInvalid(InvalidFPRReg)
27452787 , m_direction(direction)
27462788 {
27472789 ASSERT(m_jit);
2748  ASSERT(use.useKind() == DoubleUse);
2749  if (jit->isFilled(m_node))
 2790 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || (edge.useKind() == NumberUse || edge.useKind() == KnownNumberUse || edge.useKind() == RealNumberUse));
 2791 if (jit->isFilled(node()))
27502792 fpr();
27512793 }
27522794

@@public:
27552797 ASSERT(m_fprOrInvalid != InvalidFPRReg);
27562798 m_jit->unlock(m_fprOrInvalid);
27572799 }
 2800
 2801 Edge edge() const
 2802 {
 2803 return m_edge;
 2804 }
27582805
27592806 Node* node() const
27602807 {
2761  return m_node;
 2808 return edge().node();
27622809 }
27632810
27642811 FPRReg fpr()
27652812 {
27662813 if (m_fprOrInvalid == InvalidFPRReg)
2767  m_fprOrInvalid = m_jit->fillSpeculateDouble(node(), m_direction);
 2814 m_fprOrInvalid = m_jit->fillSpeculateDouble(edge(), m_direction);
27682815 return m_fprOrInvalid;
27692816 }
27702817
27712818 void use()
27722819 {
2773  m_jit->use(m_node);
 2820 m_jit->use(node());
27742821 }
27752822
27762823private:
27772824 SpeculativeJIT* m_jit;
2778  Node* m_node;
 2825 Edge m_edge;
27792826 FPRReg m_fprOrInvalid;
27802827 SpeculationDirection m_direction;
27812828};
27822829
27832830class SpeculateCellOperand {
27842831public:
2785  explicit SpeculateCellOperand(SpeculativeJIT* jit, Edge use, SpeculationDirection direction = BackwardSpeculation)
 2832 explicit SpeculateCellOperand(SpeculativeJIT* jit, Edge edge, SpeculationDirection direction = BackwardSpeculation, OperandSpeculationMode mode = AutomaticOperandSpeculation)
27862833 : m_jit(jit)
2787  , m_node(use.node())
 2834 , m_edge(edge)
27882835 , m_gprOrInvalid(InvalidGPRReg)
27892836 , m_direction(direction)
27902837 {
27912838 ASSERT(m_jit);
2792  ASSERT(use.useKind() != DoubleUse);
2793  if (jit->isFilled(m_node))
 2839 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || (edge.useKind() == CellUse || edge.useKind() == KnownCellUse || edge.useKind() == ObjectUse || edge.useKind() == StringUse));
 2840 if (jit->isFilled(node()))
27942841 gpr();
27952842 }
27962843

@@public:
27992846 ASSERT(m_gprOrInvalid != InvalidGPRReg);
28002847 m_jit->unlock(m_gprOrInvalid);
28012848 }
 2849
 2850 Edge edge() const
 2851 {
 2852 return m_edge;
 2853 }
28022854
28032855 Node* node() const
28042856 {
2805  return m_node;
 2857 return edge().node();
28062858 }
28072859
28082860 GPRReg gpr()
28092861 {
28102862 if (m_gprOrInvalid == InvalidGPRReg)
2811  m_gprOrInvalid = m_jit->fillSpeculateCell(node(), m_direction);
 2863 m_gprOrInvalid = m_jit->fillSpeculateCell(edge(), m_direction);
28122864 return m_gprOrInvalid;
28132865 }
28142866
28152867 void use()
28162868 {
2817  m_jit->use(m_node);
 2869 m_jit->use(node());
28182870 }
28192871
28202872private:
28212873 SpeculativeJIT* m_jit;
2822  Node* m_node;
 2874 Edge m_edge;
28232875 GPRReg m_gprOrInvalid;
28242876 SpeculationDirection m_direction;
28252877};
28262878
28272879class SpeculateBooleanOperand {
28282880public:
2829  explicit SpeculateBooleanOperand(SpeculativeJIT* jit, Edge use, SpeculationDirection direction = BackwardSpeculation)
 2881 explicit SpeculateBooleanOperand(SpeculativeJIT* jit, Edge edge, SpeculationDirection direction = BackwardSpeculation, OperandSpeculationMode mode = AutomaticOperandSpeculation)
28302882 : m_jit(jit)
2831  , m_node(use.node())
 2883 , m_edge(edge)
28322884 , m_gprOrInvalid(InvalidGPRReg)
28332885 , m_direction(direction)
28342886 {
28352887 ASSERT(m_jit);
2836  ASSERT(use.useKind() != DoubleUse);
2837  if (jit->isFilled(m_node))
 2888 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == BooleanUse);
 2889 if (jit->isFilled(node()))
28382890 gpr();
28392891 }
28402892

@@public:
28442896 m_jit->unlock(m_gprOrInvalid);
28452897 }
28462898
 2899 Edge edge() const
 2900 {
 2901 return m_edge;
 2902 }
 2903
28472904 Node* node() const
28482905 {
2849  return m_node;
 2906 return edge().node();
28502907 }
28512908
28522909 GPRReg gpr()
28532910 {
28542911 if (m_gprOrInvalid == InvalidGPRReg)
2855  m_gprOrInvalid = m_jit->fillSpeculateBoolean(node(), m_direction);
 2912 m_gprOrInvalid = m_jit->fillSpeculateBoolean(edge(), m_direction);
28562913 return m_gprOrInvalid;
28572914 }
28582915
28592916 void use()
28602917 {
2861  m_jit->use(m_node);
 2918 m_jit->use(node());
28622919 }
28632920
28642921private:
28652922 SpeculativeJIT* m_jit;
2866  Node* m_node;
 2923 Edge m_edge;
28672924 GPRReg m_gprOrInvalid;
28682925 SpeculationDirection m_direction;
28692926};
28702927
 2928#define DFG_TYPE_CHECK(source, edge, typesPassedThrough, jumpToFail) do { \
 2929 if (!needsTypeCheck((edge), (typesPassedThrough))) \
 2930 break; \
 2931 typeCheck((source), (edge), (typesPassedThrough), (jumpToFail)); \
 2932 } while (0)
 2933
28712934} } // namespace JSC::DFG
28722935
28732936#endif
143562

Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp

@@public:
289289
290290 Node* getLocal = insertionSet.insertNode(
291291 indexInBlock + 1, DontRefChildren, DontRefNode, variable->prediction(),
292  GetLocal, codeOrigin, OpInfo(variable), node);
 292 GetLocal, codeOrigin, OpInfo(variable), Edge(node));
293293 insertionSet.insertNode(
294294 indexInBlock + 1, RefChildren, DontRefNode, SpecNone, CheckStructure,
295295 codeOrigin, OpInfo(m_graph.addStructureSet(iter->value.m_structure)),
296  getLocal);
 296 Edge(getLocal, CellUse));
297297
298298 if (block->variablesAtTail.operand(variable->local()) == node)
299299 block->variablesAtTail.operand(variable->local()) = getLocal;

@@public:
317317 // to exit.
318318
319319 CodeOrigin codeOrigin = node->codeOrigin;
320  Node* child1 = node->child1().node();
 320 Edge child1 = node->child1();
321321
322322 insertionSet.insertNode(
323323 indexInBlock, DontRefChildren, DontRefNode, SpecNone, SetLocal, codeOrigin,

@@public:
327327 // next bytecode instruction rather than reexecuting the current one.
328328 insertionSet.insertNode(
329329 indexInBlock, RefChildren, DontRefNode, SpecNone, ForwardCheckStructure,
330  codeOrigin, OpInfo(m_graph.addStructureSet(iter->value.m_structure)), child1);
 330 codeOrigin, OpInfo(m_graph.addStructureSet(iter->value.m_structure)), Edge(child1.node(), CellUse));
331331 changed = true;
332332 break;
333333 }
143562

Source/JavaScriptCore/dfg/DFGUseKind.cpp

 1/*
 2 * Copyright (C) 2013 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "DFGUseKind.h"
 28
 29#if ENABLE(DFG_JIT)
 30
 31namespace WTF {
 32
 33using namespace JSC::DFG;
 34
 35void printInternal(PrintStream& out, UseKind useKind)
 36{
 37 switch (useKind) {
 38 case UntypedUse:
 39 out.print("Untyped");
 40 break;
 41 case Int32Use:
 42 out.print("Int32");
 43 break;
 44 case KnownInt32Use:
 45 out.print("KnownInt32");
 46 break;
 47 case RealNumberUse:
 48 out.print("RealNumber");
 49 break;
 50 case NumberUse:
 51 out.print("Number");
 52 break;
 53 case KnownNumberUse:
 54 out.print("KnownNumber");
 55 break;
 56 case BooleanUse:
 57 out.print("Boolean");
 58 break;
 59 case CellUse:
 60 out.print("Cell");
 61 break;
 62 case KnownCellUse:
 63 out.print("KnownCell");
 64 break;
 65 case ObjectUse:
 66 out.print("Object");
 67 break;
 68 case ObjectOrOtherUse:
 69 out.print("ObjectOrOther");
 70 break;
 71 case StringUse:
 72 out.print("String");
 73 break;
 74 case NotCellUse:
 75 out.print("NotCell");
 76 break;
 77 case OtherUse:
 78 out.print("Other");
 79 break;
 80 default:
 81 RELEASE_ASSERT_NOT_REACHED();
 82 break;
 83 }
 84}
 85
 86} // namespace WTF
 87
 88#endif // ENABLE(DFG_JIT)
 89
0

Source/JavaScriptCore/dfg/DFGUseKind.h

 1/*
 2 * Copyright (C) 2013 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef DFGUseKind_h
 27#define DFGUseKind_h
 28
 29#include <wtf/Platform.h>
 30
 31#if ENABLE(DFG_JIT)
 32
 33#include "SpeculatedType.h"
 34#include <wtf/PrintStream.h>
 35
 36namespace JSC { namespace DFG {
 37
 38enum UseKind {
 39 UntypedUse,
 40 Int32Use,
 41 KnownInt32Use,
 42 RealNumberUse,
 43 NumberUse,
 44 KnownNumberUse,
 45 BooleanUse,
 46 CellUse,
 47 KnownCellUse,
 48 ObjectUse,
 49 ObjectOrOtherUse,
 50 StringUse,
 51 NotCellUse,
 52 OtherUse,
 53 LastUseKind // Must always be the last entry in the enum, as it is used to denote the number of enum elements.
 54};
 55
 56ALWAYS_INLINE SpeculatedType typeFilterFor(UseKind useKind)
 57{
 58 switch (useKind) {
 59 case UntypedUse:
 60 return SpecEmptyOrTop; // TOP isn't good enough; untyped uses may use the normally unseen empty value, in the case of lazy registers.
 61 case Int32Use:
 62 case KnownInt32Use:
 63 return SpecInt32;
 64 case RealNumberUse:
 65 return SpecRealNumber;
 66 case NumberUse:
 67 case KnownNumberUse:
 68 return SpecNumber;
 69 case BooleanUse:
 70 return SpecBoolean;
 71 case CellUse:
 72 case KnownCellUse:
 73 return SpecCell;
 74 case ObjectUse:
 75 return SpecObject;
 76 case ObjectOrOtherUse:
 77 return SpecObject | SpecOther;
 78 case StringUse:
 79 return SpecString;
 80 case NotCellUse:
 81 return ~SpecCell;
 82 case OtherUse:
 83 return SpecOther;
 84 default:
 85 RELEASE_ASSERT_NOT_REACHED();
 86 return SpecTop;
 87 }
 88}
 89
 90ALWAYS_INLINE bool isNumerical(UseKind kind)
 91{
 92 switch (kind) {
 93 case Int32Use:
 94 case KnownInt32Use:
 95 case RealNumberUse:
 96 case NumberUse:
 97 return true;
 98 default:
 99 return false;
 100 }
 101}
 102
 103} } // namespace JSC::DFG
 104
 105namespace WTF {
 106
 107void printInternal(PrintStream&, JSC::DFG::UseKind);
 108
 109} // namespace WTF
 110
 111#endif // ENABLE(DFG_JIT)
 112
 113#endif // DFGUseKind_h
 114
0

Source/JavaScriptCore/dfg/DFGValidate.cpp

@@private:
354354
355355 void reportValidationContext(Node* node, Edge edge)
356356 {
357  dataLogF("@%u -> %s@%u", node->index(), useKindToString(edge.useKind()), edge->index());
 357 dataLog(node, " -> ", edge);
358358 }
359359
360360 void reportValidationContext(VirtualRegister local, BlockIndex blockIndex)

@@private:
389389 void reportValidationContext(
390390 Node* node, BlockIndex blockIndex, Node* expectedNode, Edge incomingEdge)
391391 {
392  dataLogF("@%u in Block #%u, searching for @%u from @%u", node->index(), blockIndex, expectedNode->index(), incomingEdge->index());
 392 dataLog(node, " in Block #", blockIndex, ", searching for ", expectedNode, " from ", incomingEdge);
393393 }
394394
395395 void dumpGraphIfAppropriate()
143562