Changeset 143654 in webkit


Ignore:
Timestamp:
Feb 21, 2013 2:59:02 PM (11 years ago)
Author:
fpizlo@apple.com
Message:

DFG should not change its mind about what type speculations a node does, by encoding the checks in the NodeType, UseKind, and ArrayMode
https://bugs.webkit.org/show_bug.cgi?id=109371

Reviewed by Oliver Hunt.

FixupPhase now locks in the speculations that each node will do. The DFG then
remembers those speculations, and doesn't change its mind about them even if the
graph is transformed - for example if a node's child is repointed to a different
node as part of CSE, CFG simplification, or folding. Each node ensures that it
executes the speculations promised by its edges. This is true even for Phantom
nodes.

This still leaves some craziness on the table for future work, like the
elimination of speculating SetLocal's due to CFG simplification
(webkit.org/b/109388) and elimination of nodes via DCE (webkit.org/b/109389).

In all, this allows for a huge simplification of the DFG. Instead of having to
execute the right speculation heuristic each time you want to decide what a node
does (for example Node::shouldSpeculateInteger(child1, child2) &&
node->canSpeculateInteger()), you just ask for the use kinds of its children
(typically node->binaryUseKind() == Int32Use). Because the use kinds are
discrete, you can often just switch over them. This makes many parts of the code
more clear than they were before.

Having UseKinds describe the speculations being performed also makes it far
easier to perform analyses that need to know what speculations are done. This is
so far only used to simplify large parts of the CFA.

To have a larger vocabulary of UseKinds, this also changes the node allocator to
be able to round up Node sizes to the nearest multiple of 16.

This appears to be neutral on benchmarks, except for some goofy speed-ups, like
8% on Octane/box2d.

  • CMakeLists.txt:
  • GNUmakefile.list.am:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • Target.pri:
  • dfg/DFGAbstractState.cpp:

(JSC::DFG::AbstractState::startExecuting):
(DFG):
(JSC::DFG::AbstractState::executeEdges):
(JSC::DFG::AbstractState::verifyEdge):
(JSC::DFG::AbstractState::verifyEdges):
(JSC::DFG::AbstractState::executeEffects):
(JSC::DFG::AbstractState::execute):

  • dfg/DFGAbstractState.h:

(AbstractState):
(JSC::DFG::AbstractState::filterEdgeByUse):
(JSC::DFG::AbstractState::filterByType):

  • dfg/DFGAbstractValue.h:

(JSC::DFG::AbstractValue::filter):

  • dfg/DFGAdjacencyList.h:

(JSC::DFG::AdjacencyList::AdjacencyList):
(JSC::DFG::AdjacencyList::child):
(JSC::DFG::AdjacencyList::setChild):
(JSC::DFG::AdjacencyList::reset):
(JSC::DFG::AdjacencyList::firstChild):
(JSC::DFG::AdjacencyList::setFirstChild):
(JSC::DFG::AdjacencyList::numChildren):
(JSC::DFG::AdjacencyList::setNumChildren):
(AdjacencyList):

  • dfg/DFGAllocator.h:

(DFG):
(Allocator):
(JSC::DFG::Allocator::cellSize):
(JSC::DFG::Allocator::Region::headerSize):
(JSC::DFG::Allocator::Region::numberOfThingsPerRegion):
(JSC::DFG::Allocator::Region::payloadSize):
(JSC::DFG::Allocator::Region::payloadBegin):
(JSC::DFG::Allocator::Region::payloadEnd):
(JSC::DFG::Allocator::Region::isInThisRegion):
(JSC::DFG::::Allocator):
(JSC::DFG::::~Allocator):
(JSC::DFG::::allocate):
(JSC::DFG::::free):
(JSC::DFG::::freeAll):
(JSC::DFG::::reset):
(JSC::DFG::::indexOf):
(JSC::DFG::::allocatorOf):
(JSC::DFG::::bumpAllocate):
(JSC::DFG::::freeListAllocate):
(JSC::DFG::::allocateSlow):
(JSC::DFG::::freeRegionsStartingAt):
(JSC::DFG::::startBumpingIn):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::addToGraph):
(JSC::DFG::ByteCodeParser::handleMinMax):

  • dfg/DFGCSEPhase.cpp:

(JSC::DFG::CSEPhase::setLocalStoreElimination):
(JSC::DFG::CSEPhase::eliminateIrrelevantPhantomChildren):
(JSC::DFG::CSEPhase::setReplacement):
(JSC::DFG::CSEPhase::performNodeCSE):

  • dfg/DFGCommon.h:

(DFG):

  • dfg/DFGConstantFoldingPhase.cpp:

(JSC::DFG::ConstantFoldingPhase::foldConstants):
(JSC::DFG::ConstantFoldingPhase::addStructureTransitionCheck):

  • dfg/DFGDriver.cpp:

(JSC::DFG::compile):

  • dfg/DFGEdge.cpp:

(JSC::DFG::Edge::dump):

  • dfg/DFGEdge.h:

(JSC::DFG::Edge::useKindUnchecked):
(JSC::DFG::Edge::useKind):
(JSC::DFG::Edge::shift):

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::run):
(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::checkArray):
(JSC::DFG::FixupPhase::blessArrayOperation):
(JSC::DFG::FixupPhase::fixIntEdge):
(JSC::DFG::FixupPhase::fixDoubleEdge):
(JSC::DFG::FixupPhase::injectInt32ToDoubleNode):
(FixupPhase):
(JSC::DFG::FixupPhase::truncateConstantToInt32):
(JSC::DFG::FixupPhase::truncateConstantsIfNecessary):
(JSC::DFG::FixupPhase::attemptToMakeIntegerAdd):

  • dfg/DFGGraph.cpp:

(DFG):
(JSC::DFG::Graph::refChildren):
(JSC::DFG::Graph::derefChildren):

  • dfg/DFGGraph.h:

(JSC::DFG::Graph::ref):
(JSC::DFG::Graph::deref):
(JSC::DFG::Graph::performSubstitution):
(JSC::DFG::Graph::isPredictedNumerical):
(JSC::DFG::Graph::addImmediateShouldSpeculateInteger):
(DFG):

  • dfg/DFGNode.h:

(JSC::DFG::Node::Node):
(JSC::DFG::Node::convertToGetByOffset):
(JSC::DFG::Node::convertToPutByOffset):
(JSC::DFG::Node::willHaveCodeGenOrOSR):
(JSC::DFG::Node::child1):
(JSC::DFG::Node::child2):
(JSC::DFG::Node::child3):
(JSC::DFG::Node::binaryUseKind):
(Node):
(JSC::DFG::Node::isBinaryUseKind):

  • dfg/DFGNodeAllocator.h:

(DFG):

  • dfg/DFGNodeFlags.cpp:

(JSC::DFG::nodeFlagsAsString):

  • dfg/DFGNodeType.h:

(DFG):

  • dfg/DFGPredictionPropagationPhase.cpp:

(JSC::DFG::PredictionPropagationPhase::propagate):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::speculationCheck):
(DFG):
(JSC::DFG::SpeculativeJIT::speculationWatchpoint):
(JSC::DFG::SpeculativeJIT::forwardSpeculationCheck):
(JSC::DFG::SpeculativeJIT::terminateSpeculativeExecution):
(JSC::DFG::SpeculativeJIT::typeCheck):
(JSC::DFG::SpeculativeJIT::forwardTypeCheck):
(JSC::DFG::SpeculativeJIT::fillStorage):
(JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
(JSC::DFG::SpeculativeJIT::compile):
(JSC::DFG::SpeculativeJIT::compileDoublePutByVal):
(JSC::DFG::SpeculativeJIT::compileValueToInt32):
(JSC::DFG::SpeculativeJIT::compileInt32ToDouble):
(JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
(JSC::DFG::SpeculativeJIT::compileInstanceOf):
(JSC::DFG::SpeculativeJIT::compileAdd):
(JSC::DFG::SpeculativeJIT::compileArithSub):
(JSC::DFG::SpeculativeJIT::compileArithNegate):
(JSC::DFG::SpeculativeJIT::compileArithMul):
(JSC::DFG::SpeculativeJIT::compileArithMod):
(JSC::DFG::SpeculativeJIT::compare):
(JSC::DFG::SpeculativeJIT::compileStrictEq):
(JSC::DFG::SpeculativeJIT::speculateInt32):
(JSC::DFG::SpeculativeJIT::speculateNumber):
(JSC::DFG::SpeculativeJIT::speculateRealNumber):
(JSC::DFG::SpeculativeJIT::speculateBoolean):
(JSC::DFG::SpeculativeJIT::speculateCell):
(JSC::DFG::SpeculativeJIT::speculateObject):
(JSC::DFG::SpeculativeJIT::speculateObjectOrOther):
(JSC::DFG::SpeculativeJIT::speculateString):
(JSC::DFG::SpeculativeJIT::speculateNotCell):
(JSC::DFG::SpeculativeJIT::speculateOther):
(JSC::DFG::SpeculativeJIT::speculate):

  • dfg/DFGSpeculativeJIT.h:

(SpeculativeJIT):
(JSC::DFG::SpeculativeJIT::valueOfNumberConstant):
(JSC::DFG::SpeculativeJIT::needsTypeCheck):
(JSC::DFG::IntegerOperand::IntegerOperand):
(JSC::DFG::IntegerOperand::edge):
(IntegerOperand):
(JSC::DFG::IntegerOperand::node):
(JSC::DFG::IntegerOperand::gpr):
(JSC::DFG::IntegerOperand::use):
(JSC::DFG::JSValueOperand::JSValueOperand):
(JSValueOperand):
(JSC::DFG::JSValueOperand::edge):
(JSC::DFG::JSValueOperand::node):
(JSC::DFG::JSValueOperand::gpr):
(JSC::DFG::JSValueOperand::fill):
(JSC::DFG::JSValueOperand::use):
(JSC::DFG::StorageOperand::StorageOperand):
(JSC::DFG::StorageOperand::edge):
(StorageOperand):
(JSC::DFG::StorageOperand::node):
(JSC::DFG::StorageOperand::gpr):
(JSC::DFG::StorageOperand::use):
(JSC::DFG::SpeculateIntegerOperand::SpeculateIntegerOperand):
(SpeculateIntegerOperand):
(JSC::DFG::SpeculateIntegerOperand::edge):
(JSC::DFG::SpeculateIntegerOperand::node):
(JSC::DFG::SpeculateIntegerOperand::gpr):
(JSC::DFG::SpeculateIntegerOperand::use):
(JSC::DFG::SpeculateStrictInt32Operand::SpeculateStrictInt32Operand):
(SpeculateStrictInt32Operand):
(JSC::DFG::SpeculateStrictInt32Operand::edge):
(JSC::DFG::SpeculateStrictInt32Operand::node):
(JSC::DFG::SpeculateStrictInt32Operand::gpr):
(JSC::DFG::SpeculateStrictInt32Operand::use):
(JSC::DFG::SpeculateDoubleOperand::SpeculateDoubleOperand):
(SpeculateDoubleOperand):
(JSC::DFG::SpeculateDoubleOperand::edge):
(JSC::DFG::SpeculateDoubleOperand::node):
(JSC::DFG::SpeculateDoubleOperand::fpr):
(JSC::DFG::SpeculateDoubleOperand::use):
(JSC::DFG::SpeculateCellOperand::SpeculateCellOperand):
(SpeculateCellOperand):
(JSC::DFG::SpeculateCellOperand::edge):
(JSC::DFG::SpeculateCellOperand::node):
(JSC::DFG::SpeculateCellOperand::gpr):
(JSC::DFG::SpeculateCellOperand::use):
(JSC::DFG::SpeculateBooleanOperand::SpeculateBooleanOperand):
(JSC::DFG::SpeculateBooleanOperand::edge):
(SpeculateBooleanOperand):
(JSC::DFG::SpeculateBooleanOperand::node):
(JSC::DFG::SpeculateBooleanOperand::gpr):
(JSC::DFG::SpeculateBooleanOperand::use):
(DFG):

  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::fillInteger):
(JSC::DFG::SpeculativeJIT::fillJSValue):
(JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
(JSC::DFG::SpeculativeJIT::fillSpeculateInt):
(JSC::DFG::SpeculativeJIT::fillSpeculateIntStrict):
(JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
(JSC::DFG::SpeculativeJIT::fillSpeculateCell):
(JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
(JSC::DFG::SpeculativeJIT::compileObjectEquality):
(JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
(JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
(JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
(JSC::DFG::SpeculativeJIT::compileLogicalNot):
(JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
(JSC::DFG::SpeculativeJIT::emitBranch):
(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::fillInteger):
(JSC::DFG::SpeculativeJIT::fillJSValue):
(JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
(JSC::DFG::SpeculativeJIT::fillSpeculateInt):
(JSC::DFG::SpeculativeJIT::fillSpeculateIntStrict):
(JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
(JSC::DFG::SpeculativeJIT::fillSpeculateCell):
(JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
(JSC::DFG::SpeculativeJIT::compileObjectEquality):
(JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
(JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
(JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
(JSC::DFG::SpeculativeJIT::compileLogicalNot):
(JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
(JSC::DFG::SpeculativeJIT::emitBranch):
(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGStructureCheckHoistingPhase.cpp:

(JSC::DFG::StructureCheckHoistingPhase::run):

  • dfg/DFGUseKind.cpp: Added.

(WTF):
(WTF::printInternal):

  • dfg/DFGUseKind.h: Added.

(DFG):
(JSC::DFG::typeFilterFor):
(JSC::DFG::isNumerical):
(WTF):

  • dfg/DFGValidate.cpp:

(JSC::DFG::Validate::reportValidationContext):

Location:
trunk/Source/JavaScriptCore
Files:
2 added
31 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r143147 r143654  
    114114    dfg/DFGThunks.cpp
    115115    dfg/DFGUnificationPhase.cpp
     116    dfg/DFGUseKind.cpp
    116117    dfg/DFGValueSource.cpp
    117118    dfg/DFGVariableAccessDataDump.cpp
  • trunk/Source/JavaScriptCore/ChangeLog

    r143637 r143654  
     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 Oliver Hunt.
     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  Mark Hahnenberg  <mhahnenberg@apple.com>
    2287
  • trunk/Source/JavaScriptCore/GNUmakefile.list.am

    r143392 r143654  
    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 \
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r143637 r143654  
    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 */; };
     
    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>"; };
     
    27102714                                0FBE0F6F16C1DB010082C5E8 /* DFGUnificationPhase.cpp */,
    27112715                                0FBE0F7016C1DB010082C5E8 /* DFGUnificationPhase.h */,
     2716                                0F34B14716D4200E001CDA5A /* DFGUseKind.cpp */,
     2717                                0F34B14816D4200E001CDA5A /* DFGUseKind.h */,
    27122718                                0F3B3A2915474FF4003ED0FF /* DFGValidate.cpp */,
    27132719                                0F3B3A2A15474FF4003ED0FF /* DFGValidate.h */,
     
    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 */,
     
    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 */,
  • trunk/Source/JavaScriptCore/Target.pri

    r143147 r143654  
    150150    dfg/DFGThunks.cpp \
    151151    dfg/DFGUnificationPhase.cpp \
     152    dfg/DFGUseKind.cpp \
    152153    dfg/DFGValueSource.cpp \
    153154    dfg/DFGVariableAccessDataDump.cpp \
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractState.cpp

    r143241 r143654  
    235235}
    236236
    237 bool AbstractState::execute(unsigned indexInBlock)
     237bool AbstractState::startExecuting(Node* node)
    238238{
    239239    ASSERT(m_block);
     
    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:
     
    252285    case PhantomArguments: {
    253286        forNode(node).set(m_graph.valueOfJSConstant(node));
    254         node->setCanExit(false);
    255287        break;
    256288    }
     
    258290    case Identity: {
    259291        forNode(node) = forNode(node->child1());
    260         node->setCanExit(false);
    261292        break;
    262293    }
     
    266297        if (variableAccessData->prediction() == SpecNone) {
    267298            m_isValid = false;
    268             node->setCanExit(true);
    269             break;
    270         }
    271         bool canExit = false;
     299            break;
     300        }
    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    }
     
    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;
     
    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           
     
    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;
     
    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);
     
    391389        break;
    392390    }
    393              
    394391           
    395392    case DoubleAsInt32: {
     
    405402        }
    406403        node->setCanExit(true);
    407         forNode(node->child1()).filter(SpecNumber);
    408404        forNode(node).set(SpecInt32);
    409405        break;
     
    420416            if (constantWasSet) {
    421417                m_foundConstants = true;
    422                 node->setCanExit(false);
    423418                break;
    424419            }
    425         }
    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);
    435420        }
    436421       
     
    445430            && trySetConstant(node, JSValue(JSValue::EncodeAsDouble, child.asNumber()))) {
    446431            m_foundConstants = true;
    447             node->setCanExit(false);
    448             break;
    449         }
    450         speculateNumberUnary(node);
     432            break;
     433        }
    451434        if (isInt32Speculation(forNode(node->child1()).m_type))
    452435            forNode(node).set(SpecDoubleReal);
     
    456439    }
    457440       
    458     case CheckNumber:
    459         forNode(node->child1()).filter(SpecNumber);
    460         break;
    461            
    462441    case ValueAdd:
    463442    case ArithAdd: {
     
    467446            && trySetConstant(node, JSValue(left.asNumber() + right.asNumber()))) {
    468447            m_foundConstants = true;
    469             node->setCanExit(false);
    470             break;
    471         }
    472         if (m_graph.addShouldSpeculateInteger(node)) {
    473             speculateInt32Binary(
    474                 node, !nodeCanTruncateInteger(node->arithNodeFlags()));
     448            break;
     449        }
     450        switch (node->binaryUseKind()) {
     451        case Int32Use:
    475452            forNode(node).set(SpecInt32);
    476             break;
    477         }
    478         if (Node::shouldSpeculateNumberExpectingDefined(node->child1().node(), node->child2().node())) {
    479             speculateNumberBinary(node);
     453            if (!nodeCanTruncateInteger(node->arithNodeFlags()))
     454                node->setCanExit(true);
     455            break;
     456        case NumberUse:
    480457            if (isRealNumberSpeculation(forNode(node->child1()).m_type)
    481458                && isRealNumberSpeculation(forNode(node->child2()).m_type))
     
    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);
    491             break;
    492         }
    493         // We don't handle this yet. :-(
    494         m_isValid = false;
    495         node->setCanExit(true);
     467            break;
     468        }
    496469        break;
    497470    }
     
    503476            && trySetConstant(node, JSValue(left.asNumber() - right.asNumber()))) {
    504477            m_foundConstants = true;
    505             node->setCanExit(false);
    506             break;
    507         }
    508         if (m_graph.addShouldSpeculateInteger(node)) {
    509             speculateInt32Binary(
    510                 node, !nodeCanTruncateInteger(node->arithNodeFlags()));
     478            break;
     479        }
     480        switch (node->binaryUseKind()) {
     481        case Int32Use:
    511482            forNode(node).set(SpecInt32);
    512             break;
    513         }
    514         speculateNumberBinary(node);
    515         forNode(node).set(SpecDouble);
     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();
     491            break;
     492        }
    516493        break;
    517494    }
     
    522499            && trySetConstant(node, JSValue(-child.asNumber()))) {
    523500            m_foundConstants = true;
    524             node->setCanExit(false);
    525             break;
    526         }
    527         if (m_graph.negateShouldSpeculateInteger(node)) {
    528             speculateInt32Unary(
    529                 node, !nodeCanTruncateInteger(node->arithNodeFlags()));
     501            break;
     502        }
     503        switch (node->child1().useKind()) {
     504        case Int32Use:
    530505            forNode(node).set(SpecInt32);
    531             break;
    532         }
    533         speculateNumberUnary(node);
    534         forNode(node).set(SpecDouble);
     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();
     514            break;
     515        }
    535516        break;
    536517    }
     
    542523            && trySetConstant(node, JSValue(left.asNumber() * right.asNumber()))) {
    543524            m_foundConstants = true;
    544             node->setCanExit(false);
    545             break;
    546         }
    547         if (m_graph.mulShouldSpeculateInteger(node)) {
    548             speculateInt32Binary(
    549                 node,
    550                 !nodeCanTruncateInteger(node->arithNodeFlags())
    551                 || !nodeCanIgnoreNegativeZero(node->arithNodeFlags()));
     525            break;
     526        }
     527        switch (node->binaryUseKind()) {
     528        case Int32Use:
    552529            forNode(node).set(SpecInt32);
    553             break;
    554         }
    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);
     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();
     543            break;
     544        }
    561545        break;
    562546    }
     
    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);
    602             break;
    603         }
    604         speculateNumberBinary(node);
    605         forNode(node).set(SpecDouble);
     584            node->setCanExit(true);
     585            break;
     586        case NumberUse:
     587            forNode(node).set(SpecDouble);
     588            break;
     589        default:
     590            RELEASE_ASSERT_NOT_REACHED();
     591            break;
     592        }
    606593        break;
    607594    }
     
    612599            && trySetConstant(node, JSValue(fabs(child.asNumber())))) {
    613600            m_foundConstants = true;
    614             node->setCanExit(false);
    615             break;
    616         }
    617         if (node->child1()->shouldSpeculateIntegerForArithmetic()
    618             && node->canSpeculateInteger()) {
    619             speculateInt32Unary(node, true);
     601            break;
     602        }
     603        switch (node->child1().useKind()) {
     604        case Int32Use:
    620605            forNode(node).set(SpecInt32);
    621             break;
    622         }
    623         speculateNumberUnary(node);
    624         forNode(node).set(SpecDouble);
     606            node->setCanExit(true);
     607            break;
     608        case NumberUse:
     609            forNode(node).set(SpecDouble);
     610            break;
     611        default:
     612            RELEASE_ASSERT_NOT_REACHED();
     613            break;
     614        }
    625615        break;
    626616    }
     
    631621            && trySetConstant(node, JSValue(sqrt(child.asNumber())))) {
    632622            m_foundConstants = true;
    633             node->setCanExit(false);
    634             break;
    635         }
    636         speculateNumberUnary(node);
     623            break;
     624        }
    637625        forNode(node).set(SpecDouble);
    638626        break;
     
    653641        if (didSetConstant) {
    654642            m_foundConstants = true;
    655             node->setCanExit(false);
    656             break;
    657         }
    658         Node* child = node->child1().node();
    659         if (isBooleanSpeculation(child->prediction()))
    660             speculateBooleanUnary(node);
    661         else if (child->shouldSpeculateObjectOrOther()) {
     643            break;
     644        }
     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;
     
    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);
     
    824815        if (constantWasSet) {
    825816            m_foundConstants = true;
    826             node->setCanExit(false);
    827817            break;
    828818        }
     
    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    }
     
    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    }
     
    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;
     
    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;
     
    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);
     
    971885            break;
    972886        case Array::Double:
    973             forNode(node->child2()).filter(SpecInt32);
    974887            if (node->arrayMode().isOutOfBounds()) {
    975888                clobberWorld(node->codeOrigin, indexInBlock);
     
    983896        case Array::ArrayStorage:
    984897        case Array::SlowPutArrayStorage:
    985             forNode(node->child2()).filter(SpecInt32);
    986898            if (node->arrayMode().isOutOfBounds())
    987899                clobberWorld(node->codeOrigin, indexInBlock);
     
    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);
     
    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;
     
    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:
     
    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);
     
    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        }
     
    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);
     
    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           
     
    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        }
     
    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;
     
    12211012    case Return:
    12221013        m_isValid = false;
    1223         node->setCanExit(false);
    12241014        break;
    12251015       
     
    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);
    1239             break;
    1240         }
    1241        
    1242         if (child->shouldSpeculateInteger()) {
    1243             speculateInt32Unary(node);
     1026            break;
     1027        }
     1028       
     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       
     
    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;
     
    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;
     
    13211083    case NewArrayWithSize:
    13221084        node->setCanExit(true);
    1323         forNode(node->child1()).filter(SpecInt32);
    13241085        forNode(node).set(SpecArray);
    13251086        m_haveStructures = true;
     
    13271088           
    13281089    case NewRegexp:
    1329         node->setCanExit(false);
    13301090        forNode(node).set(m_graph.globalObjectFor(node->codeOrigin)->regExpStructure());
    13311091        m_haveStructures = true;
     
    13331093           
    13341094    case ConvertThis: {
    1335         Node* child = node->child1().node();
    13361095        AbstractValue& source = forNode(node->child1());
    13371096        AbstractValue& destination = forNode(node);
     
    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;
     
    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:
    13591113            destination = source;
    13601114            break;
    1361         }
    1362            
    1363         destination = source;
    1364         destination.merge(SpecObjectOther);
     1115        case UntypedUse:
     1116            destination = source;
     1117            destination.merge(SpecObjectOther);
     1118            break;
     1119        default:
     1120            RELEASE_ASSERT_NOT_REACHED();
     1121            break;
     1122        }
    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    }
     
    13821134
    13831135    case NewObject:
    1384         node->setCanExit(false);
    13851136        forNode(node).set(node->structure());
    13861137        m_haveStructures = true;
     
    13881139       
    13891140    case CreateActivation:
    1390         node->setCanExit(false);
    13911141        forNode(node).set(m_codeBlock->globalObjectFor(node->codeOrigin)->activationStructure());
    13921142        m_haveStructures = true;
     
    13941144       
    13951145    case CreateArguments:
    1396         node->setCanExit(false);
    13971146        forNode(node).set(m_codeBlock->globalObjectFor(node->codeOrigin)->argumentsStructure());
    13981147        m_haveStructures = true;
     
    14011150    case TearOffActivation:
    14021151    case TearOffArguments:
    1403         node->setCanExit(false);
    14041152        // Does nothing that is user-visible.
    14051153        break;
     
    14081156        if (isEmptySpeculation(
    14091157                m_variables.operand(
    1410                     m_graph.argumentsRegisterFor(node->codeOrigin)).m_type)) {
    1411             node->setCanExit(false);
    1412             m_foundConstants = true;
    1413         } else
     1158                    m_graph.argumentsRegisterFor(node->codeOrigin)).m_type))
     1159            m_foundConstants = true;
     1160        else
    14141161            node->setCanExit(true);
    14151162        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.
     
    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;
     
    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();
     
    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;
     
    14741215    case SetCallee:
    14751216    case SetMyScope:
    1476         node->setCanExit(false);
    14771217        break;
    14781218           
     
    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()))) {
     
    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;
     
    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(
     
    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;
     
    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
     
    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;
     
    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;
     
    16011331    case PutStructure:
    16021332    case PhantomPutStructure:
    1603         node->setCanExit(false);
    16041333        if (!forNode(node->child1()).m_currentKnownStructure.isClear()) {
    16051334            clobberStructures(indexInBlock);
     
    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;
     
    16181345        if (node->arrayMode().alreadyChecked(m_graph, node, forNode(node->child1()))) {
    16191346            m_foundConstants = true;
    1620             node->setCanExit(false);
    16211347            break;
    16221348        }
     
    16311357        case Array::ArrayStorage:
    16321358        case Array::SlowPutArrayStorage:
    1633             forNode(node->child1()).filter(SpecCell);
    16341359            break;
    16351360        case Array::Arguments:
     
    16741399        if (node->arrayMode().alreadyChecked(m_graph, node, forNode(node->child1()))) {
    16751400            m_foundConstants = true;
    1676             node->setCanExit(false);
    16771401            break;
    16781402        }
     
    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());
     
    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);
     
    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    }
     
    17321439            m_foundConstants = true;
    17331440            ASSERT(value);
    1734             node->setCanExit(false);
    17351441            break;
    17361442        }
     
    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;
     
    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;
     
    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;
     
    18051502    case Flush:
    18061503    case PhantomLocal:
    1807         node->setCanExit(false);
    1808         break;
    1809            
    18101504    case Breakpoint:
    1811         node->setCanExit(false);
    18121505        break;
    18131506           
     
    18371530    case Nop:
    18381531    case CountExecution:
    1839         node->setCanExit(false);
    18401532        break;
    18411533       
     
    18461538   
    18471539    return m_isValid;
     1540}
     1541
     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);
    18481555}
    18491556
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractState.h

    r141069 r143654  
    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?
     
    191236   
    192237    static bool mergeVariableBetweenBlocks(AbstractValue& destination, AbstractValue& source, Node* destinationNode, Node* sourceNode);
    193    
    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     }
    237238   
    238239    enum BooleanResult {
     
    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;
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.h

    r141069 r143654  
    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();
  • trunk/Source/JavaScriptCore/dfg/DFGAdjacencyList.h

    r141069 r143654  
    4848   
    4949    AdjacencyList(Kind kind)
    50 #if !ASSERT_DISABLED
    51         : m_kind(kind)
    52 #endif
    5350    {
    5451        if (kind == Variable) {
     
    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);
     
    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);
     
    8071    {
    8172        ASSERT(i < Size);
    82         ASSERT(m_kind == Fixed);
    8373        return m_words[i];
    8474    }   
     
    8777    {
    8878        ASSERT(i < Size);
    89         ASSERT(m_kind == Fixed);
    9079        return m_words[i];
    9180    }
     
    9483    {
    9584        ASSERT(i < Size);
    96         ASSERT(m_kind == Fixed);
    9785        m_words[i] = nodeUse;
    9886    }
     
    126114    void reset()
    127115    {
    128 #if !ASSERT_DISABLED
    129         m_kind = Fixed;
    130 #endif
    131116        initialize();
    132117    }
     
    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    }
     
    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
  • trunk/Source/JavaScriptCore/dfg/DFGAllocator.h

    r142377 r143654  
    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:
     
    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       
     
    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)
     
    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();
     
    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();
     
    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) {
     
    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);
     
    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    }
     
    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()
    176 {
    177     if (unsigned remaining = m_bumpRemaining) {
    178         remaining--;
     189template<typename T, unsigned forcedCellAlignment>
     190ALWAYS_INLINE void* Allocator<T, forcedCellAlignment>::bumpAllocate()
     191{
     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;
     
    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);
     
    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) {
     
    227242}
    228243
    229 template<typename T>
    230 void Allocator<T>::startBumpingIn(typename Allocator<T>::Region* region)
    231 {
    232     m_bumpEnd = region->data() + Region::numberOfThingsPerRegion();
    233     m_bumpRemaining = Region::numberOfThingsPerRegion();
     244template<typename T, unsigned forcedCellAlignment>
     245void Allocator<T, forcedCellAlignment>::startBumpingIn(typename Allocator<T, forcedCellAlignment>::Region* region)
     246{
     247    m_bumpEnd = region->payloadEnd();
     248    m_bumpRemaining = Region::payloadSize();
    234249}
    235250
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r143165 r143654  
    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);
     
    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);
     
    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);
     
    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;
  • trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp

    r143241 r143654  
    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;
     
    10031003            if (!edge)
    10041004                continue;
     1005            if (edge.useKind() != UntypedUse)
     1006                continue; // Keep the type check.
    10051007            if (edge->flags() & NodeRelevantToOSR)
    10061008                continue;
     
    10151017    }
    10161018   
    1017     enum PredictionHandlingMode { RequireSamePrediction, AllowPredictionMismatch };
    1018     bool setReplacement(Node* replacement, PredictionHandlingMode predictionHandlingMode = RequireSamePrediction)
     1019    bool setReplacement(Node* replacement)
    10191020    {
    10201021        if (!replacement)
    1021             return false;
    1022        
    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())
    10271022            return false;
    10281023       
     
    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           
  • trunk/Source/JavaScriptCore/dfg/DFGCommon.h

    r142544 r143654  
    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:
     
    106100    DontRefNode
    107101};
    108 
    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 }
    121102
    122103inline bool isARMv7s()
     
    237218};
    238219
     220enum OperandSpeculationMode { AutomaticOperandSpeculation, ManualOperandSpeculation };
     221
    239222enum SpeculationDirection { ForwardSpeculation, BackwardSpeculation };
    240223
  • trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp

    r142377 r143654  
    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;
     
    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;
     
    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               
     
    165168                    globalData(), structure, codeBlock()->identifier(identifierNumber));
    166169               
    167                 if (!status.isSimple())
    168                     break;
     170                if (!status.isSimple()) {
     171                    // FIXME: We could handle prototype cases.
     172                    // https://bugs.webkit.org/show_bug.cgi?id=110386
     173                    break;
     174                }
    169175               
    170176                ASSERT(status.structureSet().size() == 1);
     
    182188                    m_insertionSet.insertNode(
    183189                        indexInBlock, RefChildren, DontRefNode, SpecNone,
    184                         StructureTransitionWatchpoint, codeOrigin, OpInfo(structure), child);
    185                 }
    186                
    187                 Node* propertyStorage;
     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);
     195                }
     196               
     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               
     
    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();
     225               
     226                ASSERT(childEdge.useKind() == CellUse);
    212227               
    213228                Structure* structure = m_state.forNode(child).bestProvenStructure();
     
    239254                    m_insertionSet.insertNode(
    240255                        indexInBlock, RefChildren, DontRefNode, SpecNone,
    241                         StructureTransitionWatchpoint, codeOrigin, OpInfo(structure), child);
    242                 }
     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);
     261                }
     262               
     263                childEdge.setUseKind(KnownCellUse);
    243264               
    244265                StructureTransitionData* transitionData = 0;
     
    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());
     
    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               
     
    296317                    m_insertionSet.insertNode(
    297318                        indexInBlock, RefChildren, DontRefNode, SpecNone, PutStructure, codeOrigin,
    298                         OpInfo(transitionData), child);
     319                        OpInfo(transitionData), childEdge);
    299320                }
    300321               
     
    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;
     
    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        }
     
    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   
  • trunk/Source/JavaScriptCore/dfg/DFGDriver.cpp

    r142377 r143654  
    145145            break;
    146146       
    147         dfg.resetExitStates();
    148         performFixup(dfg);
    149147        performCPSRethreading(dfg);
    150148    }
  • trunk/Source/JavaScriptCore/dfg/DFGEdge.cpp

    r141069 r143654  
    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
  • trunk/Source/JavaScriptCore/dfg/DFGEdge.h

    r141069 r143654  
    3232
    3333#include "DFGCommon.h"
     34#include "DFGUseKind.h"
    3435
    3536namespace JSC { namespace DFG {
     
    6364    }
    6465   
     66    UseKind useKindUnchecked() const
     67    {
     68        unsigned masked = m_encodedWord & (((1 << shift()) - 1));
     69        ASSERT(masked < LastUseKind);
     70        UseKind result = static_cast<UseKind>(masked);
     71        ASSERT(node() || result == UntypedUse);
     72        return result;
     73    }
    6574    UseKind useKind() const
    6675    {
    6776        ASSERT(node());
    68         unsigned masked = m_encodedWord & (((1 << shift()) - 1));
    69         ASSERT(masked < LastUseKind);
    70         return static_cast<UseKind>(masked);
     77        return useKindUnchecked();
    7178    }
    7279    void setUseKind(UseKind useKind)
     
    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)
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r143241 r143654  
    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());
     
    7780       
    7881        switch (op) {
    79         case GetById: {
    80             if (m_graph.m_fixpointState > BeforeFixpoint)
    81                 break;
    82            
    83             if (!isInt32Speculation(node->prediction()))
    84                 break;
    85             if (codeBlock()->identifier(node->identifierNumber()) != globalData().propertyNames->length)
    86                 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());
     82        case SetLocal: {
     83            VariableAccessData* variable = node->variableAccessData();
     84           
     85            if (variable->isCaptured()
     86                || m_graph.isCreatedThisArgument(variable->local()))
     87                break;
     88           
     89            if (variable->shouldUseDoubleFormat()) {
     90                fixDoubleEdge(node->child1(), NumberUse, ForwardSpeculation);
     91                break;
     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);
     128                break;
     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())
    105                 break;
    106             node->setOp(GetArrayLength);
    107             ASSERT(node->flags() & NodeMustGenerate);
    108             node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
    109             m_graph.deref(node);
    110             node->setArrayMode(arrayMode);
    111            
    112             Node* storage = checkArray(arrayMode, node->codeOrigin, node->child1().node(), 0, lengthNeedsStorage, node->shouldGenerate());
    113             if (!storage)
    114                 break;
    115            
    116             node->children.child2() = Edge(storage);
    117             break;
    118         }
    119         case GetIndexedPropertyStorage: {
    120             ASSERT(node->arrayMode().canCSEStorage());
    121             break;
    122         }
     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());
     208                break;
     209            }
     210            fixDoubleEdge(node->child1());
     211            fixDoubleEdge(node->child2());
     212            break;
     213        }
     214           
     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);
     233                break;
     234            }
     235            fixDoubleEdge(node->child1());
     236            break;
     237        }
     238           
     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());
     253            break;
     254        }
     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);
     261            break;
     262        }
     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(
     
    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();
     
    139354                node->setArrayMode(arrayMode.withSpeculation(Array::SaneChain));
    140355           
    141             break;
    142         }
    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);
     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           
     375            break;
     376        }
     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        }
     
    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:
     
    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);
    206             break;
    207         }
    208            
    209         case LogicalNot: {
    210             if (node->child1()->shouldSpeculateInteger())
    211                 break;
    212             if (!node->child1()->shouldSpeculateNumber())
    213                 break;
    214             fixDoubleEdge(0);
     477            blessArrayOperation(node->child1(), Edge(), node->child2());
     478            node->child1().setUseKind(KnownCellUse);
     479            break;
     480        }
     481           
     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();
     
    262538        }
    263539           
    264         case SetLocal: {
    265             if (node->variableAccessData()->isCaptured())
    266                 break;
    267             if (!node->variableAccessData()->shouldUseDoubleFormat())
    268                 break;
    269             fixDoubleEdge(0, ForwardSpeculation);
    270             break;
    271         }
    272            
    273         case ArithAdd:
    274         case ValueAdd: {
    275             if (m_graph.addShouldSpeculateInteger(node))
    276                 break;
    277             if (!Node::shouldSpeculateNumberExpectingDefined(node->child1().node(), node->child2().node()))
    278                 break;
    279             fixDoubleEdge(0);
    280             fixDoubleEdge(1);
    281             break;
    282         }
    283            
    284         case ArithSub: {
    285             if (m_graph.addShouldSpeculateInteger(node)
    286                 && node->canSpeculateInteger())
    287                 break;
    288             fixDoubleEdge(0);
    289             fixDoubleEdge(1);
    290             break;
    291         }
    292            
    293         case ArithNegate: {
    294             if (m_graph.negateShouldSpeculateInteger(node))
    295                 break;
    296             fixDoubleEdge(0);
    297             break;
    298         }
    299            
    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);
    308             break;
    309         }
    310            
    311         case ArithMul: {
    312             if (m_graph.mulShouldSpeculateInteger(node))
    313                 break;
    314             fixDoubleEdge(0);
    315             fixDoubleEdge(1);
    316             break;
    317         }
    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);
    338             break;
    339         }
    340            
    341         case ArithAbs: {
    342             if (node->child1()->shouldSpeculateIntegerForArithmetic()
    343                 && node->canSpeculateInteger())
    344                 break;
    345             fixDoubleEdge(0);
    346             break;
    347         }
    348            
    349         case ArithSqrt: {
    350             fixDoubleEdge(0);
    351             break;
    352         }
    353            
    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);
    367            
    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);
    385                 break;
    386             default:
    387                 break;
    388             }
     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
    389545            break;
    390546        }
     
    396552                        node->indexingType(), m_graph.varArgChild(node, i)->prediction()));
    397553            }
    398             if (node->indexingType() == ArrayWithDouble) {
    399                 for (unsigned i = m_graph.varArgNumChildren(node); i--;)
    400                     fixDoubleEdge(i);
    401             }
    402             break;
    403         }
    404            
     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);
     575                break;
     576            case ALL_CONTIGUOUS_INDEXING_TYPES:
     577            case ALL_ARRAY_STORAGE_INDEXING_TYPES:
     578                break;
     579            default:
     580                CRASH();
     581                break;
     582            }
     583            break;
     584        }
     585           
     586        case NewArrayWithSize: {
     587            node->child1().setUseKind(Int32Use);
     588            break;
     589        }
     590           
     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);
     598            break;
     599        }
     600           
     601        case CreateThis: {
     602            node->child1().setUseKind(CellUse);
     603            break;
     604        }
     605           
     606        case GetMyArgumentByVal:
     607        case GetMyArgumentByValSafe: {
     608            node->child1().setUseKind(Int32Use);
     609            break;
     610        }
     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);
     624            break;
     625        }
     626           
     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)
     634                break;
     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);
     666            break;
     667        }
     668           
     669        case GetByIdFlush: {
     670            if (node->child1()->shouldSpeculateCell())
     671                node->child1().setUseKind(CellUse);
     672            break;
     673        }
     674           
     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        }
     687           
     688        case CheckArray: {
     689            switch (node->arrayMode().type()) {
     690            case Array::String:
     691                node->child1().setUseKind(StringUse);
     692                break;
     693            default:
     694                node->child1().setUseKind(CellUse);
     695                break;
     696            }
     697            break;
     698        }
     699           
     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);
     727            break;
     728        }
     729           
     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
     
    421814       
    422815        Structure* structure = arrayMode.originalArrayStructure(m_graph, codeOrigin);
     816       
     817        Edge indexEdge = index ? Edge(index, Int32Use) : Edge();
    423818       
    424819        if (arrayMode.doesConversion()) {
     
    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 {
     
    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        }
     
    462857                shouldGenerate ? RefChildren : DontRefChildren,
    463858                shouldGenerate ? RefNode : DontRefNode,
    464                 SpecNone, GetButterfly, codeOrigin, array);
     859                SpecNone, GetButterfly, codeOrigin, Edge(array, KnownCellUse));
    465860        }
    466861       
     
    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)
    475     {
    476         if (m_graph.m_fixpointState > BeforeFixpoint)
    477             return;
    478        
     869    void blessArrayOperation(Edge base, Edge index, Edge& storageChild)
     870    {
    479871        Node* node = m_currentNode;
    480872       
     
    500892                return;
    501893           
    502             m_graph.child(node, storageChildIdx) = Edge(storage);
     894            storageChild = Edge(storage);
    503895            return;
    504896        } }
     
    508900    {
    509901        Node* node = edge.node();
    510         if (node->op() != ValueToInt32)
     902        if (node->op() != ValueToInt32) {
     903            edge.setUseKind(KnownInt32Use);
    511904            return;
    512        
    513         if (!node->child1()->shouldSpeculateInteger())
    514             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);
     
    523921    }
    524922   
    525     void fixDoubleEdge(unsigned childIndex, SpeculationDirection direction = BackwardSpeculation)
    526     {
    527         Node* source = m_currentNode;
    528         Edge& edge = m_graph.child(source, childIndex);
    529        
     923    void fixDoubleEdge(Edge& edge, UseKind useKind = NumberUse, SpeculationDirection direction = BackwardSpeculation)
     924    {
    530925        if (edge->prediction() & SpecDouble) {
    531             edge.setUseKind(DoubleUse);
     926            edge.setUseKind(useKind);
    532927            return;
    533928        }
    534929       
    535         injectInt32ToDoubleNode(childIndex, direction);
    536     }
    537 
    538     void injectInt32ToDoubleNode(unsigned childIndex, SpeculationDirection direction = BackwardSpeculation)
     930        injectInt32ToDoubleNode(edge, useKind, direction);
     931    }
     932
     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
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp

    r142377 r143654  
    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
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.h

    r142769 r143654  
    7878enum AddSpeculationMode {
    7979    DontSpeculateInteger,
    80     SpeculateIntegerButAlwaysWatchOverflow,
     80    SpeculateIntegerAndTruncateConstants,
    8181    SpeculateInteger
    8282};
     
    101101        return node;
    102102    }
    103     Edge ref(Edge nodeUse)
    104     {
    105         ref(nodeUse.node());
    106         return nodeUse;
     103    Edge ref(Edge edge)
     104    {
     105        ref(edge.node());
     106        return edge;
     107    }
     108    Edge ref(Node*, Edge edge)
     109    {
     110        return ref(edge);
    107111    }
    108112   
     
    116120            derefChildren(node);
    117121    }
    118     void deref(Edge nodeUse)
    119     {
    120         deref(nodeUse.node());
     122    void deref(Edge edge)
     123    {
     124        deref(edge.node());
     125    }
     126    void deref(Node*, Edge edge)
     127    {
     128        deref(edge);
    121129    }
    122130   
     
    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    }
     
    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   
     
    782788            return DontSpeculateInteger;
    783789       
    784         return nodeCanTruncateInteger(add->arithNodeFlags()) ? SpeculateIntegerButAlwaysWatchOverflow : DontSpeculateInteger;
     790        return nodeCanTruncateInteger(add->arithNodeFlags()) ? SpeculateIntegerAndTruncateConstants : DontSpeculateInteger;
    785791    }
    786792   
     
    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
  • trunk/Source/JavaScriptCore/dfg/DFGNode.h

    r142544 r143654  
    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)
     
    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)
     
    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)
     
    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);
     
    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;
     
    950949        case PhantomArguments:
    951950            return true;
     951        case Nop:
     952            return false;
    952953        case Phantom:
    953         case Nop:
    954             return false;
     954            return child1().useKindUnchecked() != UntypedUse || child2().useKindUnchecked() != UntypedUse || child3().useKindUnchecked() != UntypedUse;
    955955        default:
    956956            return shouldGenerate();
     
    996996    }
    997997   
    998     Edge child1()
     998    Edge& child1()
    999999    {
    10001000        ASSERT(!(m_flags & NodeHasVarArgs));
     
    10101010    }
    10111011
    1012     Edge child2()
     1012    Edge& child2()
    10131013    {
    10141014        ASSERT(!(m_flags & NodeHasVarArgs));
     
    10161016    }
    10171017
    1018     Edge child3()
     1018    Edge& child3()
    10191019    {
    10201020        ASSERT(!(m_flags & NodeHasVarArgs));
     
    10321032        ASSERT(m_flags & NodeHasVarArgs);
    10331033        return children.numChildren();
     1034    }
     1035   
     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;
    10341045    }
    10351046   
  • trunk/Source/JavaScriptCore/dfg/DFGNodeAllocator.h

    r141069 r143654  
    3636namespace JSC { namespace DFG {
    3737
    38 typedef Allocator<Node> NodeAllocator;
     38// The second template argument to Allocator is the expected size of Node rounded up to
     39// 16 bytes. This is baked in to give us assertion coverage for when Node increases in
     40// size. We don't want its size to increase for no good reason. The multiple-of-16
     41// property is asserted by DFG::Edge, which expects to never see any of the low 4 bits
     42// of a Node* being non-zero.
     43#if USE(JSVALUE64)
     44typedef Allocator<Node, 112> NodeAllocator;
     45#else
     46typedef Allocator<Node, 80> NodeAllocator;
     47#endif
    3948
    4049} } // namespace JSC::DFG
  • trunk/Source/JavaScriptCore/dfg/DFGNodeFlags.cpp

    r140594 r143654  
    3535const char* nodeFlagsAsString(NodeFlags flags)
    3636{
    37     if (!flags)
     37    if (!(flags ^ NodeDoesNotExit))
    3838        return "<empty>";
    3939
  • trunk/Source/JavaScriptCore/dfg/DFGNodeType.h

    r143241 r143654  
    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. */\
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r142695 r143654  
    806806        case TearOffActivation:
    807807        case TearOffArguments:
    808         case CheckNumber:
    809808        case CheckArgumentsNotCreated:
    810809        case GlobalVarWatchpoint:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r143562 r143654  
    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()));
     
    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}
     
    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();
     
    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}
     
    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()));
     
    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}
     
    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);
     
    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}
     
    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(
     
    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);
     
    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);
     
    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");
     
    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}
     
    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");
     
    329339    speculationCheck(kind, jsValueRegs, node, m_jit.jump(), direction);
    330340    m_compileOkay = false;
     341}
     342
     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();
    331361}
    332362
     
    873903}
    874904
    875 GPRReg SpeculativeJIT::fillStorage(Node* node)
    876 {
    877     VirtualRegister virtualRegister = node->virtualRegister();
     905GPRReg SpeculativeJIT::fillStorage(Edge edge)
     906{
     907    VirtualRegister virtualRegister = edge->virtualRegister();
    878908    GenerationInfo& info = m_generationInfo[virtualRegister];
    879909   
     
    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       
     
    899929       
    900930    default:
    901         return fillSpeculateCell(node, BackwardSpeculation);
     931        return fillSpeculateCell(edge, BackwardSpeculation);
    902932    }
    903933}
     
    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 {
     
    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;
     
    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());
    1716 #endif
     1754                dataLog("   ");
     1755#else
     1756                dataLog("\n");
     1757#endif
     1758            }
    17171759#if DFG_ENABLE(JIT_BREAK_ON_EVERY_NODE)
    17181760            m_jit.breakpoint();
     
    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())
     
    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)
     
    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);
     
    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));
    2142 
    2143         integerResult(gpr, node);
    2144         return;
    2145     }
    2146     case GeneratedOperandJSValue: {
    2147         GPRTemporary result(this);
     2173            addSlowPathGenerator(slowPathCall(notTruncatedToInteger, this, toInt32, gpr, fpr));
     2174
     2175            integerResult(gpr, node);
     2176            return;
     2177        }
     2178        case GeneratedOperandJSValue: {
     2179            GPRTemporary result(this);
    21482180#if USE(JSVALUE64)
    2149         JSValueOperand op1(this, node->child1());
    2150 
    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 {
     2181            JSValueOperand op1(this, node->child1(), ManualOperandSpeculation);
     2182
     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.
     
    21722208                isNumber.link(&m_jit);
    21732209            }
    2174         }
    2175 
    2176         // First, if we get here we have a double encoded as a JSValue
    2177         m_jit.move(gpr, resultGpr);
    2178         unboxDouble(resultGpr, fpr);
    2179 
    2180         silentSpillAllRegisters(resultGpr);
    2181         callOperation(toInt32, resultGpr, fpr);
    2182         silentFillAllRegisters(resultGpr);
    2183 
    2184         converted.append(m_jit.jump());
    2185 
    2186         isInteger.link(&m_jit);
    2187         m_jit.zeroExtend32ToPtr(gpr, resultGpr);
    2188 
    2189         converted.link(&m_jit);
     2210
     2211            // First, if we get here we have a double encoded as a JSValue
     2212            m_jit.move(gpr, resultGpr);
     2213            unboxDouble(resultGpr, fpr);
     2214
     2215            silentSpillAllRegisters(resultGpr);
     2216            callOperation(toInt32, resultGpr, fpr);
     2217            silentFillAllRegisters(resultGpr);
     2218
     2219            converted.append(m_jit.jump());
     2220
     2221            isInteger.link(&m_jit);
     2222            m_jit.zeroExtend32ToPtr(gpr, resultGpr);
     2223
     2224            converted.link(&m_jit);
    21902225#else
    2191         Node* childNode = node->child1().node();
    2192         VirtualRegister virtualRegister = childNode->virtualRegister();
    2193         GenerationInfo& info = m_generationInfo[virtualRegister];
    2194 
    2195         JSValueOperand op1(this, node->child1());
    2196 
    2197         GPRReg payloadGPR = op1.payloadGPR();
    2198         GPRReg resultGpr = result.gpr();
    2199        
    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));
    2211 
    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 {
     2226            Node* childNode = node->child1().node();
     2227            VirtualRegister virtualRegister = childNode->virtualRegister();
     2228            GenerationInfo& info = m_generationInfo[virtualRegister];
     2229
     2230            JSValueOperand op1(this, node->child1(), ManualOperandSpeculation);
     2231
     2232            GPRReg payloadGPR = op1.payloadGPR();
     2233            GPRReg resultGpr = result.gpr();
     2234       
     2235            JITCompiler::JumpList converted;
     2236
     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.
     
    22302270                    isNumber.link(&m_jit);
    22312271                }
     2272
     2273                unboxDouble(tagGPR, payloadGPR, fpr, scratch.fpr());
     2274
     2275                silentSpillAllRegisters(resultGpr);
     2276                callOperation(toInt32, resultGpr, fpr);
     2277                silentFillAllRegisters(resultGpr);
     2278
     2279                converted.append(m_jit.jump());
     2280
     2281                isInteger.link(&m_jit);
     2282                m_jit.move(payloadGPR, resultGpr);
     2283
     2284                converted.link(&m_jit);
    22322285            }
    2233 
    2234             unboxDouble(tagGPR, payloadGPR, fpr, scratch.fpr());
    2235 
    2236             silentSpillAllRegisters(resultGpr);
    2237             callOperation(toInt32, resultGpr, fpr);
    2238             silentFillAllRegisters(resultGpr);
    2239 
    2240             converted.append(m_jit.jump());
    2241 
    2242             isInteger.link(&m_jit);
    2243             m_jit.move(payloadGPR, resultGpr);
    2244 
    2245             converted.link(&m_jit);
    2246         }
    2247 #endif
    2248         integerResult(resultGpr, node);
    2249         return;
    2250     }
    2251     case GeneratedOperandTypeUnknown:
     2286#endif
     2287            integerResult(resultGpr, node);
     2288            return;
     2289        }
     2290        case GeneratedOperandTypeUnknown:
     2291            RELEASE_ASSERT_NOT_REACHED();
     2292            return;
     2293        }
     2294        RELEASE_ASSERT_NOT_REACHED();
     2295        return;
     2296    }
     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}
     
    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());
     
    23212379    }
    23222380   
    2323     JSValueOperand op1(this, node->child1());
     2381    JSValueOperand op1(this, node->child1(), ManualOperandSpeculation);
    23242382    FPRTemporary result(this);
    23252383   
     
    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        }
     
    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        }
     
    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;
    2570     }
     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        }
     2642    }
     2643   
    25712644    ASSERT_UNUSED(valueGPR, valueGPR != property);
    25722645    ASSERT(valueGPR != base);
     
    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
     
    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);
     
    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               
     
    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());
     
    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
     
    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);
     
    30853162    }
    30863163       
    3087     SpeculateDoubleOperand op1(this, node->child1());
    3088     SpeculateDoubleOperand op2(this, node->child2());
    3089     FPRTemporary result(this, op1);
    3090 
    3091     FPRReg reg1 = op1.fpr();
    3092     FPRReg reg2 = op2.fpr();
    3093     m_jit.subDouble(reg1, reg2, result.fpr());
    3094 
    3095     doubleResult(result.fpr(), node);
     3164    case NumberUse: {
     3165        SpeculateDoubleOperand op1(this, node->child1());
     3166        SpeculateDoubleOperand op2(this, node->child2());
     3167        FPRTemporary result(this, op1);
     3168
     3169        FPRReg reg1 = op1.fpr();
     3170        FPRReg reg2 = op2.fpr();
     3171        m_jit.subDouble(reg1, reg2, result.fpr());
     3172
     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);
     
    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());
     
    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();
    3166        
    3167     m_jit.mulDouble(reg1, reg2, result.fpr());
    3168        
    3169     doubleResult(result.fpr(), node);
     3254       
     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());
     3264       
     3265        doubleResult(result.fpr(), node);
     3266        return;
     3267    }
     3268       
     3269    default:
     3270        RELEASE_ASSERT_NOT_REACHED();
     3271        return;
     3272    }
    31703273}
    31713274
     
    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());
    3287        
    3288     FPRReg op1FPR = op1.fpr();
    3289     FPRReg op2FPR = op2.fpr();
    3290        
    3291     flushRegisters();
    3292        
    3293     FPRResult result(this);
    3294 
    3295     callOperation(fmodAsDFGOperation, result.fpr(), op1FPR, op2FPR);
    3296        
    3297     doubleResult(result.fpr(), node);
     3388    case NumberUse: {
     3389        SpeculateDoubleOperand op1(this, node->child1());
     3390        SpeculateDoubleOperand op2(this, node->child2());
     3391       
     3392        FPRReg op1FPR = op1.fpr();
     3393        FPRReg op2FPR = op2.fpr();
     3394       
     3395        flushRegisters();
     3396       
     3397        FPRResult result(this);
     3398       
     3399        callOperation(fmodAsDFGOperation, result.fpr(), op1FPR, op2FPR);
     3400       
     3401        doubleResult(result.fpr(), node);
     3402        return;
     3403    }
     3404       
     3405    default:
     3406        RELEASE_ASSERT_NOT_REACHED();
     3407        return;
     3408    }
    32983409}
    32993410
     
    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;
     
    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;
     
    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) {
     
    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) {
     
    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) {
     
    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
     
    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
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r143247 r143654  
    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&);
    129 #endif
    130     GPRReg fillStorage(Node*);
     128    bool fillJSValue(Edge, GPRReg&, GPRReg&, FPRReg&);
     129#endif
     130    GPRReg fillStorage(Edge);
    131131
    132132    // lock and unlock GPR & FPR registers.
     
    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
     
    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); }
     
    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   
     
    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*);
     
    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   
     
    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
     
    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.
     
    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
     
    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    }
     
    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
     
    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    }
     
    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;
     
    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)
     
    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
     
    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
     
    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    }
     
    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
     
    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;
     
    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    }
     
    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   
     
    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    }
     
    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};
     
    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
     
    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    }
     
    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
     
    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    }
     
    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;
     
    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    }
     
    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
     
    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    }
     
    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};
     
    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    }
     
    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
     
    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    }
     
    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;
     
    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    }
     
    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
     
    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    }
     
    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;
     
    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    }
     
    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   
     
    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    }
     
    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
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r143314 r143654  
    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
     
    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            }
     
    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
     
    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();
     
    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;
     
    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);
     
    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();
     
    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);
     
    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);
     
    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();
     
    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();
     
    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
     
    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()) {
     
    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);
     
    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);
     
    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
     
    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()) {
     
    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();
     
    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);
     
    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);
     
    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(
     
    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(
     
    13281329{
    13291330    SpeculateCellOperand op1(this, leftChild);
    1330     JSValueOperand op2(this, rightChild);
     1331    JSValueOperand op2(this, rightChild, ManualOperandSpeculation);
    13311332    GPRTemporary result(this);
    13321333   
     
    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);
     
    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(
     
    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);
     
    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(
     
    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,
     
    14401431   
    14411432    SpeculateCellOperand op1(this, leftChild);
    1442     JSValueOperand op2(this, rightChild);
     1433    JSValueOperand op2(this, rightChild, ManualOperandSpeculation);
    14431434    GPRTemporary result(this);
    14441435   
     
    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);
     
    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(
     
    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);
     
    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(
     
    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 {
     
    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,
     
    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();
     
    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);
     
    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 =
     
    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,
     
    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);
     
    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);
     
    16781660        return;
    16791661    }
    1680     if (node->child1()->shouldSpeculateNumber()) {
     1662       
     1663    case NumberUse: {
    16811664        SpeculateDoubleOperand value(this, node->child1());
    16821665        FPRTemporary scratch(this);
     
    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();
    1697        
    1698     arg1.use();
    1699 
    1700     JITCompiler::Jump slowCase = m_jit.branch32(JITCompiler::NotEqual, arg1TagGPR, TrustedImm32(JSValue::BooleanTag));
    1701    
    1702     m_jit.move(arg1PayloadGPR, resultPayloadGPR);
    1703 
    1704     addSlowPathGenerator(
    1705         slowPathCall(
    1706             slowCase, this, dfgConvertJSValueToBoolean, resultPayloadGPR, arg1TagGPR,
    1707             arg1PayloadGPR));
    1708    
    1709     m_jit.xor32(TrustedImm32(1), resultPayloadGPR);
    1710     booleanResult(resultPayloadGPR, node, UseChildrenCalledExplicitly);
     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();
     1681       
     1682        arg1.use();
     1683
     1684        JITCompiler::Jump slowCase = m_jit.branch32(JITCompiler::NotEqual, arg1TagGPR, TrustedImm32(JSValue::BooleanTag));
     1685   
     1686        m_jit.move(arg1PayloadGPR, resultPayloadGPR);
     1687
     1688        addSlowPathGenerator(
     1689            slowPathCall(
     1690                slowCase, this, dfgConvertJSValueToBoolean, resultPayloadGPR, arg1TagGPR,
     1691                arg1PayloadGPR));
     1692   
     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();
     
    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));
     
    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
     
    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;
     
    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           
     
    18211813    }
    18221814   
    1823     JSValueOperand value(this, node->child1());
    1824     value.fill();
    1825     GPRReg valueTagGPR = value.tagGPR();
    1826     GPRReg valuePayloadGPR = value.payloadGPR();
    1827 
    1828     GPRTemporary result(this);
    1829     GPRReg resultGPR = result.gpr();
    1830    
    1831     use(node->child1());
    1832    
    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);
    1839 
    1840     slowPath.link(&m_jit);
    1841     silentSpillAllRegisters(resultGPR);
    1842     callOperation(dfgConvertJSValueToBoolean, resultGPR, valueTagGPR, valuePayloadGPR);
    1843     silentFillAllRegisters(resultGPR);
    1844    
    1845     branchTest32(JITCompiler::NonZero, resultGPR, taken);
    1846     jump(notTaken);
    1847    
    1848     noResult(node, UseChildrenCalledExplicitly);
     1815    case UntypedUse: {
     1816        JSValueOperand value(this, node->child1());
     1817        value.fill();
     1818        GPRReg valueTagGPR = value.tagGPR();
     1819        GPRReg valuePayloadGPR = value.payloadGPR();
     1820
     1821        GPRTemporary result(this);
     1822        GPRReg resultGPR = result.gpr();
     1823   
     1824        use(node->child1());
     1825   
     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));
     1828
     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);
     1837   
     1838        branchTest32(JITCompiler::NonZero, resultGPR, taken);
     1839        jump(notTaken);
     1840   
     1841        noResult(node, UseChildrenCalledExplicitly);
     1842        return;
     1843    }
     1844       
     1845    default:
     1846        RELEASE_ASSERT_NOT_REACHED();
     1847        break;
     1848    }
    18491849}
    18501850
     
    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    }
     
    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;
     
    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);
     
    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:
     
    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);
     
    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    }
     
    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);
     
    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    }
     
    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());
     
    22902289        }
    22912290       
    2292         SpeculateDoubleOperand op1(this, node->child1());
    2293         SpeculateDoubleOperand op2(this, node->child2());
    2294         FPRTemporary result(this, op1);
    2295        
    2296         MacroAssembler::JumpList done;
    2297        
    2298         MacroAssembler::Jump op1Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleLessThan : MacroAssembler::DoubleGreaterThan, op1.fpr(), op2.fpr());
    2299        
    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());
    2302        
    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());
    2307        
    2308         op2Less.link(&m_jit);
    2309         m_jit.moveDouble(op2.fpr(), result.fpr());
    2310        
    2311         if (op1.fpr() != result.fpr()) {
     2291        case NumberUse: {
     2292            SpeculateDoubleOperand op1(this, node->child1());
     2293            SpeculateDoubleOperand op2(this, node->child2());
     2294            FPRTemporary result(this, op1);
     2295       
     2296            MacroAssembler::JumpList done;
     2297       
     2298            MacroAssembler::Jump op1Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleLessThan : MacroAssembler::DoubleGreaterThan, op1.fpr(), op2.fpr());
     2299       
     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());
     2302       
     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());
    23122306            done.append(m_jit.jump());
    2313            
    2314             op1Less.link(&m_jit);
    2315             m_jit.moveDouble(op1.fpr(), result.fpr());
    2316         } else
    2317             op1Less.link(&m_jit);
    2318        
    2319         done.link(&m_jit);
    2320        
    2321         doubleResult(result.fpr(), node);
     2307       
     2308            op2Less.link(&m_jit);
     2309            m_jit.moveDouble(op2.fpr(), result.fpr());
     2310       
     2311            if (op1.fpr() != result.fpr()) {
     2312                done.append(m_jit.jump());
     2313           
     2314                op1Less.link(&m_jit);
     2315                m_jit.moveDouble(op1.fpr(), result.fpr());
     2316            } else
     2317                op1Less.link(&m_jit);
     2318       
     2319            done.link(&m_jit);
     2320       
     2321            doubleResult(result.fpr(), node);
     2322            break;
     2323        }
     2324           
     2325        default:
     2326            RELEASE_ASSERT_NOT_REACHED();
     2327            break;
     2328        }
    23222329        break;
    23232330    }
     
    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);
     
    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.
     
    32493253            break;
    32503254        }
    3251        
    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();
    3262        
    3263         op1.use();
    3264        
    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()));
    3271            
    3272             alreadyPrimitive.link(&m_jit);
    3273             m_jit.move(op1TagGPR, resultTagGPR);
    3274             m_jit.move(op1PayloadGPR, resultPayloadGPR);
    3275            
    3276             addSlowPathGenerator(
    3277                 slowPathCall(
    3278                     notPrimitive, this, operationToPrimitive,
    3279                     JSValueRegs(resultTagGPR, resultPayloadGPR), op1TagGPR, op1PayloadGPR));
    3280         }
    3281        
    3282         jsValueResult(resultTagGPR, resultPayloadGPR, node, UseChildrenCalledExplicitly);
     3255
     3256        case UntypedUse: {
     3257            JSValueOperand op1(this, node->child1());
     3258            GPRTemporary resultTag(this, op1);
     3259            GPRTemporary resultPayload(this, op1, false);
     3260       
     3261            GPRReg op1TagGPR = op1.tagGPR();
     3262            GPRReg op1PayloadGPR = op1.payloadGPR();
     3263            GPRReg resultTagGPR = resultTag.gpr();
     3264            GPRReg resultPayloadGPR = resultPayload.gpr();
     3265       
     3266            op1.use();
     3267       
     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()));
     3274           
     3275                alreadyPrimitive.link(&m_jit);
     3276                m_jit.move(op1TagGPR, resultTagGPR);
     3277                m_jit.move(op1PayloadGPR, resultPayloadGPR);
     3278           
     3279                addSlowPathGenerator(
     3280                    slowPathCall(
     3281                        notPrimitive, this, operationToPrimitive,
     3282                        JSValueRegs(resultTagGPR, resultPayloadGPR), op1TagGPR, op1PayloadGPR));
     3283            }
     3284       
     3285            jsValueResult(resultTagGPR, resultPayloadGPR, node, UseChildrenCalledExplicitly);
     3286            break;
     3287        }
     3288           
     3289        default:
     3290            RELEASE_ASSERT_NOT_REACHED();
     3291            break;
     3292        }
    32833293        break;
    32843294    }
     
    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));
     
    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));
     
    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           
     
    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);
     
    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);
     
    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    }
     
    39073919        }
    39083920       
    3909         if (isCellSpeculation(node->child1()->prediction())) {
     3921        switch (node->child1().useKind()) {
     3922        case CellUse: {
    39103923            SpeculateCellOperand base(this, node->child1());
    39113924           
     
    39273940        }
    39283941       
    3929         JSValueOperand base(this, node->child1());
    3930         GPRReg baseTagGPR = base.tagGPR();
    3931         GPRReg basePayloadGPR = base.payloadGPR();
    3932 
    3933         GPRResult resultTag(this);
    3934         GPRResult2 resultPayload(this);
    3935         GPRReg resultTagGPR = resultTag.gpr();
    3936         GPRReg resultPayloadGPR = resultPayload.gpr();
    3937 
    3938         base.use();
    3939        
    3940         flushRegisters();
    3941        
    3942         JITCompiler::Jump notCell = m_jit.branch32(JITCompiler::NotEqual, baseTagGPR, TrustedImm32(JSValue::CellTag));
    3943        
    3944         cachedGetById(node->codeOrigin, baseTagGPR, basePayloadGPR, resultTagGPR, resultPayloadGPR, node->identifierNumber(), notCell, DontSpill);
    3945        
    3946         jsValueResult(resultTagGPR, resultPayloadGPR, node, UseChildrenCalledExplicitly);
     3942        case UntypedUse: {
     3943            JSValueOperand base(this, node->child1());
     3944            GPRReg baseTagGPR = base.tagGPR();
     3945            GPRReg basePayloadGPR = base.payloadGPR();
     3946
     3947            GPRResult resultTag(this);
     3948            GPRResult2 resultPayload(this);
     3949            GPRReg resultTagGPR = resultTag.gpr();
     3950            GPRReg resultPayloadGPR = resultPayload.gpr();
     3951
     3952            base.use();
     3953       
     3954            flushRegisters();
     3955       
     3956            JITCompiler::Jump notCell = m_jit.branch32(JITCompiler::NotEqual, baseTagGPR, TrustedImm32(JSValue::CellTag));
     3957       
     3958            cachedGetById(node->codeOrigin, baseTagGPR, basePayloadGPR, resultTagGPR, resultPayloadGPR, node->identifierNumber(), notCell, DontSpill);
     3959       
     3960            jsValueResult(resultTagGPR, resultPayloadGPR, node, UseChildrenCalledExplicitly);
     3961            break;
     3962        }
     3963           
     3964        default:
     3965            RELEASE_ASSERT_NOT_REACHED();
     3966            break;
     3967        }
    39473968        break;
    39483969    }
     
    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);
     
    40334047        m_jit.breakpoint();
    40344048        isOK.link(&m_jit);
     4049#else
     4050        speculaceCell(node->child1());
    40354051#endif
    40364052
     
    40404056       
    40414057    case PhantomPutStructure: {
     4058        ASSERT(isKnownCell(node->child1().node()));
    40424059        ASSERT(node->structureTransitionData().previousStructure->transitionWatchpointSetHasBeenInvalidated());
    40434060        m_jit.addWeakReferenceTransition(
     
    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);
     
    44124431        }
    44134432
    4414         if (!node->child1()->shouldSpeculateCell()) {
     4433        if (node->child1().useKind() == UntypedUse) {
    44154434            isNotCell.link(&m_jit);
    44164435
     
    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.
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r143276 r143654  
    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
     
    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            }
     
    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   
     
    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);
     
    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;
     
    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;
     
    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.
     
    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;
     
    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);
     
    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);
     
    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
     
    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
     
    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);
     
    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;
     
    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;
     
    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
     
    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);
     
    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        }
     
    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        }
     
    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);
     
    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(
     
    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(
     
    13551356{
    13561357    SpeculateCellOperand op1(this, leftChild);
    1357     JSValueOperand op2(this, rightChild);
     1358    JSValueOperand op2(this, rightChild, ManualOperandSpeculation);
    13581359    GPRTemporary result(this);
    13591360   
     
    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);
     
    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(
     
    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);
     
    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(
     
    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,
     
    14651454   
    14661455    SpeculateCellOperand op1(this, leftChild);
    1467     JSValueOperand op2(this, rightChild);
     1456    JSValueOperand op2(this, rightChild, ManualOperandSpeculation);
    14681457    GPRTemporary result(this);
    14691458   
     
    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);
     
    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(
     
    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);
     
    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(
     
    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 {
     
    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)));
     
    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();
     
    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);
     
    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 =
     
    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,
     
    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);
     
    16921664        return;
    16931665    }
    1694     if (node->child1()->shouldSpeculateNumber()) {
     1666       
     1667    case NumberUse: {
    16951668        SpeculateDoubleOperand value(this, node->child1());
    16961669        FPRTemporary scratch(this);
     
    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);
     
    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       
     
    17291703        return;
    17301704    }
    1731    
    1732     JSValueOperand arg1(this, node->child1());
    1733     GPRTemporary result(this);
    1734    
    1735     GPRReg arg1GPR = arg1.gpr();
    1736     GPRReg resultGPR = result.gpr();
    1737    
    1738     arg1.use();
    1739    
    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)));
    1743    
    1744     addSlowPathGenerator(
    1745         slowPathCall(slowCase, this, dfgConvertJSValueToBoolean, resultGPR, arg1GPR));
    1746    
    1747     m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueTrue)), resultGPR);
    1748     jsValueResult(resultGPR, node, DataFormatJSBoolean, UseChildrenCalledExplicitly);
     1705       
     1706    case UntypedUse: {
     1707        JSValueOperand arg1(this, node->child1());
     1708        GPRTemporary result(this);
     1709   
     1710        GPRReg arg1GPR = arg1.gpr();
     1711        GPRReg resultGPR = result.gpr();
     1712   
     1713        arg1.use();
     1714   
     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)));
     1718   
     1719        addSlowPathGenerator(
     1720            slowPathCall(slowCase, this, dfgConvertJSValueToBoolean, resultGPR, arg1GPR));
     1721   
     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();
     
    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));
     
    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);
     
    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           
     
    18381819    }
    18391820
    1840     JSValueOperand value(this, node->child1());
    1841     GPRReg valueGPR = value.gpr();
    1842        
    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;
     1821    case UntypedUse:
     1822    case BooleanUse: {
     1823        JSValueOperand value(this, node->child1(), ManualOperandSpeculation);
     1824        GPRReg valueGPR = value.gpr();
     1825       
     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;
     1830                if (taken == nextBlock()) {
     1831                    condition = MacroAssembler::Zero;
     1832                    BlockIndex tmp = taken;
     1833                    taken = notTaken;
     1834                    notTaken = tmp;
     1835                }
     1836               
     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);
     1842               
     1843                typeCheck(JSValueRegs(valueGPR), node->child1(), SpecBoolean, m_jit.jump());
    18541844            }
    1855                
    1856             branchTest32(condition, valueGPR, TrustedImm32(true), taken);
     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            }
     1854   
     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            }
     1859   
     1860            value.use();
     1861   
     1862            silentSpillAllRegisters(resultGPR);
     1863            callOperation(dfgConvertJSValueToBoolean, resultGPR, valueGPR);
     1864            silentFillAllRegisters(resultGPR);
     1865   
     1866            branchTest32(MacroAssembler::NonZero, resultGPR, taken);
    18571867            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);
    1861                
    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         }
    1873    
    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         }
    1878    
    1879         value.use();
    1880    
    1881         silentSpillAllRegisters(resultGPR);
    1882         callOperation(dfgConvertJSValueToBoolean, resultGPR, valueGPR);
    1883         silentFillAllRegisters(resultGPR);
    1884    
    1885         branchTest32(MacroAssembler::NonZero, resultGPR, taken);
    1886         jump(notTaken);
    1887     }
    1888        
    1889     noResult(node, UseChildrenCalledExplicitly);
     1868        }
     1869       
     1870        noResult(node, UseChildrenCalledExplicitly);
     1871        return;
     1872    }
     1873       
     1874    default:
     1875        RELEASE_ASSERT_NOT_REACHED();
     1876    }
    18901877}
    18911878
     
    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    }
     
    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;
     
    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:
     
    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    }
     
    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);
     
    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    }
     
    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());
     
    22322220        }
    22332221       
    2234         SpeculateDoubleOperand op1(this, node->child1());
    2235         SpeculateDoubleOperand op2(this, node->child2());
    2236         FPRTemporary result(this, op1);
    2237        
    2238         MacroAssembler::JumpList done;
    2239        
    2240         MacroAssembler::Jump op1Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleLessThan : MacroAssembler::DoubleGreaterThan, op1.fpr(), op2.fpr());
    2241        
    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());
    2244        
    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());
    2249        
    2250         op2Less.link(&m_jit);
    2251         m_jit.moveDouble(op2.fpr(), result.fpr());
    2252        
    2253         if (op1.fpr() != result.fpr()) {
     2222        case NumberUse: {
     2223            SpeculateDoubleOperand op1(this, node->child1());
     2224            SpeculateDoubleOperand op2(this, node->child2());
     2225            FPRTemporary result(this, op1);
     2226       
     2227            MacroAssembler::JumpList done;
     2228       
     2229            MacroAssembler::Jump op1Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleLessThan : MacroAssembler::DoubleGreaterThan, op1.fpr(), op2.fpr());
     2230       
     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());
     2233       
     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());
    22542237            done.append(m_jit.jump());
    2255            
    2256             op1Less.link(&m_jit);
    2257             m_jit.moveDouble(op1.fpr(), result.fpr());
    2258         } else
    2259             op1Less.link(&m_jit);
    2260        
    2261         done.link(&m_jit);
    2262        
    2263         doubleResult(result.fpr(), node);
     2238       
     2239            op2Less.link(&m_jit);
     2240            m_jit.moveDouble(op2.fpr(), result.fpr());
     2241       
     2242            if (op1.fpr() != result.fpr()) {
     2243                done.append(m_jit.jump());
     2244           
     2245                op1Less.link(&m_jit);
     2246                m_jit.moveDouble(op1.fpr(), result.fpr());
     2247            } else
     2248                op1Less.link(&m_jit);
     2249       
     2250            done.link(&m_jit);
     2251       
     2252            doubleResult(result.fpr(), node);
     2253            break;
     2254        }
     2255           
     2256        default:
     2257            RELEASE_ASSERT_NOT_REACHED();
     2258            break;
     2259        }
    22642260        break;
    22652261    }
     
    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();
     
    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       
     
    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
     
    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);
     
    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.
     
    31873181        }
    31883182       
    3189         // FIXME: Add string speculation here.
    3190        
    3191         JSValueOperand op1(this, node->child1());
    3192         GPRTemporary result(this, op1);
    3193        
    3194         GPRReg op1GPR = op1.gpr();
    3195         GPRReg resultGPR = result.gpr();
    3196        
    3197         op1.use();
    3198        
    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()));
    3204            
    3205             alreadyPrimitive.link(&m_jit);
    3206             m_jit.move(op1GPR, resultGPR);
    3207            
    3208             addSlowPathGenerator(
    3209                 slowPathCall(notPrimitive, this, operationToPrimitive, resultGPR, op1GPR));
    3210         }
    3211        
    3212         jsValueResult(resultGPR, node, UseChildrenCalledExplicitly);
     3183        case UntypedUse: {
     3184            JSValueOperand op1(this, node->child1());
     3185            GPRTemporary result(this, op1);
     3186       
     3187            GPRReg op1GPR = op1.gpr();
     3188            GPRReg resultGPR = result.gpr();
     3189       
     3190            op1.use();
     3191       
     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()));
     3197           
     3198                alreadyPrimitive.link(&m_jit);
     3199                m_jit.move(op1GPR, resultGPR);
     3200           
     3201                addSlowPathGenerator(
     3202                    slowPathCall(notPrimitive, this, operationToPrimitive, resultGPR, op1GPR));
     3203            }
     3204       
     3205            jsValueResult(resultGPR, node, UseChildrenCalledExplicitly);
     3206            break;
     3207        }
     3208           
     3209        default:
     3210            RELEASE_ASSERT_NOT_REACHED();
     3211            break;
     3212        }
    32133213        break;
    32143214    }
     
    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;
     
    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));
     
    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);
     
    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);
     
    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           
     
    35853576        }
    35863577       
    3587         if (isObjectSpeculation(node->child1()->prediction())) {
     3578        case ObjectUse: {
    35883579            SpeculateCellOperand thisValue(this, node->child1());
    35893580            GPRTemporary result(this, thisValue);
     
    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);
     
    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    }
     
    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);
     
    37933797        }
    37943798       
    3795         JSValueOperand base(this, node->child1());
    3796         GPRTemporary result(this, base);
    3797        
    3798         GPRReg baseGPR = base.gpr();
    3799         GPRReg resultGPR = result.gpr();
    3800        
    3801         base.use();
    3802        
    3803         JITCompiler::Jump notCell = m_jit.branchTest64(JITCompiler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
    3804        
    3805         cachedGetById(node->codeOrigin, baseGPR, resultGPR, node->identifierNumber(), notCell);
    3806        
    3807         jsValueResult(resultGPR, node, UseChildrenCalledExplicitly);
    3808        
     3799        case UntypedUse: {
     3800            JSValueOperand base(this, node->child1());
     3801            GPRTemporary result(this, base);
     3802       
     3803            GPRReg baseGPR = base.gpr();
     3804            GPRReg resultGPR = result.gpr();
     3805       
     3806            base.use();
     3807       
     3808            JITCompiler::Jump notCell = m_jit.branchTest64(JITCompiler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
     3809       
     3810            cachedGetById(node->codeOrigin, baseGPR, resultGPR, node->identifierNumber(), notCell);
     3811       
     3812            jsValueResult(resultGPR, node, UseChildrenCalledExplicitly);
     3813            break;
     3814        }
     3815           
     3816        default:
     3817            RELEASE_ASSERT_NOT_REACHED();
     3818            break;
     3819        }
    38093820        break;
    38103821    }
     
    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();
     
    38343846        }
    38353847       
    3836         JSValueOperand base(this, node->child1());
    3837         GPRReg baseGPR = base.gpr();
    3838 
    3839         GPRResult result(this);
    3840         GPRReg resultGPR = result.gpr();
    3841        
    3842         base.use();
    3843         flushRegisters();
    3844        
    3845         JITCompiler::Jump notCell = m_jit.branchTest64(JITCompiler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
    3846        
    3847         cachedGetById(node->codeOrigin, baseGPR, resultGPR, node->identifierNumber(), notCell, DontSpill);
    3848        
    3849         jsValueResult(resultGPR, node, UseChildrenCalledExplicitly);
    3850 
     3848        case UntypedUse: {
     3849            JSValueOperand base(this, node->child1());
     3850            GPRReg baseGPR = base.gpr();
     3851
     3852            GPRResult result(this);
     3853            GPRReg resultGPR = result.gpr();
     3854       
     3855            base.use();
     3856            flushRegisters();
     3857       
     3858            JITCompiler::Jump notCell = m_jit.branchTest64(JITCompiler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
     3859       
     3860            cachedGetById(node->codeOrigin, baseGPR, resultGPR, node->identifierNumber(), notCell, DontSpill);
     3861       
     3862            jsValueResult(resultGPR, node, UseChildrenCalledExplicitly);
     3863            break;
     3864        }
     3865           
     3866        default:
     3867            RELEASE_ASSERT_NOT_REACHED();
     3868            break;
     3869        }
    38513870        break;
    38523871    }
     
    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);
     
    39433955        m_jit.breakpoint();
    39443956        isOK.link(&m_jit);
     3957#else
     3958        speculateCell(node->child1());
    39453959#endif
    39463960       
     
    39503964       
    39513965    case PhantomPutStructure: {
     3966        ASSERT(isKnownCell(node->child1().node()));
     3967       
    39523968        ASSERT(node->structureTransitionData().previousStructure->transitionWatchpointSetHasBeenInvalidated());
    39533969        m_jit.addWeakReferenceTransition(
     
    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);
     
    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);
    4287 
    4288         if (!node->child1()->shouldSpeculateObject()) {
     4303        if (node->child1().useKind() != UntypedUse)
     4304            DFG_TYPE_CHECK(JSValueSource(valueGPR), node->child1(), SpecCell, isNotCell);
     4305
     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);
     
    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);
     
    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.
  • trunk/Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp

    r142377 r143654  
    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)
     
    318318                   
    319319                    CodeOrigin codeOrigin = node->codeOrigin;
    320                     Node* child1 = node->child1().node();
     320                    Edge child1 = node->child1();
    321321                   
    322322                    insertionSet.insertNode(
     
    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;
  • trunk/Source/JavaScriptCore/dfg/DFGValidate.cpp

    r142377 r143654  
    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   
     
    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   
Note: See TracChangeset for help on using the changeset viewer.