Changeset 167325 in webkit


Ignore:
Timestamp:
Apr 15, 2014 1:26:16 PM (10 years ago)
Author:
fpizlo@apple.com
Message:

DFG IR should keep the data flow of doubles and int52's separate from the data flow of JSValue's
https://bugs.webkit.org/show_bug.cgi?id=131423

Reviewed by Geoffrey Garen.

This introduces more static typing into DFG IR. Previously we just had the notion of
JSValues and Storage. This was weird because doubles weren't always convertible to
JSValues, and Int52s weren't always convertible to either doubles or JSValues. We would
sort of insert explicit conversion nodes just for the places where we knew that an
implicit conversion wouldn't have been possible -- but there was no hard and fast rule so
we'd get bugs from forgetting to do the right conversion.

This patch introduces a hard and fast rule: doubles can never be implicitly converted to
anything but doubles, and likewise Int52's can never be implicitly converted. Conversion
nodes are used for all of the conversions. Int52Rep, DoubleRep, and ValueRep are the
conversions. They are like Identity but return the same value using a different
representation. Likewise, constants may now be represented using either JSConstant,
Int52Constant, or DoubleConstant. UseKinds have been adjusted accordingly, as well.
Int52RepUse and DoubleRepUse are node uses that mean "the node must be of Int52 (or
Double) type". They don't imply checks. There is also DoubleRepRealUse, which means that
we speculate DoubleReal and expect Double representation.

In addition to simplifying a bunch of rules in the IR and making the IR more verifiable,
this also makes it easier to introduce optimizations in the future. It's now possible for
AI to model when/how conversion take place. For example if doing a conversion results in
NaN sanitization, then AI can model this and can allow us to sink sanitizations. That's
what https://bugs.webkit.org/show_bug.cgi?id=131419 will be all about.

This was a big change, so I had to do some interesting things, like finally get rid of
the DFG's weird variadic template macro hacks and use real C++11 variadic templates. Also
the ByteCodeParser no longer emits Identity nodes since that was always pointless.

No performance change because this mostly just rationalizes preexisting behavior.

  • JavaScriptCore.xcodeproj/project.pbxproj:
  • assembler/MacroAssemblerX86.h:
  • bytecode/CodeBlock.cpp:
  • bytecode/CodeBlock.h:
  • dfg/DFGAbstractInterpreter.h:

(JSC::DFG::AbstractInterpreter::setBuiltInConstant):
(JSC::DFG::AbstractInterpreter::setConstant):

  • dfg/DFGAbstractInterpreterInlines.h:

(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):

  • dfg/DFGAbstractValue.cpp:

(JSC::DFG::AbstractValue::set):
(JSC::DFG::AbstractValue::fixTypeForRepresentation):
(JSC::DFG::AbstractValue::checkConsistency):

  • dfg/DFGAbstractValue.h:
  • dfg/DFGBackwardsPropagationPhase.cpp:

(JSC::DFG::BackwardsPropagationPhase::propagate):

  • dfg/DFGBasicBlock.h:
  • dfg/DFGBasicBlockInlines.h:

(JSC::DFG::BasicBlock::appendNode):
(JSC::DFG::BasicBlock::appendNonTerminal):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::parseBlock):

  • dfg/DFGCSEPhase.cpp:

(JSC::DFG::CSEPhase::constantCSE):
(JSC::DFG::CSEPhase::performNodeCSE):
(JSC::DFG::CSEPhase::int32ToDoubleCSE): Deleted.

  • dfg/DFGCapabilities.h:
  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

  • dfg/DFGConstantFoldingPhase.cpp:

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

  • dfg/DFGDCEPhase.cpp:

(JSC::DFG::DCEPhase::fixupBlock):

  • dfg/DFGEdge.h:

(JSC::DFG::Edge::willNotHaveCheck):

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::run):
(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::fixupGetAndSetLocalsInBlock):
(JSC::DFG::FixupPhase::observeUseKindOnNode):
(JSC::DFG::FixupPhase::fixIntEdge):
(JSC::DFG::FixupPhase::attemptToMakeIntegerAdd):
(JSC::DFG::FixupPhase::injectTypeConversionsInBlock):
(JSC::DFG::FixupPhase::tryToRelaxRepresentation):
(JSC::DFG::FixupPhase::fixEdgeRepresentation):
(JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
(JSC::DFG::FixupPhase::addRequiredPhantom):
(JSC::DFG::FixupPhase::addPhantomsIfNecessary):
(JSC::DFG::FixupPhase::clearPhantomsAtEnd):
(JSC::DFG::FixupPhase::fixupSetLocalsInBlock): Deleted.

  • dfg/DFGFlushFormat.h:

(JSC::DFG::resultFor):
(JSC::DFG::useKindFor):

  • dfg/DFGGraph.cpp:

(JSC::DFG::Graph::dump):

  • dfg/DFGGraph.h:

(JSC::DFG::Graph::addNode):

  • dfg/DFGInPlaceAbstractState.cpp:

(JSC::DFG::InPlaceAbstractState::initialize):

  • dfg/DFGInsertionSet.h:

(JSC::DFG::InsertionSet::insertNode):
(JSC::DFG::InsertionSet::insertConstant):
(JSC::DFG::InsertionSet::insertConstantForUse):

  • dfg/DFGIntegerCheckCombiningPhase.cpp:

(JSC::DFG::IntegerCheckCombiningPhase::insertAdd):
(JSC::DFG::IntegerCheckCombiningPhase::insertMustAdd):

  • dfg/DFGNode.cpp:

(JSC::DFG::Node::convertToIdentity):
(WTF::printInternal):

  • dfg/DFGNode.h:

(JSC::DFG::Node::Node):
(JSC::DFG::Node::setResult):
(JSC::DFG::Node::result):
(JSC::DFG::Node::isConstant):
(JSC::DFG::Node::hasConstant):
(JSC::DFG::Node::convertToConstant):
(JSC::DFG::Node::valueOfJSConstant):
(JSC::DFG::Node::hasResult):
(JSC::DFG::Node::hasInt32Result):
(JSC::DFG::Node::hasInt52Result):
(JSC::DFG::Node::hasNumberResult):
(JSC::DFG::Node::hasDoubleResult):
(JSC::DFG::Node::hasJSResult):
(JSC::DFG::Node::hasBooleanResult):
(JSC::DFG::Node::hasStorageResult):
(JSC::DFG::Node::defaultUseKind):
(JSC::DFG::Node::defaultEdge):
(JSC::DFG::Node::convertToIdentity): Deleted.

  • dfg/DFGNodeFlags.cpp:

(JSC::DFG::dumpNodeFlags):

  • dfg/DFGNodeFlags.h:

(JSC::DFG::canonicalResultRepresentation):

  • dfg/DFGNodeType.h:
  • dfg/DFGOSRExitCompiler32_64.cpp:

(JSC::DFG::OSRExitCompiler::compileExit):

  • dfg/DFGOSRExitCompiler64.cpp:

(JSC::DFG::OSRExitCompiler::compileExit):

  • dfg/DFGPredictionPropagationPhase.cpp:

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

  • dfg/DFGResurrectionForValidationPhase.cpp:

(JSC::DFG::ResurrectionForValidationPhase::run):

  • dfg/DFGSSAConversionPhase.cpp:

(JSC::DFG::SSAConversionPhase::run):

  • dfg/DFGSafeToExecute.h:

(JSC::DFG::SafeToExecuteEdge::operator()):
(JSC::DFG::safeToExecute):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::silentSavePlanForGPR):
(JSC::DFG::SpeculativeJIT::silentSavePlanForFPR):
(JSC::DFG::SpeculativeJIT::silentFill):
(JSC::DFG::JSValueRegsTemporary::JSValueRegsTemporary):
(JSC::DFG::JSValueRegsTemporary::~JSValueRegsTemporary):
(JSC::DFG::JSValueRegsTemporary::regs):
(JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
(JSC::DFG::SpeculativeJIT::checkGeneratedTypeForToInt32):
(JSC::DFG::SpeculativeJIT::compileValueToInt32):
(JSC::DFG::SpeculativeJIT::compileDoubleRep):
(JSC::DFG::SpeculativeJIT::compileValueRep):
(JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
(JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
(JSC::DFG::SpeculativeJIT::compileAdd):
(JSC::DFG::SpeculativeJIT::compileArithSub):
(JSC::DFG::SpeculativeJIT::compileArithNegate):
(JSC::DFG::SpeculativeJIT::compileArithMul):
(JSC::DFG::SpeculativeJIT::compileArithDiv):
(JSC::DFG::SpeculativeJIT::compileArithMod):
(JSC::DFG::SpeculativeJIT::compare):
(JSC::DFG::SpeculativeJIT::compileStrictEq):
(JSC::DFG::SpeculativeJIT::speculateNumber):
(JSC::DFG::SpeculativeJIT::speculateDoubleReal):
(JSC::DFG::SpeculativeJIT::speculate):
(JSC::DFG::SpeculativeJIT::compileInt32ToDouble): Deleted.
(JSC::DFG::SpeculativeJIT::speculateMachineInt): Deleted.
(JSC::DFG::SpeculativeJIT::speculateRealNumber): Deleted.

  • dfg/DFGSpeculativeJIT.h:

(JSC::DFG::SpeculativeJIT::allocate):
(JSC::DFG::SpeculativeJIT::use):
(JSC::DFG::SpeculativeJIT::boxDouble):
(JSC::DFG::SpeculativeJIT::spill):
(JSC::DFG::SpeculativeJIT::jsValueResult):
(JSC::DFG::SpeculateInt52Operand::SpeculateInt52Operand):
(JSC::DFG::SpeculateStrictInt52Operand::SpeculateStrictInt52Operand):
(JSC::DFG::SpeculateWhicheverInt52Operand::SpeculateWhicheverInt52Operand):
(JSC::DFG::SpeculateDoubleOperand::SpeculateDoubleOperand):

  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::fillJSValue):
(JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
(JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
(JSC::DFG::SpeculativeJIT::fillSpeculateCell):
(JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
(JSC::DFG::SpeculativeJIT::compileLogicalNot):
(JSC::DFG::SpeculativeJIT::emitBranch):
(JSC::DFG::SpeculativeJIT::compile):
(JSC::DFG::SpeculativeJIT::convertToDouble): Deleted.

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::fillJSValue):
(JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
(JSC::DFG::SpeculativeJIT::fillSpeculateInt52):
(JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
(JSC::DFG::SpeculativeJIT::fillSpeculateCell):
(JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
(JSC::DFG::SpeculativeJIT::compileLogicalNot):
(JSC::DFG::SpeculativeJIT::emitBranch):
(JSC::DFG::SpeculativeJIT::compile):
(JSC::DFG::SpeculativeJIT::convertToDouble): Deleted.

  • dfg/DFGStrengthReductionPhase.cpp:

(JSC::DFG::StrengthReductionPhase::handleNode):

  • dfg/DFGUseKind.cpp:

(WTF::printInternal):

  • dfg/DFGUseKind.h:

(JSC::DFG::typeFilterFor):
(JSC::DFG::shouldNotHaveTypeCheck):
(JSC::DFG::mayHaveTypeCheck):
(JSC::DFG::isNumerical):
(JSC::DFG::isDouble):
(JSC::DFG::isCell):
(JSC::DFG::usesStructure):
(JSC::DFG::useKindForResult):

  • dfg/DFGValidate.cpp:

(JSC::DFG::Validate::validate):

  • dfg/DFGVariadicFunction.h: Removed.
  • ftl/FTLCapabilities.cpp:

(JSC::FTL::canCompile):

  • ftl/FTLLowerDFGToLLVM.cpp:

(JSC::FTL::LowerDFGToLLVM::createPhiVariables):
(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compileUpsilon):
(JSC::FTL::LowerDFGToLLVM::compilePhi):
(JSC::FTL::LowerDFGToLLVM::compileDoubleConstant):
(JSC::FTL::LowerDFGToLLVM::compileInt52Constant):
(JSC::FTL::LowerDFGToLLVM::compileWeakJSConstant):
(JSC::FTL::LowerDFGToLLVM::compileDoubleRep):
(JSC::FTL::LowerDFGToLLVM::compileValueRep):
(JSC::FTL::LowerDFGToLLVM::compileInt52Rep):
(JSC::FTL::LowerDFGToLLVM::compileValueToInt32):
(JSC::FTL::LowerDFGToLLVM::compileArithAddOrSub):
(JSC::FTL::LowerDFGToLLVM::compileArithMul):
(JSC::FTL::LowerDFGToLLVM::compileArithDiv):
(JSC::FTL::LowerDFGToLLVM::compileArithMod):
(JSC::FTL::LowerDFGToLLVM::compileArithMinOrMax):
(JSC::FTL::LowerDFGToLLVM::compileArithAbs):
(JSC::FTL::LowerDFGToLLVM::compileArithNegate):
(JSC::FTL::LowerDFGToLLVM::compilePutByVal):
(JSC::FTL::LowerDFGToLLVM::compileCompareEq):
(JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
(JSC::FTL::LowerDFGToLLVM::compare):
(JSC::FTL::LowerDFGToLLVM::boolify):
(JSC::FTL::LowerDFGToLLVM::lowInt52):
(JSC::FTL::LowerDFGToLLVM::lowStrictInt52):
(JSC::FTL::LowerDFGToLLVM::lowWhicheverInt52):
(JSC::FTL::LowerDFGToLLVM::lowDouble):
(JSC::FTL::LowerDFGToLLVM::lowJSValue):
(JSC::FTL::LowerDFGToLLVM::strictInt52ToDouble):
(JSC::FTL::LowerDFGToLLVM::jsValueToDouble):
(JSC::FTL::LowerDFGToLLVM::speculate):
(JSC::FTL::LowerDFGToLLVM::speculateNumber):
(JSC::FTL::LowerDFGToLLVM::speculateDoubleReal):
(JSC::FTL::LowerDFGToLLVM::compileInt52ToValue): Deleted.
(JSC::FTL::LowerDFGToLLVM::compileInt32ToDouble): Deleted.
(JSC::FTL::LowerDFGToLLVM::setInt52WithStrictValue): Deleted.
(JSC::FTL::LowerDFGToLLVM::speculateRealNumber): Deleted.
(JSC::FTL::LowerDFGToLLVM::speculateMachineInt): Deleted.

  • ftl/FTLValueFormat.cpp:

(JSC::FTL::reboxAccordingToFormat):

  • jit/AssemblyHelpers.cpp:

(JSC::AssemblyHelpers::sanitizeDouble):

  • jit/AssemblyHelpers.h:

(JSC::AssemblyHelpers::boxDouble):

Location:
trunk/Source/JavaScriptCore
Files:
1 deleted
50 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r167313 r167325  
     12014-04-15  Filip Pizlo  <fpizlo@apple.com>
     2
     3        DFG IR should keep the data flow of doubles and int52's separate from the data flow of JSValue's
     4        https://bugs.webkit.org/show_bug.cgi?id=131423
     5
     6        Reviewed by Geoffrey Garen.
     7       
     8        This introduces more static typing into DFG IR. Previously we just had the notion of
     9        JSValues and Storage. This was weird because doubles weren't always convertible to
     10        JSValues, and Int52s weren't always convertible to either doubles or JSValues. We would
     11        sort of insert explicit conversion nodes just for the places where we knew that an
     12        implicit conversion wouldn't have been possible -- but there was no hard and fast rule so
     13        we'd get bugs from forgetting to do the right conversion.
     14       
     15        This patch introduces a hard and fast rule: doubles can never be implicitly converted to
     16        anything but doubles, and likewise Int52's can never be implicitly converted. Conversion
     17        nodes are used for all of the conversions. Int52Rep, DoubleRep, and ValueRep are the
     18        conversions. They are like Identity but return the same value using a different
     19        representation. Likewise, constants may now be represented using either JSConstant,
     20        Int52Constant, or DoubleConstant. UseKinds have been adjusted accordingly, as well.
     21        Int52RepUse and DoubleRepUse are node uses that mean "the node must be of Int52 (or
     22        Double) type". They don't imply checks. There is also DoubleRepRealUse, which means that
     23        we speculate DoubleReal and expect Double representation.
     24       
     25        In addition to simplifying a bunch of rules in the IR and making the IR more verifiable,
     26        this also makes it easier to introduce optimizations in the future. It's now possible for
     27        AI to model when/how conversion take place. For example if doing a conversion results in
     28        NaN sanitization, then AI can model this and can allow us to sink sanitizations. That's
     29        what https://bugs.webkit.org/show_bug.cgi?id=131419 will be all about.
     30       
     31        This was a big change, so I had to do some interesting things, like finally get rid of
     32        the DFG's weird variadic template macro hacks and use real C++11 variadic templates. Also
     33        the ByteCodeParser no longer emits Identity nodes since that was always pointless.
     34       
     35        No performance change because this mostly just rationalizes preexisting behavior.
     36
     37        * JavaScriptCore.xcodeproj/project.pbxproj:
     38        * assembler/MacroAssemblerX86.h:
     39        * bytecode/CodeBlock.cpp:
     40        * bytecode/CodeBlock.h:
     41        * dfg/DFGAbstractInterpreter.h:
     42        (JSC::DFG::AbstractInterpreter::setBuiltInConstant):
     43        (JSC::DFG::AbstractInterpreter::setConstant):
     44        * dfg/DFGAbstractInterpreterInlines.h:
     45        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
     46        * dfg/DFGAbstractValue.cpp:
     47        (JSC::DFG::AbstractValue::set):
     48        (JSC::DFG::AbstractValue::fixTypeForRepresentation):
     49        (JSC::DFG::AbstractValue::checkConsistency):
     50        * dfg/DFGAbstractValue.h:
     51        * dfg/DFGBackwardsPropagationPhase.cpp:
     52        (JSC::DFG::BackwardsPropagationPhase::propagate):
     53        * dfg/DFGBasicBlock.h:
     54        * dfg/DFGBasicBlockInlines.h:
     55        (JSC::DFG::BasicBlock::appendNode):
     56        (JSC::DFG::BasicBlock::appendNonTerminal):
     57        * dfg/DFGByteCodeParser.cpp:
     58        (JSC::DFG::ByteCodeParser::parseBlock):
     59        * dfg/DFGCSEPhase.cpp:
     60        (JSC::DFG::CSEPhase::constantCSE):
     61        (JSC::DFG::CSEPhase::performNodeCSE):
     62        (JSC::DFG::CSEPhase::int32ToDoubleCSE): Deleted.
     63        * dfg/DFGCapabilities.h:
     64        * dfg/DFGClobberize.h:
     65        (JSC::DFG::clobberize):
     66        * dfg/DFGConstantFoldingPhase.cpp:
     67        (JSC::DFG::ConstantFoldingPhase::foldConstants):
     68        * dfg/DFGDCEPhase.cpp:
     69        (JSC::DFG::DCEPhase::fixupBlock):
     70        * dfg/DFGEdge.h:
     71        (JSC::DFG::Edge::willNotHaveCheck):
     72        * dfg/DFGFixupPhase.cpp:
     73        (JSC::DFG::FixupPhase::run):
     74        (JSC::DFG::FixupPhase::fixupNode):
     75        (JSC::DFG::FixupPhase::fixupGetAndSetLocalsInBlock):
     76        (JSC::DFG::FixupPhase::observeUseKindOnNode):
     77        (JSC::DFG::FixupPhase::fixIntEdge):
     78        (JSC::DFG::FixupPhase::attemptToMakeIntegerAdd):
     79        (JSC::DFG::FixupPhase::injectTypeConversionsInBlock):
     80        (JSC::DFG::FixupPhase::tryToRelaxRepresentation):
     81        (JSC::DFG::FixupPhase::fixEdgeRepresentation):
     82        (JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
     83        (JSC::DFG::FixupPhase::addRequiredPhantom):
     84        (JSC::DFG::FixupPhase::addPhantomsIfNecessary):
     85        (JSC::DFG::FixupPhase::clearPhantomsAtEnd):
     86        (JSC::DFG::FixupPhase::fixupSetLocalsInBlock): Deleted.
     87        * dfg/DFGFlushFormat.h:
     88        (JSC::DFG::resultFor):
     89        (JSC::DFG::useKindFor):
     90        * dfg/DFGGraph.cpp:
     91        (JSC::DFG::Graph::dump):
     92        * dfg/DFGGraph.h:
     93        (JSC::DFG::Graph::addNode):
     94        * dfg/DFGInPlaceAbstractState.cpp:
     95        (JSC::DFG::InPlaceAbstractState::initialize):
     96        * dfg/DFGInsertionSet.h:
     97        (JSC::DFG::InsertionSet::insertNode):
     98        (JSC::DFG::InsertionSet::insertConstant):
     99        (JSC::DFG::InsertionSet::insertConstantForUse):
     100        * dfg/DFGIntegerCheckCombiningPhase.cpp:
     101        (JSC::DFG::IntegerCheckCombiningPhase::insertAdd):
     102        (JSC::DFG::IntegerCheckCombiningPhase::insertMustAdd):
     103        * dfg/DFGNode.cpp:
     104        (JSC::DFG::Node::convertToIdentity):
     105        (WTF::printInternal):
     106        * dfg/DFGNode.h:
     107        (JSC::DFG::Node::Node):
     108        (JSC::DFG::Node::setResult):
     109        (JSC::DFG::Node::result):
     110        (JSC::DFG::Node::isConstant):
     111        (JSC::DFG::Node::hasConstant):
     112        (JSC::DFG::Node::convertToConstant):
     113        (JSC::DFG::Node::valueOfJSConstant):
     114        (JSC::DFG::Node::hasResult):
     115        (JSC::DFG::Node::hasInt32Result):
     116        (JSC::DFG::Node::hasInt52Result):
     117        (JSC::DFG::Node::hasNumberResult):
     118        (JSC::DFG::Node::hasDoubleResult):
     119        (JSC::DFG::Node::hasJSResult):
     120        (JSC::DFG::Node::hasBooleanResult):
     121        (JSC::DFG::Node::hasStorageResult):
     122        (JSC::DFG::Node::defaultUseKind):
     123        (JSC::DFG::Node::defaultEdge):
     124        (JSC::DFG::Node::convertToIdentity): Deleted.
     125        * dfg/DFGNodeFlags.cpp:
     126        (JSC::DFG::dumpNodeFlags):
     127        * dfg/DFGNodeFlags.h:
     128        (JSC::DFG::canonicalResultRepresentation):
     129        * dfg/DFGNodeType.h:
     130        * dfg/DFGOSRExitCompiler32_64.cpp:
     131        (JSC::DFG::OSRExitCompiler::compileExit):
     132        * dfg/DFGOSRExitCompiler64.cpp:
     133        (JSC::DFG::OSRExitCompiler::compileExit):
     134        * dfg/DFGPredictionPropagationPhase.cpp:
     135        (JSC::DFG::PredictionPropagationPhase::propagate):
     136        * dfg/DFGResurrectionForValidationPhase.cpp:
     137        (JSC::DFG::ResurrectionForValidationPhase::run):
     138        * dfg/DFGSSAConversionPhase.cpp:
     139        (JSC::DFG::SSAConversionPhase::run):
     140        * dfg/DFGSafeToExecute.h:
     141        (JSC::DFG::SafeToExecuteEdge::operator()):
     142        (JSC::DFG::safeToExecute):
     143        * dfg/DFGSpeculativeJIT.cpp:
     144        (JSC::DFG::SpeculativeJIT::silentSavePlanForGPR):
     145        (JSC::DFG::SpeculativeJIT::silentSavePlanForFPR):
     146        (JSC::DFG::SpeculativeJIT::silentFill):
     147        (JSC::DFG::JSValueRegsTemporary::JSValueRegsTemporary):
     148        (JSC::DFG::JSValueRegsTemporary::~JSValueRegsTemporary):
     149        (JSC::DFG::JSValueRegsTemporary::regs):
     150        (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
     151        (JSC::DFG::SpeculativeJIT::checkGeneratedTypeForToInt32):
     152        (JSC::DFG::SpeculativeJIT::compileValueToInt32):
     153        (JSC::DFG::SpeculativeJIT::compileDoubleRep):
     154        (JSC::DFG::SpeculativeJIT::compileValueRep):
     155        (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
     156        (JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
     157        (JSC::DFG::SpeculativeJIT::compileAdd):
     158        (JSC::DFG::SpeculativeJIT::compileArithSub):
     159        (JSC::DFG::SpeculativeJIT::compileArithNegate):
     160        (JSC::DFG::SpeculativeJIT::compileArithMul):
     161        (JSC::DFG::SpeculativeJIT::compileArithDiv):
     162        (JSC::DFG::SpeculativeJIT::compileArithMod):
     163        (JSC::DFG::SpeculativeJIT::compare):
     164        (JSC::DFG::SpeculativeJIT::compileStrictEq):
     165        (JSC::DFG::SpeculativeJIT::speculateNumber):
     166        (JSC::DFG::SpeculativeJIT::speculateDoubleReal):
     167        (JSC::DFG::SpeculativeJIT::speculate):
     168        (JSC::DFG::SpeculativeJIT::compileInt32ToDouble): Deleted.
     169        (JSC::DFG::SpeculativeJIT::speculateMachineInt): Deleted.
     170        (JSC::DFG::SpeculativeJIT::speculateRealNumber): Deleted.
     171        * dfg/DFGSpeculativeJIT.h:
     172        (JSC::DFG::SpeculativeJIT::allocate):
     173        (JSC::DFG::SpeculativeJIT::use):
     174        (JSC::DFG::SpeculativeJIT::boxDouble):
     175        (JSC::DFG::SpeculativeJIT::spill):
     176        (JSC::DFG::SpeculativeJIT::jsValueResult):
     177        (JSC::DFG::SpeculateInt52Operand::SpeculateInt52Operand):
     178        (JSC::DFG::SpeculateStrictInt52Operand::SpeculateStrictInt52Operand):
     179        (JSC::DFG::SpeculateWhicheverInt52Operand::SpeculateWhicheverInt52Operand):
     180        (JSC::DFG::SpeculateDoubleOperand::SpeculateDoubleOperand):
     181        * dfg/DFGSpeculativeJIT32_64.cpp:
     182        (JSC::DFG::SpeculativeJIT::fillJSValue):
     183        (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
     184        (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
     185        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
     186        (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
     187        (JSC::DFG::SpeculativeJIT::compileLogicalNot):
     188        (JSC::DFG::SpeculativeJIT::emitBranch):
     189        (JSC::DFG::SpeculativeJIT::compile):
     190        (JSC::DFG::SpeculativeJIT::convertToDouble): Deleted.
     191        * dfg/DFGSpeculativeJIT64.cpp:
     192        (JSC::DFG::SpeculativeJIT::fillJSValue):
     193        (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
     194        (JSC::DFG::SpeculativeJIT::fillSpeculateInt52):
     195        (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
     196        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
     197        (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
     198        (JSC::DFG::SpeculativeJIT::compileLogicalNot):
     199        (JSC::DFG::SpeculativeJIT::emitBranch):
     200        (JSC::DFG::SpeculativeJIT::compile):
     201        (JSC::DFG::SpeculativeJIT::convertToDouble): Deleted.
     202        * dfg/DFGStrengthReductionPhase.cpp:
     203        (JSC::DFG::StrengthReductionPhase::handleNode):
     204        * dfg/DFGUseKind.cpp:
     205        (WTF::printInternal):
     206        * dfg/DFGUseKind.h:
     207        (JSC::DFG::typeFilterFor):
     208        (JSC::DFG::shouldNotHaveTypeCheck):
     209        (JSC::DFG::mayHaveTypeCheck):
     210        (JSC::DFG::isNumerical):
     211        (JSC::DFG::isDouble):
     212        (JSC::DFG::isCell):
     213        (JSC::DFG::usesStructure):
     214        (JSC::DFG::useKindForResult):
     215        * dfg/DFGValidate.cpp:
     216        (JSC::DFG::Validate::validate):
     217        * dfg/DFGVariadicFunction.h: Removed.
     218        * ftl/FTLCapabilities.cpp:
     219        (JSC::FTL::canCompile):
     220        * ftl/FTLLowerDFGToLLVM.cpp:
     221        (JSC::FTL::LowerDFGToLLVM::createPhiVariables):
     222        (JSC::FTL::LowerDFGToLLVM::compileNode):
     223        (JSC::FTL::LowerDFGToLLVM::compileUpsilon):
     224        (JSC::FTL::LowerDFGToLLVM::compilePhi):
     225        (JSC::FTL::LowerDFGToLLVM::compileDoubleConstant):
     226        (JSC::FTL::LowerDFGToLLVM::compileInt52Constant):
     227        (JSC::FTL::LowerDFGToLLVM::compileWeakJSConstant):
     228        (JSC::FTL::LowerDFGToLLVM::compileDoubleRep):
     229        (JSC::FTL::LowerDFGToLLVM::compileValueRep):
     230        (JSC::FTL::LowerDFGToLLVM::compileInt52Rep):
     231        (JSC::FTL::LowerDFGToLLVM::compileValueToInt32):
     232        (JSC::FTL::LowerDFGToLLVM::compileArithAddOrSub):
     233        (JSC::FTL::LowerDFGToLLVM::compileArithMul):
     234        (JSC::FTL::LowerDFGToLLVM::compileArithDiv):
     235        (JSC::FTL::LowerDFGToLLVM::compileArithMod):
     236        (JSC::FTL::LowerDFGToLLVM::compileArithMinOrMax):
     237        (JSC::FTL::LowerDFGToLLVM::compileArithAbs):
     238        (JSC::FTL::LowerDFGToLLVM::compileArithNegate):
     239        (JSC::FTL::LowerDFGToLLVM::compilePutByVal):
     240        (JSC::FTL::LowerDFGToLLVM::compileCompareEq):
     241        (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
     242        (JSC::FTL::LowerDFGToLLVM::compare):
     243        (JSC::FTL::LowerDFGToLLVM::boolify):
     244        (JSC::FTL::LowerDFGToLLVM::lowInt52):
     245        (JSC::FTL::LowerDFGToLLVM::lowStrictInt52):
     246        (JSC::FTL::LowerDFGToLLVM::lowWhicheverInt52):
     247        (JSC::FTL::LowerDFGToLLVM::lowDouble):
     248        (JSC::FTL::LowerDFGToLLVM::lowJSValue):
     249        (JSC::FTL::LowerDFGToLLVM::strictInt52ToDouble):
     250        (JSC::FTL::LowerDFGToLLVM::jsValueToDouble):
     251        (JSC::FTL::LowerDFGToLLVM::speculate):
     252        (JSC::FTL::LowerDFGToLLVM::speculateNumber):
     253        (JSC::FTL::LowerDFGToLLVM::speculateDoubleReal):
     254        (JSC::FTL::LowerDFGToLLVM::compileInt52ToValue): Deleted.
     255        (JSC::FTL::LowerDFGToLLVM::compileInt32ToDouble): Deleted.
     256        (JSC::FTL::LowerDFGToLLVM::setInt52WithStrictValue): Deleted.
     257        (JSC::FTL::LowerDFGToLLVM::speculateRealNumber): Deleted.
     258        (JSC::FTL::LowerDFGToLLVM::speculateMachineInt): Deleted.
     259        * ftl/FTLValueFormat.cpp:
     260        (JSC::FTL::reboxAccordingToFormat):
     261        * jit/AssemblyHelpers.cpp:
     262        (JSC::AssemblyHelpers::sanitizeDouble):
     263        * jit/AssemblyHelpers.h:
     264        (JSC::AssemblyHelpers::boxDouble):
     265
    12662014-04-15  Commit Queue  <commit-queue@webkit.org>
    2267
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r167313 r167325  
    611611                0FFB921C16D02F110055A5DB /* DFGOSRExitCompilationInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 65987F2C167FE84B003C2F8D /* DFGOSRExitCompilationInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
    612612                0FFB921D16D02F300055A5DB /* DFGSlowPathGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F1E3A501537C2CB000F9456 /* DFGSlowPathGenerator.h */; settings = {ATTRIBUTES = (Private, ); }; };
    613                 0FFB921E16D02F470055A5DB /* DFGVariadicFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F85A31E16AB76AE0077571E /* DFGVariadicFunction.h */; settings = {ATTRIBUTES = (Private, ); }; };
    614613                0FFB922016D033B70055A5DB /* NodeConstructors.h in Headers */ = {isa = PBXBuildFile; fileRef = 930DAD030FB1EB1A0082D205 /* NodeConstructors.h */; settings = {ATTRIBUTES = (Private, ); }; };
    615614                0FFC99D1184EC8AD009C10AB /* ConstantMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FFC99D0184EC8AD009C10AB /* ConstantMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    895894                5540772118DA58AD00EFF7F2 /* JSArrayBufferViewInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66BC17B6B5AB00A7AE3F /* JSArrayBufferViewInlines.h */; };
    896895                5540772218DA58AD00EFF7F2 /* JSArrayIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = A7BDAEC517F4EA1400F6140C /* JSArrayIterator.h */; };
    897                 5540772518DA58AD00EFF7F2 /* JSBoundFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 86FA9E90142BBB2E001773B7 /* JSBoundFunction.h */; };
     896                5540772518DA58AD00EFF7F2 /* (null) in Headers */ = {isa = PBXBuildFile; };
    898897                5540772B18DA58AD00EFF7F2 /* JSCell.h in Headers */ = {isa = PBXBuildFile; fileRef = BC1167D80E19BCC9008066DD /* JSCell.h */; };
    899898                5540772C18DA58AD00EFF7F2 /* JSCellInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F97496F1687ADE200A4FF6A /* JSCellInlines.h */; };
     
    10441043                5540788D18DA58AD00EFF7F2 /* WriteBarrier.h in Headers */ = {isa = PBXBuildFile; fileRef = A7DCB77912E3D90500911940 /* WriteBarrier.h */; };
    10451044                5540788F18DA58AD00EFF7F2 /* WriteBarrierInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = C2B6D75218A33793004A9301 /* WriteBarrierInlines.h */; };
    1046                 5540789E18DA58AD00EFF7F2 /* Arguments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC257DE50E1F51C50016B6C9 /* Arguments.cpp */; };
    1047                 554078A018DA58AD00EFF7F2 /* ArgumentsIteratorPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A76140C9182982CB00750624 /* ArgumentsIteratorPrototype.cpp */; };
    10481045                554078AB18DA58AD00EFF7F2 /* ArrayConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC7952060E15E8A800A898AB /* ArrayConstructor.cpp */; };
    1049                 554078AD18DA58AD00EFF7F2 /* ArrayIteratorPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7BDAEC217F4EA1400F6140C /* ArrayIteratorPrototype.cpp */; };
    10501046                554078AF18DA58AD00EFF7F2 /* ArrayPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A84D0255597D01FF60F7 /* ArrayPrototype.cpp */; };
    1051                 554078B218DA58AD00EFF7F2 /* BooleanConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC7952320E15EB5600A898AB /* BooleanConstructor.cpp */; };
    1052                 554078B418DA58AD00EFF7F2 /* BooleanPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC7952340E15EB5600A898AB /* BooleanPrototype.cpp */; };
    1053                 554078D518DA58AD00EFF7F2 /* DateConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCD203450E17135E002C7E82 /* DateConstructor.cpp */; };
    1054                 554078D818DA58AD00EFF7F2 /* DatePrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCD203470E17135E002C7E82 /* DatePrototype.cpp */; };
    1055                 5540794B18DA58AD00EFF7F2 /* ErrorConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC02E9040E1839DB000F9297 /* ErrorConstructor.cpp */; };
    1056                 5540794E18DA58AD00EFF7F2 /* ErrorPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC02E9060E1839DB000F9297 /* ErrorPrototype.cpp */; };
    1057                 5540797D18DA58AD00EFF7F2 /* FunctionConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC2680C00E16D4E900A06E92 /* FunctionConstructor.cpp */; };
    1058                 5540797F18DA58AD00EFF7F2 /* FunctionPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A85C0255597D01FF60F7 /* FunctionPrototype.cpp */; };
    1059                 554079C218DA58AD00EFF7F2 /* JSArrayBufferConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B66B617B6B5AB00A7AE3F /* JSArrayBufferConstructor.cpp */; };
    1060                 554079C318DA58AD00EFF7F2 /* JSArrayBufferPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B66B817B6B5AB00A7AE3F /* JSArrayBufferPrototype.cpp */; };
    1061                 554079C518DA58AD00EFF7F2 /* JSArrayIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7BDAEC417F4EA1400F6140C /* JSArrayIterator.cpp */; };
    1062                 554079C718DA58AD00EFF7F2 /* JSBoundFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86FA9E8F142BBB2D001773B7 /* JSBoundFunction.cpp */; };
    1063                 554079D318DA58AD00EFF7F2 /* JSDataViewPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B66BF17B6B5AB00A7AE3F /* JSDataViewPrototype.cpp */; };
    1064                 554079D518DA58AD00EFF7F2 /* JSFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A85E0255597D01FF60F7 /* JSFunction.cpp */; };
    1065                 554079DA18DA58AD00EFF7F2 /* JSGlobalObjectFunctions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC756FC60E2031B200DE7D12 /* JSGlobalObjectFunctions.cpp */; };
    1066                 554079EB18DA58AD00EFF7F2 /* JSONObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7F9935E0FD7325100A0B2D0 /* JSONObject.cpp */; };
    1067                 554079EE18DA58AD00EFF7F2 /* JSPromiseConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C184E2017BEE240007CB63A /* JSPromiseConstructor.cpp */; };
    1068                 554079F018DA58AD00EFF7F2 /* JSPromiseFunctions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C008CD0186F8A9300955C24 /* JSPromiseFunctions.cpp */; };
    1069                 554079F118DA58AD00EFF7F2 /* JSPromisePrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C184E1C17BEE22E007CB63A /* JSPromisePrototype.cpp */; };
    1070                 55407A2218DA58AD00EFF7F2 /* ConsolePrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A53CE08118BC1A5600BEDF76 /* ConsolePrototype.cpp */; };
    1071                 55407A2518DA58AD00EFF7F2 /* MapConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A700873717CBE85300C3E643 /* MapConstructor.cpp */; };
    1072                 55407A2818DA58AD00EFF7F2 /* MapIteratorPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A74DEF8D182D991400522C22 /* MapIteratorPrototype.cpp */; };
    1073                 55407A2918DA58AD00EFF7F2 /* MapPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A700873B17CBE8D300C3E643 /* MapPrototype.cpp */; };
    1074                 55407A2E18DA58AD00EFF7F2 /* MathObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A86A0255597D01FF60F7 /* MathObject.cpp */; };
    1075                 55407A3118DA58AD00EFF7F2 /* NameConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86EBF2F91560F036008E9222 /* NameConstructor.cpp */; };
    1076                 55407A3318DA58AD00EFF7F2 /* NamePrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86EBF2FD1560F036008E9222 /* NamePrototype.cpp */; };
    10771047                55407A3818DA58AD00EFF7F2 /* NumberConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC2680C20E16D4E900A06E92 /* NumberConstructor.cpp */; };
    10781048                55407A3A18DA58AD00EFF7F2 /* NumberPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC2680C40E16D4E900A06E92 /* NumberPrototype.cpp */; };
    1079                 55407A3C18DA58AD00EFF7F2 /* ObjectConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC2680C60E16D4E900A06E92 /* ObjectConstructor.cpp */; };
    1080                 55407A3D18DA58AD00EFF7F2 /* ObjectPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC2680C80E16D4E900A06E92 /* ObjectPrototype.cpp */; };
    1081                 55407A6318DA58AD00EFF7F2 /* RegExpConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCD202BD0E1706A7002C7E82 /* RegExpConstructor.cpp */; };
    1082                 55407A6618DA58AD00EFF7F2 /* RegExpPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCD202BF0E1706A7002C7E82 /* RegExpPrototype.cpp */; };
    1083                 55407A7B18DA58AD00EFF7F2 /* SetIteratorPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A790DD67182F499700588807 /* SetIteratorPrototype.cpp */; };
    1084                 55407A7C18DA58AD00EFF7F2 /* SetPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7299D9F17D12848005F5FF9 /* SetPrototype.cpp */; };
    1085                 55407A8818DA58AD00EFF7F2 /* StringConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC18C3C00E16EE3300B34460 /* StringConstructor.cpp */; };
    1086                 55407A8A18DA58AD00EFF7F2 /* StringPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC18C3C50E16EE3300B34460 /* StringPrototype.cpp */; };
    1087                 55407AAC18DA58AD00EFF7F2 /* WeakMapConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7CA3ADD17DA41AE006538AF /* WeakMapConstructor.cpp */; };
    1088                 55407AAE18DA58AD00EFF7F2 /* WeakMapPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7CA3ADF17DA41AE006538AF /* WeakMapPrototype.cpp */; };
    1089                 55F1380B18EF5F5000982015 /* NativeErrorConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC02E9080E1839DB000F9297 /* NativeErrorConstructor.cpp */; };
    1090                 55F1380C18EF5FB900982015 /* SetConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7299DA317D12858005F5FF9 /* SetConstructor.cpp */; };
    10911049                5D53726F0E1C54880021E549 /* Tracing.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D53726E0E1C54880021E549 /* Tracing.h */; };
    10921050                5D5D8AD10E0D0EBE00F9C692 /* libedit.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */; };
     
    21862144                0F8335B51639C1E3001443B5 /* ArrayAllocationProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArrayAllocationProfile.h; sourceTree = "<group>"; };
    21872145                0F8364B5164B0C0E0053329A /* DFGBranchDirection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBranchDirection.h; path = dfg/DFGBranchDirection.h; sourceTree = "<group>"; };
    2188                 0F85A31E16AB76AE0077571E /* DFGVariadicFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGVariadicFunction.h; path = dfg/DFGVariadicFunction.h; sourceTree = "<group>"; };
    21892146                0F885E101849A3BE00F1E3FA /* BytecodeUseDef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeUseDef.h; sourceTree = "<group>"; };
    21902147                0F8F2B93172E049E007DBDA5 /* FTLLink.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = FTLLink.cpp; path = ftl/FTLLink.cpp; sourceTree = "<group>"; };
     
    48504807                                0F2BDC421522801700CD8910 /* DFGVariableEventStream.cpp */,
    48514808                                0F2BDC431522801700CD8910 /* DFGVariableEventStream.h */,
    4852                                 0F85A31E16AB76AE0077571E /* DFGVariadicFunction.h */,
    48534809                                0FFFC95314EF909500C72532 /* DFGVirtualRegisterAllocationPhase.cpp */,
    48544810                                0FFFC95414EF909500C72532 /* DFGVirtualRegisterAllocationPhase.h */,
     
    52775233                                5540771B18DA58AD00EFF7F2 /* JSArgumentsIterator.h in Headers */,
    52785234                                5540772218DA58AD00EFF7F2 /* JSArrayIterator.h in Headers */,
    5279                                 5540772518DA58AD00EFF7F2 /* JSBoundFunction.h in Headers */,
     5235                                5540772518DA58AD00EFF7F2 /* (null) in Headers */,
    52805236                                5540774818DA58AD00EFF7F2 /* JSGlobalObjectDebuggable.h in Headers */,
    52815237                                5540774A18DA58AD00EFF7F2 /* JSGlobalObjectFunctions.h in Headers */,
     
    57515707                                0F2BDC491522809600CD8910 /* DFGVariableEvent.h in Headers */,
    57525708                                0F2BDC4B1522809D00CD8910 /* DFGVariableEventStream.h in Headers */,
    5753                                 0FFB921E16D02F470055A5DB /* DFGVariadicFunction.h in Headers */,
    57545709                                0FFFC96014EF90BD00C72532 /* DFGVirtualRegisterAllocationPhase.h in Headers */,
    57555710                                0FC97F4218202119002C9B26 /* DFGWatchpointCollectionPhase.h in Headers */,
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86.h

    r164764 r167325  
    158158   
    159159    // Possibly clobbers src.
     160    // FIXME: Don't do that.
     161    // https://bugs.webkit.org/show_bug.cgi?id=131690
    160162    void moveDoubleToInts(FPRegisterID src, RegisterID dest1, RegisterID dest2)
    161163    {
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r167094 r167325  
    3838#include "DFGDriver.h"
    3939#include "DFGJITCode.h"
    40 #include "DFGNode.h"
    4140#include "DFGWorklist.h"
    4241#include "Debugger.h"
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.h

    r166678 r167325  
    4646#include "DFGCommonData.h"
    4747#include "DFGExitProfile.h"
    48 #include "DFGMinifiedGraph.h"
    49 #include "DFGOSREntry.h"
    50 #include "DFGOSRExit.h"
    51 #include "DFGVariableEventStream.h"
    5248#include "DeferredCompilationCallback.h"
    5349#include "EvalCodeCache.h"
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h

    r164424 r167325  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    158158    BooleanResult booleanResult(Node*, AbstractValue&);
    159159   
     160    void setBuiltInConstant(Node* node, JSValue value)
     161    {
     162        AbstractValue& abstractValue = forNode(node);
     163        abstractValue.set(m_graph, value);
     164        abstractValue.fixTypeForRepresentation(node);
     165    }
     166   
    160167    void setConstant(Node* node, JSValue value)
    161168    {
    162         forNode(node).set(m_graph, value);
     169        setBuiltInConstant(node, value);
    163170        m_state.setFoundConstants(true);
    164171    }
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

    r167189 r167325  
    127127    switch (node->op()) {
    128128    case JSConstant:
     129    case DoubleConstant:
     130    case Int52Constant:
    129131    case WeakJSConstant:
    130132    case PhantomArguments: {
    131         forNode(node).set(m_graph, m_graph.valueOfJSConstant(node));
     133        setBuiltInConstant(node, m_graph.valueOfJSConstant(node));
    132134        break;
    133135    }
     
    308310    }
    309311       
    310     case Int32ToDouble: {
     312    case DoubleRep: {
    311313        JSValue child = forNode(node->child1()).value();
    312314        if (child && child.isNumber()) {
    313             setConstant(node, JSValue(JSValue::EncodeAsDouble, child.asNumber()));
    314             break;
    315         }
    316         if (isInt32Speculation(forNode(node->child1()).m_type))
    317             forNode(node).setType(SpecDoubleReal);
    318         else
    319             forNode(node).setType(SpecDouble);
    320         break;
    321     }
    322        
    323     case Int52ToDouble: {
     315            setConstant(node, jsDoubleNumber(child.asNumber()));
     316            break;
     317        }
     318        forNode(node).setType(forNode(node->child1()).m_type);
     319        forNode(node).fixTypeForRepresentation(node);
     320        break;
     321    }
     322       
     323    case Int52Rep: {
     324        RELEASE_ASSERT(node->child1().useKind() == Int32Use);
     325       
    324326        JSValue child = forNode(node->child1()).value();
    325         if (child && child.isNumber()) {
     327        if (child && child.isInt32()) {
    326328            setConstant(node, child);
    327329            break;
    328330        }
    329         forNode(node).setType(SpecDouble);
    330         break;
    331     }
    332        
    333     case Int52ToValue: {
    334         JSValue child = forNode(node->child1()).value();
    335         if (child && child.isNumber()) {
    336             setConstant(node, child);
    337             break;
    338         }
    339         SpeculatedType type = forNode(node->child1()).m_type;
    340         if (type & SpecInt52)
    341             type = (type | SpecInt32 | SpecInt52AsDouble) & ~SpecInt52;
    342         forNode(node).setType(type);
     331       
     332        forNode(node).setType(SpecInt32);
     333        break;
     334    }
     335       
     336    case ValueRep: {
     337        JSValue value = forNode(node->child1()).value();
     338        if (value) {
     339            setConstant(node, value);
     340            break;
     341        }
     342       
     343        forNode(node).setType(forNode(node->child1()).m_type);
     344        forNode(node).fixTypeForRepresentation(node);
    343345        break;
    344346    }
     
    371373                node->setCanExit(true);
    372374            break;
    373         case MachineIntUse:
     375        case Int52RepUse:
    374376            if (left && right && left.isMachineInt() && right.isMachineInt()) {
    375377                JSValue result = jsNumber(left.asMachineInt() + right.asMachineInt());
     
    384386                node->setCanExit(true);
    385387            break;
    386         case NumberUse:
     388        case DoubleRepUse:
    387389            if (left && right && left.isNumber() && right.isNumber()) {
    388                 setConstant(node, jsNumber(left.asNumber() + right.asNumber()));
     390                setConstant(node, jsDoubleNumber(left.asNumber() + right.asNumber()));
    389391                break;
    390392            }
     
    427429                node->setCanExit(true);
    428430            break;
    429         case MachineIntUse:
     431        case Int52RepUse:
    430432            if (left && right && left.isMachineInt() && right.isMachineInt()) {
    431433                JSValue result = jsNumber(left.asMachineInt() - right.asMachineInt());
     
    440442                node->setCanExit(true);
    441443            break;
    442         case NumberUse:
     444        case DoubleRepUse:
    443445            if (left && right && left.isNumber() && right.isNumber()) {
    444                 setConstant(node, jsNumber(left.asNumber() - right.asNumber()));
     446                setConstant(node, jsDoubleNumber(left.asNumber() - right.asNumber()));
    445447                break;
    446448            }
     
    478480                node->setCanExit(true);
    479481            break;
    480         case MachineIntUse:
     482        case Int52RepUse:
    481483            if (child && child.isMachineInt()) {
    482484                double doubleResult;
     
    497499                node->setCanExit(true);
    498500            break;
    499         case NumberUse:
     501        case DoubleRepUse:
    500502            if (child && child.isNumber()) {
    501                 setConstant(node, jsNumber(-child.asNumber()));
     503                setConstant(node, jsDoubleNumber(-child.asNumber()));
    502504                break;
    503505            }
     
    534536                node->setCanExit(true);
    535537            break;
    536         case MachineIntUse:
     538        case Int52RepUse:
    537539            if (left && right && left.isMachineInt() && right.isMachineInt()) {
    538540                double doubleResult = left.asNumber() * right.asNumber();
     
    548550            node->setCanExit(true);
    549551            break;
    550         case NumberUse:
     552        case DoubleRepUse:
    551553            if (left && right && left.isNumber() && right.isNumber()) {
    552                 setConstant(node, jsNumber(left.asNumber() * right.asNumber()));
     554                setConstant(node, jsDoubleNumber(left.asNumber() * right.asNumber()));
    553555                break;
    554556            }
     
    586588            node->setCanExit(true);
    587589            break;
    588         case NumberUse:
     590        case DoubleRepUse:
    589591            if (left && right && left.isNumber() && right.isNumber()) {
    590                 setConstant(node, jsNumber(left.asNumber() / right.asNumber()));
     592                setConstant(node, jsDoubleNumber(left.asNumber() / right.asNumber()));
    591593                break;
    592594            }
     
    620622            node->setCanExit(true);
    621623            break;
    622         case NumberUse:
     624        case DoubleRepUse:
    623625            if (left && right && left.isNumber() && right.isNumber()) {
    624                 setConstant(node, jsNumber(fmod(left.asNumber(), right.asNumber())));
     626                setConstant(node, jsDoubleNumber(fmod(left.asNumber(), right.asNumber())));
    625627                break;
    626628            }
     
    646648            node->setCanExit(true);
    647649            break;
    648         case NumberUse:
     650        case DoubleRepUse:
    649651            if (left && right && left.isNumber() && right.isNumber()) {
    650652                double a = left.asNumber();
    651653                double b = right.asNumber();
    652                 setConstant(node, jsNumber(a < b ? a : (b <= a ? b : a + b)));
     654                setConstant(node, jsDoubleNumber(a < b ? a : (b <= a ? b : a + b)));
    653655                break;
    654656            }
     
    674676            node->setCanExit(true);
    675677            break;
    676         case NumberUse:
     678        case DoubleRepUse:
    677679            if (left && right && left.isNumber() && right.isNumber()) {
    678680                double a = left.asNumber();
    679681                double b = right.asNumber();
    680                 setConstant(node, jsNumber(a > b ? a : (b >= a ? b : a + b)));
     682                setConstant(node, jsDoubleNumber(a > b ? a : (b >= a ? b : a + b)));
    681683                break;
    682684            }
     
    704706            node->setCanExit(true);
    705707            break;
    706         case NumberUse:
     708        case DoubleRepUse:
    707709            if (child && child.isNumber()) {
    708                 setConstant(node, jsNumber(child.asNumber()));
     710                setConstant(node, jsDoubleNumber(child.asNumber()));
    709711                break;
    710712            }
     
    721723        JSValue child = forNode(node->child1()).value();
    722724        if (child && child.isNumber()) {
    723             setConstant(node, jsNumber(sqrt(child.asNumber())));
     725            setConstant(node, jsDoubleNumber(sqrt(child.asNumber())));
    724726            break;
    725727        }
     
    731733        JSValue child = forNode(node->child1()).value();
    732734        if (child && child.isNumber()) {
    733             setConstant(node, jsNumber(static_cast<float>(child.asNumber())));
     735            setConstant(node, jsDoubleNumber(static_cast<float>(child.asNumber())));
    734736            break;
    735737        }
     
    741743        JSValue child = forNode(node->child1()).value();
    742744        if (child && child.isNumber()) {
    743             setConstant(node, jsNumber(sin(child.asNumber())));
     745            setConstant(node, jsDoubleNumber(sin(child.asNumber())));
    744746            break;
    745747        }
     
    751753        JSValue child = forNode(node->child1()).value();
    752754        if (child && child.isNumber()) {
    753             setConstant(node, jsNumber(cos(child.asNumber())));
     755            setConstant(node, jsDoubleNumber(cos(child.asNumber())));
    754756            break;
    755757        }
     
    770772            case BooleanUse:
    771773            case Int32Use:
    772             case NumberUse:
     774            case DoubleRepUse:
    773775            case UntypedUse:
    774776            case StringUse:
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp

    r164229 r167325  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    6868   
    6969    m_type = speculationFromValue(value);
    70     if (m_type == SpecInt52AsDouble)
    71         m_type = SpecInt52;
    7270    m_value = value;
    7371   
     
    8482   
    8583    checkConsistency();
     84}
     85
     86void AbstractValue::fixTypeForRepresentation(NodeFlags representation)
     87{
     88    if (representation == NodeResultDouble) {
     89        if (m_value) {
     90            ASSERT(m_value.isNumber());
     91            if (m_value.isInt32())
     92                m_value = jsDoubleNumber(m_value.asNumber());
     93        }
     94        if (m_type & SpecMachineInt) {
     95            m_type &= ~SpecMachineInt;
     96            m_type |= SpecInt52AsDouble;
     97        }
     98        RELEASE_ASSERT(!(m_type & ~SpecDouble));
     99    } else if (representation == NodeResultInt52) {
     100        if (m_type & SpecInt52AsDouble) {
     101            m_type &= ~SpecInt52AsDouble;
     102            m_type |= SpecInt52;
     103        }
     104        RELEASE_ASSERT(!(m_type & ~SpecMachineInt));
     105    } else {
     106        if (m_type & SpecInt52) {
     107            m_type &= ~SpecInt52;
     108            m_type |= SpecInt52AsDouble;
     109        }
     110        RELEASE_ASSERT(!(m_type & ~SpecBytecodeTop));
     111    }
     112   
     113    checkConsistency();
     114}
     115
     116void AbstractValue::fixTypeForRepresentation(Node* node)
     117{
     118    fixTypeForRepresentation(node->result());
    86119}
    87120
     
    245278    if (!!m_value) {
    246279        SpeculatedType type = m_type;
     280        // This relaxes the assertion below a bit, since we don't know the representation of the
     281        // node.
    247282        if (type & SpecInt52)
    248283            type |= SpecInt52AsDouble;
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.h

    r164424 r167325  
    11/*
    2  * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3131#include "ArrayProfile.h"
    3232#include "DFGFiltrationResult.h"
     33#include "DFGNodeFlags.h"
    3334#include "DFGStructureAbstractValue.h"
    3435#include "JSCell.h"
     
    4041
    4142class Graph;
     43struct Node;
    4244
    4345struct AbstractValue {
     
    129131        checkConsistency();
    130132    }
     133   
     134    void fixTypeForRepresentation(NodeFlags representation);
     135    void fixTypeForRepresentation(Node*);
    131136   
    132137    bool operator==(const AbstractValue& other) const
  • trunk/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp

    r164229 r167325  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    211211        }
    212212           
    213         case Identity:
    214213        case UInt32ToNumber: {
    215214            node->child1()->mergeFlags(flags);
     
    379378            break;
    380379        }
     380
     381        case Identity:
     382            // This would be trivial to handle but we just assert that we cannot see these yet.
     383            RELEASE_ASSERT_NOT_REACHED();
     384            break;
    381385           
    382386        // Note: ArithSqrt, ArithSin, and ArithCos and other math intrinsics don't have special
  • trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.h

    r165869 r167325  
    3434#include "DFGFlushedAt.h"
    3535#include "DFGNode.h"
    36 #include "DFGVariadicFunction.h"
    3736#include "Operands.h"
    3837#include <wtf/HashMap.h>
     
    9998    void replacePredecessor(BasicBlock* from, BasicBlock* to);
    10099
    101 #define DFG_DEFINE_APPEND_NODE(templatePre, templatePost, typeParams, valueParamsComma, valueParams, valueArgs) \
    102     templatePre typeParams templatePost Node* appendNode(Graph&, SpeculatedType valueParamsComma valueParams);
    103     DFG_VARIADIC_TEMPLATE_FUNCTION(DFG_DEFINE_APPEND_NODE)
    104 #undef DFG_DEFINE_APPEND_NODE
     100    template<typename... Params>
     101    Node* appendNode(Graph&, SpeculatedType, Params...);
    105102   
    106 #define DFG_DEFINE_APPEND_NODE(templatePre, templatePost, typeParams, valueParamsComma, valueParams, valueArgs) \
    107     templatePre typeParams templatePost Node* appendNonTerminal(Graph&, SpeculatedType valueParamsComma valueParams);
    108     DFG_VARIADIC_TEMPLATE_FUNCTION(DFG_DEFINE_APPEND_NODE)
    109 #undef DFG_DEFINE_APPEND_NODE
     103    template<typename... Params>
     104    Node* appendNonTerminal(Graph&, SpeculatedType, Params...);
    110105   
    111106    void dump(PrintStream& out) const;
  • trunk/Source/JavaScriptCore/dfg/DFGBasicBlockInlines.h

    r163802 r167325  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3434namespace JSC { namespace DFG {
    3535
    36 #define DFG_DEFINE_APPEND_NODE(templatePre, templatePost, typeParams, valueParamsComma, valueParams, valueArgs) \
    37     templatePre typeParams templatePost inline Node* BasicBlock::appendNode(Graph& graph, SpeculatedType type valueParamsComma valueParams) \
    38     { \
    39         Node* result = graph.addNode(type valueParamsComma valueArgs); \
    40         append(result); \
    41         return result; \
    42     }
    43     DFG_VARIADIC_TEMPLATE_FUNCTION(DFG_DEFINE_APPEND_NODE)
    44 #undef DFG_DEFINE_APPEND_NODE
     36template<typename... Params>
     37Node* BasicBlock::appendNode(Graph& graph, SpeculatedType type, Params... params)
     38{
     39    Node* result = graph.addNode(type, params...);
     40    append(result);
     41    return result;
     42}
    4543
    46 #define DFG_DEFINE_APPEND_NODE(templatePre, templatePost, typeParams, valueParamsComma, valueParams, valueArgs) \
    47     templatePre typeParams templatePost inline Node* BasicBlock::appendNonTerminal(Graph& graph, SpeculatedType type valueParamsComma valueParams) \
    48     { \
    49         Node* result = graph.addNode(type valueParamsComma valueArgs); \
    50         insertBeforeLast(result); \
    51         return result; \
    52     }
    53     DFG_VARIADIC_TEMPLATE_FUNCTION(DFG_DEFINE_APPEND_NODE)
    54 #undef DFG_DEFINE_APPEND_NODE
     44template<typename... Params>
     45Node* BasicBlock::appendNonTerminal(Graph& graph, SpeculatedType type, Params... params)
     46{
     47    Node* result = graph.addNode(type, params...);
     48    insertBeforeLast(result);
     49    return result;
     50}
    5551
    5652} } // namespace JSC::DFG
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r167189 r167325  
    32643264
    32653265        case op_to_number: {
    3266             set(VirtualRegister(currentInstruction[1].u.operand),
    3267                 addToGraph(Identity, Edge(get(VirtualRegister(currentInstruction[2].u.operand)), NumberUse)));
     3266            Node* node = get(VirtualRegister(currentInstruction[2].u.operand));
     3267            addToGraph(Phantom, Edge(node, NumberUse));
     3268            set(VirtualRegister(currentInstruction[1].u.operand), node);
    32683269            NEXT_OPCODE(op_to_number);
    32693270        }
  • trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp

    r167189 r167325  
    11/*
    2  * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    162162    }
    163163   
    164     Node* int32ToDoubleCSE(Node* node)
    165     {
    166         for (unsigned i = m_indexInBlock; i--;) {
    167             Node* otherNode = m_currentBlock->at(i);
    168             if (otherNode == node->child1())
    169                 return 0;
    170             switch (otherNode->op()) {
    171             case Int32ToDouble:
    172                 if (otherNode->child1().sanitized() == node->child1().sanitized())
    173                     return otherNode;
    174                 break;
    175             default:
    176                 break;
    177             }
    178         }
    179         return 0;
    180     }
    181    
    182164    Node* constantCSE(Node* node)
    183165    {
    184166        for (unsigned i = endIndexForPureCSE(); i--;) {
    185167            Node* otherNode = m_currentBlock->at(i);
    186             if (otherNode->op() != JSConstant)
     168            if (otherNode->op() != node->op())
    187169                continue;
    188170           
     
    11491131        case ValueToInt32:
    11501132        case MakeRope:
    1151         case Int52ToDouble:
    1152         case Int52ToValue:
     1133        case DoubleRep:
     1134        case ValueRep:
     1135        case Int52Rep:
    11531136            if (cseMode == StoreElimination)
    11541137                break;
     
    11771160            break;
    11781161        }
    1179            
    1180         case Int32ToDouble:
    1181             if (cseMode == StoreElimination)
    1182                 break;
    1183             setReplacement(int32ToDoubleCSE(node));
    1184             break;
    11851162           
    11861163        case GetCallee:
     
    12621239            Node* dataNode = replacement->child1().node();
    12631240            ASSERT(dataNode->hasResult());
    1264             node->child1() = Edge(dataNode);
     1241            node->child1() = dataNode->defaultEdge();
    12651242            m_graph.dethread();
    12661243            m_changed = true;
     
    12691246           
    12701247        case JSConstant:
     1248        case DoubleConstant:
     1249        case Int52Constant:
    12711250            if (cseMode == StoreElimination)
    12721251                break;
  • trunk/Source/JavaScriptCore/dfg/DFGCapabilities.h

    r164734 r167325  
    11/*
    2  * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2929#include "CodeBlock.h"
    3030#include "DFGCommon.h"
    31 #include "DFGNode.h"
    3231#include "Executable.h"
    3332#include "Interpreter.h"
  • trunk/Source/JavaScriptCore/dfg/DFGClobberize.h

    r167189 r167325  
    8484    switch (node->op()) {
    8585    case JSConstant:
     86    case DoubleConstant:
     87    case Int52Constant:
    8688    case WeakJSConstant:
    8789    case Identity:
     
    124126    case IsString:
    125127    case LogicalNot:
    126     case Int32ToDouble:
    127128    case ExtractOSREntryLocal:
    128     case Int52ToDouble:
    129     case Int52ToValue:
    130129    case CheckInBounds:
    131130    case ConstantStoragePointer:
     
    133132    case DoubleAsInt32:
    134133    case Check:
     134    case DoubleRep:
     135    case ValueRep:
     136    case Int52Rep:
    135137        return;
    136138       
  • trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp

    r165407 r167325  
    300300            AbstractValue constantValue;
    301301            constantValue.set(m_graph, value);
     302            constantValue.fixTypeForRepresentation(node);
    302303            if (oldValue.merge(constantValue))
    303304                continue;
  • trunk/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp

    r165522 r167325  
    195195            switch (node->op()) {
    196196            case MovHint: {
    197                 ASSERT(node->child1().useKind() == UntypedUse);
     197                ASSERT(node->child1().useKind() == node->child1()->defaultUseKind());
    198198                if (!node->child1()->shouldGenerate()) {
    199199                    node->setOpAndDefaultFlags(ZombieHint);
     
    201201                    break;
    202202                }
    203                 node->setOpAndDefaultFlags(MovHint);
    204203                break;
    205204            }
  • trunk/Source/JavaScriptCore/dfg/DFGEdge.h

    r164424 r167325  
    11/*
    2  * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    123123    bool willNotHaveCheck() const
    124124    {
    125         return isProved() || useKind() == UntypedUse;
     125        return isProved() || shouldNotHaveTypeCheck(useKind());
    126126    }
    127127    bool willHaveCheck() const
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r167189 r167325  
    6262           
    6363            for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
    64                 fixupSetLocalsInBlock(m_graph.block(blockIndex));
     64                fixupGetAndSetLocalsInBlock(m_graph.block(blockIndex));
    6565        }
    6666       
     
    124124            else if (nodeCanSpeculateInt32(node->arithNodeFlags()))
    125125                node->setArithMode(Arith::CheckOverflow);
    126             else
     126            else {
    127127                node->setArithMode(Arith::DoOverflow);
     128                node->setResult(NodeResultDouble);
     129            }
    128130            break;
    129131        }
     
    136138            }
    137139            if (Node::shouldSpeculateNumberExpectingDefined(node->child1().node(), node->child2().node())) {
    138                 fixEdge<NumberUse>(node->child1());
    139                 fixEdge<NumberUse>(node->child2());
     140                fixEdge<DoubleRepUse>(node->child1());
     141                fixEdge<DoubleRepUse>(node->child2());
    140142                node->setOp(ArithAdd);
    141143                node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
     144                node->setResult(NodeResultDouble);
    142145                break;
    143146            }
     
    178181            if (attemptToMakeIntegerAdd(node))
    179182                break;
    180             fixEdge<NumberUse>(node->child1());
    181             fixEdge<NumberUse>(node->child2());
     183            fixEdge<DoubleRepUse>(node->child1());
     184            fixEdge<DoubleRepUse>(node->child2());
     185            node->setResult(NodeResultDouble);
    182186            break;
    183187        }
     
    195199            }
    196200            if (m_graph.negateShouldSpeculateMachineInt(node)) {
    197                 fixEdge<MachineIntUse>(node->child1());
     201                fixEdge<Int52RepUse>(node->child1());
    198202                if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
    199203                    node->setArithMode(Arith::CheckOverflow);
    200204                else
    201205                    node->setArithMode(Arith::CheckOverflowAndNegativeZero);
    202                 break;
    203             }
    204             fixEdge<NumberUse>(node->child1());
     206                node->setResult(NodeResultInt52);
     207                break;
     208            }
     209            fixEdge<DoubleRepUse>(node->child1());
     210            node->setResult(NodeResultDouble);
    205211            break;
    206212        }
     
    219225            }
    220226            if (m_graph.mulShouldSpeculateMachineInt(node)) {
    221                 fixEdge<MachineIntUse>(node->child1());
    222                 fixEdge<MachineIntUse>(node->child2());
     227                fixEdge<Int52RepUse>(node->child1());
     228                fixEdge<Int52RepUse>(node->child2());
    223229                if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
    224230                    node->setArithMode(Arith::CheckOverflow);
    225231                else
    226232                    node->setArithMode(Arith::CheckOverflowAndNegativeZero);
    227                 break;
    228             }
    229             fixEdge<NumberUse>(node->child1());
    230             fixEdge<NumberUse>(node->child2());
     233                node->setResult(NodeResultInt52);
     234                break;
     235            }
     236            fixEdge<DoubleRepUse>(node->child1());
     237            fixEdge<DoubleRepUse>(node->child2());
     238            node->setResult(NodeResultDouble);
    231239            break;
    232240        }
     
    247255                    break;
    248256                }
    249                 fixEdge<NumberUse>(node->child1());
    250                 fixEdge<NumberUse>(node->child2());
     257               
     258                // This will cause conversion nodes to be inserted later.
     259                fixEdge<DoubleRepUse>(node->child1());
     260                fixEdge<DoubleRepUse>(node->child2());
     261               
     262                // But we have to make sure that everything is phantom'd until after the
     263                // DoubleAsInt32 node, which occurs after the Div/Mod node that the conversions
     264                // will be insered on.
     265                addRequiredPhantom(node->child1().node());
     266                addRequiredPhantom(node->child2().node());
    251267
    252268                // We don't need to do ref'ing on the children because we're stealing them from
     
    254270                Node* newDivision = m_insertionSet.insertNode(
    255271                    m_indexInBlock, SpecDouble, *node);
     272                newDivision->setResult(NodeResultDouble);
    256273               
    257274                node->setOp(DoubleAsInt32);
    258                 node->children.initialize(Edge(newDivision, KnownNumberUse), Edge(), Edge());
     275                node->children.initialize(Edge(newDivision, DoubleRepUse), Edge(), Edge());
    259276                if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
    260277                    node->setArithMode(Arith::CheckOverflow);
     
    263280                break;
    264281            }
    265             fixEdge<NumberUse>(node->child1());
    266             fixEdge<NumberUse>(node->child2());
     282            fixEdge<DoubleRepUse>(node->child1());
     283            fixEdge<DoubleRepUse>(node->child2());
     284            node->setResult(NodeResultDouble);
    267285            break;
    268286        }
     
    276294                break;
    277295            }
    278             fixEdge<NumberUse>(node->child1());
    279             fixEdge<NumberUse>(node->child2());
     296            fixEdge<DoubleRepUse>(node->child1());
     297            fixEdge<DoubleRepUse>(node->child2());
     298            node->setResult(NodeResultDouble);
    280299            break;
    281300        }
     
    287306                break;
    288307            }
    289             fixEdge<NumberUse>(node->child1());
     308            fixEdge<DoubleRepUse>(node->child1());
     309            node->setResult(NodeResultDouble);
    290310            break;
    291311        }
     
    295315        case ArithSin:
    296316        case ArithCos: {
    297             fixEdge<NumberUse>(node->child1());
     317            fixEdge<DoubleRepUse>(node->child1());
     318            node->setResult(NodeResultDouble);
    298319            break;
    299320        }
     
    307328                fixEdge<Int32Use>(node->child1());
    308329            else if (node->child1()->shouldSpeculateNumber())
    309                 fixEdge<NumberUse>(node->child1());
     330                fixEdge<DoubleRepUse>(node->child1());
    310331            else if (node->child1()->shouldSpeculateString())
    311332                fixEdge<StringUse>(node->child1());
     
    338359            if (enableInt52()
    339360                && Node::shouldSpeculateMachineInt(node->child1().node(), node->child2().node())) {
    340                 fixEdge<MachineIntUse>(node->child1());
    341                 fixEdge<MachineIntUse>(node->child2());
     361                fixEdge<Int52RepUse>(node->child1());
     362                fixEdge<Int52RepUse>(node->child2());
    342363                node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
    343364                break;
    344365            }
    345366            if (Node::shouldSpeculateNumber(node->child1().node(), node->child2().node())) {
    346                 fixEdge<NumberUse>(node->child1());
    347                 fixEdge<NumberUse>(node->child2());
     367                fixEdge<DoubleRepUse>(node->child1());
     368                fixEdge<DoubleRepUse>(node->child2());
    348369                node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
    349370                break;
     
    403424            if (enableInt52()
    404425                && Node::shouldSpeculateMachineInt(node->child1().node(), node->child2().node())) {
    405                 fixEdge<MachineIntUse>(node->child1());
    406                 fixEdge<MachineIntUse>(node->child2());
     426                fixEdge<Int52RepUse>(node->child1());
     427                fixEdge<Int52RepUse>(node->child2());
    407428                break;
    408429            }
    409430            if (Node::shouldSpeculateNumber(node->child1().node(), node->child2().node())) {
    410                 fixEdge<NumberUse>(node->child1());
    411                 fixEdge<NumberUse>(node->child2());
     431                fixEdge<DoubleRepUse>(node->child1());
     432                fixEdge<DoubleRepUse>(node->child2());
    412433                break;
    413434            }
     
    502523            }
    503524           
    504             switch (node->arrayMode().type()) {
     525            arrayMode = node->arrayMode();
     526            switch (arrayMode.type()) {
    505527            case Array::SelectUsingPredictions:
    506528            case Array::Unprofiled:
     
    518540                fixEdge<KnownCellUse>(node->child1());
    519541                fixEdge<Int32Use>(node->child2());
     542                break;
     543            }
     544           
     545            switch (arrayMode.type()) {
     546            case Array::Double:
     547                if (!arrayMode.isOutOfBounds())
     548                    node->setResult(NodeResultDouble);
     549                break;
     550               
     551            case Array::Float32Array:
     552            case Array::Float64Array:
     553                node->setResult(NodeResultDouble);
     554                break;
     555               
     556            case Array::Uint32Array:
     557                if (node->shouldSpeculateInt32())
     558                    break;
     559                if (node->shouldSpeculateMachineInt() && enableInt52())
     560                    node->setResult(NodeResultInt52);
     561                else
     562                    node->setResult(NodeResultDouble);
     563                break;
     564               
     565            default:
    520566                break;
    521567            }
     
    560606                fixEdge<Int32Use>(child3);
    561607                if (child3->prediction() & SpecInt52)
    562                     fixEdge<MachineIntUse>(child3);
     608                    fixEdge<Int52RepUse>(child3);
    563609                else
    564610                    fixEdge<Int32Use>(child3);
     
    567613                fixEdge<KnownCellUse>(child1);
    568614                fixEdge<Int32Use>(child2);
    569                 fixEdge<RealNumberUse>(child3);
     615                fixEdge<DoubleRepRealUse>(child3);
    570616                break;
    571617            case Array::Int8Array:
     
    581627                    fixEdge<Int32Use>(child3);
    582628                else if (child3->shouldSpeculateMachineInt())
    583                     fixEdge<MachineIntUse>(child3);
     629                    fixEdge<Int52RepUse>(child3);
    584630                else
    585                     fixEdge<NumberUse>(child3);
     631                    fixEdge<DoubleRepUse>(child3);
    586632                break;
    587633            case Array::Float32Array:
     
    589635                fixEdge<KnownCellUse>(child1);
    590636                fixEdge<Int32Use>(child2);
    591                 fixEdge<NumberUse>(child3);
     637                fixEdge<DoubleRepUse>(child3);
    592638                break;
    593639            case Array::Contiguous:
     
    631677                break;
    632678            case Array::Double:
    633                 fixEdge<RealNumberUse>(node->child2());
     679                fixEdge<DoubleRepRealUse>(node->child2());
    634680                break;
    635681            case Array::Contiguous:
     
    664710                fixEdge<Int32Use>(node->child1());
    665711            else if (node->child1()->shouldSpeculateNumber())
    666                 fixEdge<NumberUse>(node->child1());
     712                fixEdge<DoubleRepUse>(node->child1());
    667713
    668714            Node* logicalNot = node->child1().node();
     
    761807            case ALL_DOUBLE_INDEXING_TYPES:
    762808                for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
    763                     fixEdge<RealNumberUse>(m_graph.m_varArgChildren[node->firstChild() + operandIndex]);
     809                    fixEdge<DoubleRepRealUse>(m_graph.m_varArgChildren[node->firstChild() + operandIndex]);
    764810                break;
    765811            case ALL_CONTIGUOUS_INDEXING_TYPES:
     
    937983
    938984        case Phantom:
    939         case Identity:
    940985        case Check: {
    941986            switch (node->child1().useKind()) {
     
    9621007        case CheckTierUpAtReturn:
    9631008        case CheckTierUpAndOSREnter:
    964         case Int52ToDouble:
    965         case Int52ToValue:
    9661009        case InvalidationPoint:
    9671010        case CheckArray:
     
    9691012        case ConstantStoragePointer:
    9701013        case DoubleAsInt32:
    971         case Int32ToDouble:
    9721014        case ValueToInt32:
    9731015        case HardPhantom: // HardPhantom would be trivial to handle but anyway we assert that we won't see it here yet.
     1016        case DoubleRep:
     1017        case Int52Rep:
     1018        case ValueRep:
     1019        case DoubleConstant:
     1020        case Int52Constant:
     1021        case Identity: // This should have been cleaned up.
    9741022            // These are just nodes that we don't currently expect to see during fixup.
    9751023            // If we ever wanted to insert them prior to fixup, then we just have to create
     
    13131361    }
    13141362   
    1315     void fixupSetLocalsInBlock(BasicBlock* block)
     1363    void fixupGetAndSetLocalsInBlock(BasicBlock* block)
    13161364    {
    13171365        if (!block)
     
    13211369        for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
    13221370            Node* node = m_currentNode = block->at(m_indexInBlock);
    1323             if (node->op() != SetLocal)
     1371            if (node->op() != SetLocal && node->op() != GetLocal)
    13241372                continue;
    13251373           
    13261374            VariableAccessData* variable = node->variableAccessData();
    1327             switch (variable->flushFormat()) {
    1328             case FlushedJSValue:
    1329                 break;
    1330             case FlushedDouble:
    1331                 fixEdge<NumberUse>(node->child1());
    1332                 break;
    1333             case FlushedInt32:
    1334                 fixEdge<Int32Use>(node->child1());
    1335                 break;
    1336             case FlushedInt52:
    1337                 fixEdge<MachineIntUse>(node->child1());
    1338                 break;
    1339             case FlushedCell:
    1340                 fixEdge<CellUse>(node->child1());
    1341                 break;
    1342             case FlushedBoolean:
    1343                 fixEdge<BooleanUse>(node->child1());
    1344                 break;
     1375            switch (node->op()) {
     1376            case GetLocal:
     1377                switch (variable->flushFormat()) {
     1378                case FlushedDouble:
     1379                    node->setResult(NodeResultDouble);
     1380                    break;
     1381                case FlushedInt52:
     1382                    node->setResult(NodeResultInt52);
     1383                    break;
     1384                default:
     1385                    break;
     1386                }
     1387                break;
     1388               
     1389            case SetLocal:
     1390                switch (variable->flushFormat()) {
     1391                case FlushedJSValue:
     1392                    break;
     1393                case FlushedDouble:
     1394                    fixEdge<DoubleRepUse>(node->child1());
     1395                    break;
     1396                case FlushedInt32:
     1397                    fixEdge<Int32Use>(node->child1());
     1398                    break;
     1399                case FlushedInt52:
     1400                    fixEdge<Int52RepUse>(node->child1());
     1401                    break;
     1402                case FlushedCell:
     1403                    fixEdge<CellUse>(node->child1());
     1404                    break;
     1405                case FlushedBoolean:
     1406                    fixEdge<BooleanUse>(node->child1());
     1407                    break;
     1408                default:
     1409                    RELEASE_ASSERT_NOT_REACHED();
     1410                    break;
     1411                }
     1412                break;
     1413               
    13451414            default:
    13461415                RELEASE_ASSERT_NOT_REACHED();
     
    14681537            break;
    14691538        case NumberUse:
    1470         case RealNumberUse:
     1539        case DoubleRepUse:
     1540        case DoubleRepRealUse:
    14711541            if (variable->doubleFormatState() == UsingDoubleFormat)
    14721542                m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
     
    14771547                m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
    14781548            break;
    1479         case MachineIntUse:
     1549        case Int52RepUse:
    14801550            if (isMachineIntSpeculation(variable->prediction()))
    14811551                m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
     
    15201590        UseKind useKind;
    15211591        if (node->shouldSpeculateMachineInt())
    1522             useKind = MachineIntUse;
     1592            useKind = Int52RepUse;
    15231593        else if (node->shouldSpeculateNumber())
    1524             useKind = NumberUse;
     1594            useKind = DoubleRepUse;
    15251595        else if (node->shouldSpeculateBoolean())
    15261596            useKind = BooleanUse;
     
    15901660       
    15911661        if (m_graph.addShouldSpeculateMachineInt(node)) {
    1592             fixEdge<MachineIntUse>(node->child1());
    1593             fixEdge<MachineIntUse>(node->child2());
     1662            fixEdge<Int52RepUse>(node->child1());
     1663            fixEdge<Int52RepUse>(node->child2());
    15941664            node->setArithMode(Arith::CheckOverflow);
     1665            node->setResult(NodeResultInt52);
    15951666            return true;
    15961667        }
     
    17251796            m_currentNode = block->at(m_indexInBlock);
    17261797            addPhantomsIfNecessary();
    1727             if (m_currentNode->containsMovHint())
    1728                 continue;
     1798            tryToRelaxRepresentation(m_currentNode);
    17291799            DFG_NODE_DO_TO_CHILDREN(m_graph, m_currentNode, injectTypeConversionsForEdge);
    17301800        }
     
    17331803    }
    17341804   
     1805    void tryToRelaxRepresentation(Node* node)
     1806    {
     1807        // Some operations may be able to operate more efficiently over looser representations.
     1808        // Identify those here. This avoids inserting a redundant representation conversion.
     1809        // Also, for some operations, like MovHint, this is a necessary optimization: inserting
     1810        // an otherwise-dead conversion just for a MovHint would break OSR's understanding of
     1811        // the IR.
     1812       
     1813        switch (node->op()) {
     1814        case MovHint:
     1815        case Phantom:
     1816        case Check:
     1817        case HardPhantom:
     1818            DFG_NODE_DO_TO_CHILDREN(m_graph, m_currentNode, fixEdgeRepresentation);
     1819            break;
     1820           
     1821        case ValueToInt32:
     1822            if (node->child1().useKind() == DoubleRepUse
     1823                && !node->child1()->hasDoubleResult()) {
     1824                node->child1().setUseKind(NumberUse);
     1825                break;
     1826            }
     1827            break;
     1828           
     1829        default:
     1830            break;
     1831        }
     1832    }
     1833   
     1834    void fixEdgeRepresentation(Node*, Edge& edge)
     1835    {
     1836        switch (edge.useKind()) {
     1837        case DoubleRepUse:
     1838        case DoubleRepRealUse:
     1839            if (edge->hasDoubleResult())
     1840                break;
     1841           
     1842            if (edge->hasInt52Result())
     1843                edge.setUseKind(Int52RepUse);
     1844            else if (edge.useKind() == DoubleRepUse)
     1845                edge.setUseKind(NumberUse);
     1846            break;
     1847           
     1848        case Int52RepUse:
     1849            // Nothing we can really do.
     1850            break;
     1851           
     1852        case UntypedUse:
     1853        case NumberUse:
     1854            if (edge->hasDoubleResult())
     1855                edge.setUseKind(DoubleRepUse);
     1856            else if (edge->hasInt52Result())
     1857                edge.setUseKind(Int52RepUse);
     1858            break;
     1859           
     1860        default:
     1861            break;
     1862        }
     1863    }
     1864   
    17351865    void injectTypeConversionsForEdge(Node* node, Edge& edge)
    17361866    {
    17371867        ASSERT(node == m_currentNode);
    17381868       
    1739         if (isDouble(edge.useKind())) {
    1740             if (edge->shouldSpeculateInt32ForArithmetic()) {
    1741                 addRequiredPhantom(edge.node());
    1742                
    1743                 Node* result = m_insertionSet.insertNode(
    1744                     m_indexInBlock, SpecInt52AsDouble, Int32ToDouble,
    1745                     node->origin, Edge(edge.node(), NumberUse));
    1746                
    1747                 edge.setNode(result);
    1748                 return;
    1749             }
    1750            
    1751             if (enableInt52() && edge->shouldSpeculateMachineInt()) {
    1752                 // Make all double uses of int52 values have an intermediate Int52ToDouble.
    1753                 // This is for the same reason as Int52ToValue (see below) except that
    1754                 // Int8ToDouble will convert int52's that fit in an int32 into a double
    1755                 // rather than trying to create a boxed int32 like Int52ToValue does.
    1756                
    1757                 addRequiredPhantom(edge.node());
    1758                 Node* result = m_insertionSet.insertNode(
    1759                     m_indexInBlock, SpecInt52AsDouble, Int52ToDouble,
    1760                     node->origin, Edge(edge.node(), NumberUse));
    1761                 edge.setNode(result);
    1762                 return;
    1763             }
    1764         }
    1765        
    1766         if (enableInt52() && edge.useKind() != MachineIntUse
    1767             && edge->shouldSpeculateMachineInt() && !edge->shouldSpeculateInt32()) {
    1768             // We make all non-int52 uses of int52 values have an intermediate Int52ToValue
    1769             // node to ensure that we handle this properly:
    1770             //
    1771             // a: SomeInt52
    1772             // b: ArithAdd(@a, ...)
    1773             // c: Call(..., @a)
    1774             // d: ArithAdd(@a, ...)
    1775             //
    1776             // Without an intermediate node and just labeling the uses, we will get:
    1777             //
    1778             // a: SomeInt52
    1779             // b: ArithAdd(Int52:@a, ...)
    1780             // c: Call(..., Untyped:@a)
    1781             // d: ArithAdd(Int52:@a, ...)
    1782             //
    1783             // And now the c->Untyped:@a edge will box the value of @a into a double. This
    1784             // is bad, because now the d->Int52:@a edge will either have to do double-to-int
    1785             // conversions, or will have to OSR exit unconditionally. Alternatively we could
    1786             // have the c->Untyped:@a edge box the value by copying rather than in-place.
    1787             // But these boxings are also costly so this wouldn't be great.
    1788             //
    1789             // The solution we use is to always have non-Int52 uses of predicted Int52's use
    1790             // an intervening Int52ToValue node:
    1791             //
    1792             // a: SomeInt52
    1793             // b: ArithAdd(Int52:@a, ...)
    1794             // x: Int52ToValue(Int52:@a)
    1795             // c: Call(..., Untyped:@x)
    1796             // d: ArithAdd(Int52:@a, ...)
    1797             //
    1798             // Note that even if we had multiple non-int52 uses of @a, the multiple
    1799             // Int52ToValue's would get CSE'd together. So the boxing would only happen once.
    1800             // At the same time, @a would continue to be represented as a native int52.
    1801             //
    1802             // An alternative would have been to insert ToNativeInt52 nodes on int52 uses of
    1803             // int52's. This would have handled the above example but would fall over for:
    1804             //
    1805             // a: SomeInt52
    1806             // b: Call(..., @a)
    1807             // c: ArithAdd(@a, ...)
    1808             //
    1809             // But the solution we use handles the above gracefully.
     1869        switch (edge.useKind()) {
     1870        case DoubleRepUse:
     1871        case DoubleRepRealUse: {
     1872            if (edge->hasDoubleResult())
     1873                break;
    18101874           
    18111875            addRequiredPhantom(edge.node());
    1812             Node* result = m_insertionSet.insertNode(
    1813                 m_indexInBlock, SpecInt52, Int52ToValue,
    1814                 node->origin, Edge(edge.node(), UntypedUse));
     1876
     1877            Node* result;
     1878            if (edge->hasInt52Result()) {
     1879                result = m_insertionSet.insertNode(
     1880                    m_indexInBlock, SpecInt52AsDouble, DoubleRep, node->origin,
     1881                    Edge(edge.node(), Int52RepUse));
     1882            } else {
     1883                result = m_insertionSet.insertNode(
     1884                    m_indexInBlock, SpecDouble, DoubleRep, node->origin,
     1885                    Edge(edge.node(), NumberUse));
     1886            }
     1887
    18151888            edge.setNode(result);
    1816             return;
    1817         }
     1889            break;
     1890        }
     1891           
     1892        case Int52RepUse: {
     1893            if (edge->hasInt52Result())
     1894                break;
     1895           
     1896            addRequiredPhantom(edge.node());
     1897
     1898            Node* result;
     1899            if (edge->hasDoubleResult()) {
     1900                // This will never happen.
     1901                RELEASE_ASSERT_NOT_REACHED();
     1902            } else if (edge->shouldSpeculateInt32ForArithmetic()) {
     1903                result = m_insertionSet.insertNode(
     1904                    m_indexInBlock, SpecInt32, Int52Rep, node->origin,
     1905                    Edge(edge.node(), Int32Use));
     1906            } else {
     1907                // This is only here for dealing with constants.
     1908                RELEASE_ASSERT(edge->op() == JSConstant);
     1909                result = m_insertionSet.insertNode(
     1910                    m_indexInBlock, SpecMachineInt, Int52Constant, node->origin,
     1911                    OpInfo(edge->constantNumber()));
     1912            }
     1913
     1914            edge.setNode(result);
     1915            break;
     1916        }
     1917           
     1918        default: {
     1919            if (!edge->hasDoubleResult() && !edge->hasInt52Result())
     1920                break;
     1921           
     1922            addRequiredPhantom(edge.node());
     1923           
     1924            Node* result;
     1925            if (edge->hasDoubleResult()) {
     1926                result = m_insertionSet.insertNode(
     1927                    m_indexInBlock, SpecDouble, ValueRep, node->origin,
     1928                    Edge(edge.node(), DoubleRepUse));
     1929            } else {
     1930                result = m_insertionSet.insertNode(
     1931                    m_indexInBlock, SpecInt32 | SpecInt52AsDouble, ValueRep, node->origin,
     1932                    Edge(edge.node(), Int52RepUse));
     1933            }
     1934           
     1935            edge.setNode(result);
     1936            break;
     1937        } }
    18181938    }
    18191939   
    18201940    void addRequiredPhantom(Node* node)
    18211941    {
    1822         if (!m_codeOriginOfPhantoms) {
    1823             ASSERT(m_requiredPhantoms.isEmpty());
    1824             m_codeOriginOfPhantoms = m_currentNode->origin.forExit;
    1825         } else {
    1826             ASSERT(!m_requiredPhantoms.isEmpty());
    1827             ASSERT(m_codeOriginOfPhantoms == m_currentNode->origin.forExit);
    1828         }
    1829        
    18301942        m_requiredPhantoms.append(node);
    18311943    }
     
    18361948            return;
    18371949       
    1838         RELEASE_ASSERT(!!m_codeOriginOfPhantoms);
    1839        
    1840         if (m_currentNode->origin.forExit == m_codeOriginOfPhantoms)
    1841             return;
    1842        
    18431950        for (unsigned i = m_requiredPhantoms.size(); i--;) {
     1951            Node* node = m_requiredPhantoms[i];
    18441952            m_insertionSet.insertNode(
    1845                 m_indexInBlock, SpecNone, Phantom, NodeOrigin(m_codeOriginOfPhantoms),
    1846                 Edge(m_requiredPhantoms[i], UntypedUse));
     1953                m_indexInBlock, SpecNone, Phantom, m_currentNode->origin,
     1954                node->defaultEdge());
    18471955        }
    18481956       
    18491957        m_requiredPhantoms.resize(0);
    1850         m_codeOriginOfPhantoms = CodeOrigin();
    18511958    }
    18521959   
     
    18641971       
    18651972        m_requiredPhantoms.resize(0);
    1866         m_codeOriginOfPhantoms = CodeOrigin();
    18671973    }
    18681974   
     
    18721978    InsertionSet m_insertionSet;
    18731979    bool m_profitabilityChanged;
    1874     CodeOrigin m_codeOriginOfPhantoms;
    18751980    Vector<Node*, 3> m_requiredPhantoms;
    18761981};
  • trunk/Source/JavaScriptCore/dfg/DFGFlushFormat.h

    r164424 r167325  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    6363        return NodeResultInt52;
    6464    case FlushedDouble:
    65         return NodeResultNumber;
     65        return NodeResultDouble;
    6666    case FlushedBoolean:
    6767        return NodeResultBoolean;
     
    8484        return Int32Use;
    8585    case FlushedInt52:
    86         return MachineIntUse;
     86        return Int52RepUse;
    8787    case FlushedDouble:
    88         return NumberUse;
     88        return DoubleRepUse;
    8989    case FlushedBoolean:
    9090        return BooleanUse;
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp

    r165995 r167325  
    315315    if (node->hasStoragePointer())
    316316        out.print(comma, RawPointer(node->storagePointer()));
    317     if (op == JSConstant) {
     317    if (node->isConstant()) {
    318318        out.print(comma, "$", node->constantNumber());
    319319        JSValue value = valueOfJSConstant(node);
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.h

    r166440 r167325  
    4040#include "DFGPlan.h"
    4141#include "DFGScannable.h"
    42 #include "DFGVariadicFunction.h"
    4342#include "InlineCallFrameSet.h"
    4443#include "JSStack.h"
     
    137136    }
    138137   
    139 #define DFG_DEFINE_ADD_NODE(templatePre, templatePost, typeParams, valueParamsComma, valueParams, valueArgs) \
    140     templatePre typeParams templatePost Node* addNode(SpeculatedType type valueParamsComma valueParams) \
    141     { \
    142         Node* node = new (m_allocator) Node(valueArgs); \
    143         node->predict(type); \
    144         return node; \
    145     }
    146     DFG_VARIADIC_TEMPLATE_FUNCTION(DFG_DEFINE_ADD_NODE)
    147 #undef DFG_DEFINE_ADD_NODE
     138    template<typename... Params>
     139    Node* addNode(SpeculatedType type, Params... params)
     140    {
     141        Node* node = new (m_allocator) Node(params...);
     142        node->predict(type);
     143        return node;
     144    }
    148145
    149146    void dethread();
  • trunk/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp

    r165522 r167325  
    156156            block->valuesAtTail.local(i).clear();
    157157        }
     158        if (m_graph.m_form == SSA)
     159            continue;
    158160        if (!block->isOSRTarget)
    159161            continue;
     
    161163            continue;
    162164        for (size_t i = 0; i < m_graph.m_mustHandleAbstractValues.size(); ++i) {
     165            int operand = m_graph.m_mustHandleAbstractValues.operandForIndex(i);
     166            Node* node = block->variablesAtHead.operand(operand);
     167            if (!node)
     168                continue;
    163169            AbstractValue value = m_graph.m_mustHandleAbstractValues[i];
    164             int operand = m_graph.m_mustHandleAbstractValues.operandForIndex(i);
    165             block->valuesAtHead.operand(operand).merge(value);
     170            AbstractValue& abstractValue = block->valuesAtHead.operand(operand);
     171            VariableAccessData* variable = node->variableAccessData();
     172            FlushFormat format = variable->flushFormat();
     173            abstractValue.merge(value);
     174            abstractValue.fixTypeForRepresentation(resultFor(format));
    166175        }
    167176        block->cfaShouldRevisit = true;
  • trunk/Source/JavaScriptCore/dfg/DFGInsertionSet.h

    r164424 r167325  
    11/*
    2  * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    5555        return insert(Insertion(index, element));
    5656    }
     57
     58    template<typename... Params>
     59    Node* insertNode(size_t index, SpeculatedType type, Params... params)
     60    {
     61        return insert(index, m_graph.addNode(type, params...));
     62    }
    5763   
    58 #define DFG_DEFINE_INSERT_NODE(templatePre, templatePost, typeParams, valueParamsComma, valueParams, valueArgs) \
    59     templatePre typeParams templatePost Node* insertNode(size_t index, SpeculatedType type valueParamsComma valueParams) \
    60     { \
    61         return insert(index, m_graph.addNode(type valueParamsComma valueArgs)); \
    62     }
    63     DFG_VARIADIC_TEMPLATE_FUNCTION(DFG_DEFINE_INSERT_NODE)
    64 #undef DFG_DEFINE_INSERT_NODE
    65    
    66     Node* insertConstant(size_t index, NodeOrigin origin, JSValue value)
     64    Node* insertConstant(
     65        size_t index, NodeOrigin origin, JSValue value,
     66        NodeType op = JSConstant)
    6767    {
    6868        unsigned constantReg =
    6969            m_graph.constantRegisterForConstant(value);
    7070        return insertNode(
    71             index, speculationFromValue(value), JSConstant, origin,
    72             OpInfo(constantReg));
     71            index, speculationFromValue(value), op, origin, OpInfo(constantReg));
    7372    }
    7473   
    75     Node* insertConstant(size_t index, CodeOrigin origin, JSValue value)
     74    Node* insertConstant(
     75        size_t index, CodeOrigin origin, JSValue value, NodeType op = JSConstant)
    7676    {
    77         return insertConstant(index, NodeOrigin(origin), value);
     77        return insertConstant(index, NodeOrigin(origin), value, op);
     78    }
     79   
     80    Edge insertConstantForUse(
     81        size_t index, NodeOrigin origin, JSValue value, UseKind useKind)
     82    {
     83        NodeType op;
     84        if (isDouble(useKind))
     85            op = DoubleConstant;
     86        else if (useKind == Int52RepUse)
     87            op = Int52Constant;
     88        else
     89            op = JSConstant;
     90        return Edge(insertConstant(index, origin, value, op), useKind);
     91    }
     92   
     93    Edge insertConstantForUse(
     94        size_t index, CodeOrigin origin, JSValue value, UseKind useKind)
     95    {
     96        return insertConstantForUse(index, NodeOrigin(origin), value, useKind);
    7897    }
    7998
  • trunk/Source/JavaScriptCore/dfg/DFGIntegerCheckCombiningPhase.cpp

    r164229 r167325  
    371371            return source.node();
    372372        return m_insertionSet.insertNode(
    373             nodeIndex, source->prediction(), ArithAdd, origin, OpInfo(arithMode),
    374             source, Edge(
    375                 m_insertionSet.insertConstant(nodeIndex, origin, jsNumber(addend)),
    376                 source.useKind()));
     373            nodeIndex, source->prediction(), source->result(),
     374            ArithAdd, origin, OpInfo(arithMode), source,
     375            m_insertionSet.insertConstantForUse(
     376                nodeIndex, origin, jsNumber(addend), source.useKind()));
    377377    }
    378378   
     
    382382        Node* result = insertAdd(nodeIndex, origin, source, addend);
    383383        m_insertionSet.insertNode(
    384             nodeIndex, SpecNone, HardPhantom, origin, Edge(result, UntypedUse));
     384            nodeIndex, SpecNone, HardPhantom, origin, result->defaultEdge());
    385385        return result;
    386386    }
  • trunk/Source/JavaScriptCore/dfg/DFGNode.cpp

    r164620 r167325  
    9292}
    9393
     94void Node::convertToIdentity()
     95{
     96    RELEASE_ASSERT(child1());
     97    RELEASE_ASSERT(!child2());
     98    NodeFlags result = canonicalResultRepresentation(this->result());
     99    setOpAndDefaultFlags(Identity);
     100    setResult(result);
     101}
     102
    94103} } // namespace JSC::DFG
    95104
     
    122131    }
    123132    out.print("@", node->index());
    124     out.print(AbbreviatedSpeculationDump(node->prediction()));
     133    if (node->hasDoubleResult())
     134        out.print("<Double>");
     135    else if (node->hasInt52Result())
     136        out.print("<Int52>");
    125137}
    126138
  • trunk/Source/JavaScriptCore/dfg/DFGNode.h

    r166095 r167325  
    3939#include "DFGNodeOrigin.h"
    4040#include "DFGNodeType.h"
     41#include "DFGUseKind.h"
    4142#include "DFGVariableAccessData.h"
    4243#include "GetByIdVariant.h"
     
    240241    }
    241242
     243    // Construct a node with up to 3 children, no immediate value.
     244    Node(NodeFlags result, NodeType op, NodeOrigin nodeOrigin, Edge child1 = Edge(), Edge child2 = Edge(), Edge child3 = Edge())
     245        : origin(nodeOrigin)
     246        , children(AdjacencyList::Fixed, child1, child2, child3)
     247        , m_virtualRegister(VirtualRegister())
     248        , m_refCount(1)
     249        , m_prediction(SpecNone)
     250        , m_opInfo(0)
     251        , m_opInfo2(0)
     252    {
     253        misc.replacement = 0;
     254        setOpAndDefaultFlags(op);
     255        setResult(result);
     256        ASSERT(!(m_flags & NodeHasVarArgs));
     257    }
     258
    242259    // Construct a node with up to 3 children and an immediate value.
    243260    Node(NodeType op, NodeOrigin nodeOrigin, OpInfo imm, Edge child1 = Edge(), Edge child2 = Edge(), Edge child3 = Edge())
     
    255272    }
    256273
     274    // Construct a node with up to 3 children and an immediate value.
     275    Node(NodeFlags result, NodeType op, NodeOrigin nodeOrigin, OpInfo imm, Edge child1 = Edge(), Edge child2 = Edge(), Edge child3 = Edge())
     276        : origin(nodeOrigin)
     277        , children(AdjacencyList::Fixed, child1, child2, child3)
     278        , m_virtualRegister(VirtualRegister())
     279        , m_refCount(1)
     280        , m_prediction(SpecNone)
     281        , m_opInfo(imm.m_value)
     282        , m_opInfo2(0)
     283    {
     284        misc.replacement = 0;
     285        setOpAndDefaultFlags(op);
     286        setResult(result);
     287        ASSERT(!(m_flags & NodeHasVarArgs));
     288    }
     289
    257290    // Construct a node with up to 3 children and two immediate values.
    258291    Node(NodeType op, NodeOrigin nodeOrigin, OpInfo imm1, OpInfo imm2, Edge child1 = Edge(), Edge child2 = Edge(), Edge child3 = Edge())
     
    326359    }
    327360   
     361    void setResult(NodeFlags result)
     362    {
     363        ASSERT(!(result & ~NodeResultMask));
     364        clearFlags(NodeResultMask);
     365        mergeFlags(result);
     366    }
     367   
     368    NodeFlags result() const
     369    {
     370        return flags() & NodeResultMask;
     371    }
     372   
    328373    void setOpAndDefaultFlags(NodeType op)
    329374    {
     
    342387    }
    343388
    344     void convertToIdentity()
    345     {
    346         RELEASE_ASSERT(child1());
    347         RELEASE_ASSERT(!child2());
    348         setOpAndDefaultFlags(Identity);
    349     }
     389    void convertToIdentity();
    350390
    351391    bool mustGenerate()
     
    369409    bool isConstant()
    370410    {
    371         return op() == JSConstant;
     411        switch (op()) {
     412        case JSConstant:
     413        case DoubleConstant:
     414        case Int52Constant:
     415            return true;
     416        default:
     417            return false;
     418        }
    372419    }
    373420   
     
    386433        switch (op()) {
    387434        case JSConstant:
     435        case DoubleConstant:
     436        case Int52Constant:
    388437        case WeakJSConstant:
    389438        case PhantomArguments:
     
    402451    void convertToConstant(unsigned constantNumber)
    403452    {
    404         m_op = JSConstant;
     453        if (hasDoubleResult())
     454            m_op = DoubleConstant;
     455        else if (hasInt52Result())
     456            m_op = Int52Constant;
     457        else
     458            m_op = JSConstant;
    405459        m_flags &= ~(NodeMustGenerate | NodeMightClobber | NodeClobbersWorld);
    406460        m_opInfo = constantNumber;
     
    503557            return JSValue(weakConstant());
    504558        case JSConstant:
     559        case DoubleConstant:
     560        case Int52Constant:
    505561            return codeBlock->constantRegister(FirstConstantRegisterIndex + constantNumber()).get();
    506562        case PhantomArguments:
     
    798854    bool hasResult()
    799855    {
    800         return m_flags & NodeResultMask;
     856        return !!result();
    801857    }
    802858
    803859    bool hasInt32Result()
    804860    {
    805         return (m_flags & NodeResultMask) == NodeResultInt32;
     861        return result() == NodeResultInt32;
     862    }
     863   
     864    bool hasInt52Result()
     865    {
     866        return result() == NodeResultInt52;
    806867    }
    807868   
    808869    bool hasNumberResult()
    809870    {
    810         return (m_flags & NodeResultMask) == NodeResultNumber;
     871        return result() == NodeResultNumber;
     872    }
     873   
     874    bool hasDoubleResult()
     875    {
     876        return result() == NodeResultDouble;
    811877    }
    812878   
    813879    bool hasJSResult()
    814880    {
    815         return (m_flags & NodeResultMask) == NodeResultJS;
     881        return result() == NodeResultJS;
    816882    }
    817883   
    818884    bool hasBooleanResult()
    819885    {
    820         return (m_flags & NodeResultMask) == NodeResultBoolean;
     886        return result() == NodeResultBoolean;
    821887    }
    822888
    823889    bool hasStorageResult()
    824890    {
    825         return (m_flags & NodeResultMask) == NodeResultStorage;
     891        return result() == NodeResultStorage;
     892    }
     893   
     894    UseKind defaultUseKind()
     895    {
     896        return useKindForResult(result());
     897    }
     898   
     899    Edge defaultEdge()
     900    {
     901        return Edge(this, defaultUseKind());
    826902    }
    827903
  • trunk/Source/JavaScriptCore/dfg/DFGNodeFlags.cpp

    r165995 r167325  
    11/*
    2  * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4747        case NodeResultNumber:
    4848            out.print(comma, "Number");
     49            break;
     50        case NodeResultDouble:
     51            out.print(comma, "Double");
    4952            break;
    5053        case NodeResultInt32:
  • trunk/Source/JavaScriptCore/dfg/DFGNodeFlags.h

    r166095 r167325  
    11/*
    2  * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3939#define NodeResultJS                     0x0001
    4040#define NodeResultNumber                 0x0002
    41 #define NodeResultInt32                  0x0003
    42 #define NodeResultInt52                  0x0004
    43 #define NodeResultBoolean                0x0005
    44 #define NodeResultStorage                0x0006
     41#define NodeResultDouble                 0x0003
     42#define NodeResultInt32                  0x0004
     43#define NodeResultInt52                  0x0005
     44#define NodeResultBoolean                0x0006
     45#define NodeResultStorage                0x0007
    4546                               
    4647#define NodeMustGenerate                 0x0008 // set on nodes that have side effects, and may not trivially be removed by DCE.
     
    115116}
    116117
     118// FIXME: Get rid of this.
     119// https://bugs.webkit.org/show_bug.cgi?id=131689
     120static inline NodeFlags canonicalResultRepresentation(NodeFlags flags)
     121{
     122    switch (flags) {
     123    case NodeResultDouble:
     124    case NodeResultInt52:
     125    case NodeResultStorage:
     126        return flags;
     127    default:
     128        return NodeResultJS;
     129    }
     130}
     131
    117132void dumpNodeFlags(PrintStream&, NodeFlags);
    118133MAKE_PRINT_ADAPTOR(NodeFlagsDump, NodeFlags, dumpNodeFlags);
  • trunk/Source/JavaScriptCore/dfg/DFGNodeType.h

    r167189 r167325  
    3838    macro(JSConstant, NodeResultJS | NodeDoesNotExit) \
    3939    \
     40    /* Constants with specific representations. */\
     41    macro(DoubleConstant, NodeResultDouble | NodeDoesNotExit) \
     42    macro(Int52Constant, NodeResultInt52 | NodeDoesNotExit) \
     43    \
    4044    /* A constant not in the CodeBlock's constant pool. Uses get patched to jumps that exit the */\
    4145    /* code block. */\
     
    107111    macro(UInt32ToNumber, NodeResultNumber) \
    108112    \
    109     /* Used to cast known integers to doubles, so as to separate the double form */\
    110     /* of the value from the integer form. */\
    111     macro(Int32ToDouble, NodeResultNumber) \
    112     /* Used to speculate that a double value is actually an integer. */\
     113    /* Attempt to truncate a double to int32; this will exit if it can't do it. */\
    113114    macro(DoubleAsInt32, NodeResultInt32) \
    114     /* Used to separate representation and register allocation of Int52's represented */\
    115     /* as values. */\
    116     macro(Int52ToValue, NodeResultJS) \
    117     macro(Int52ToDouble, NodeResultNumber) \
     115    \
     116    /* Change the representation of a value. */\
     117    macro(DoubleRep, NodeResultDouble) \
     118    macro(Int52Rep, NodeResultInt52) \
     119    macro(ValueRep, NodeResultJS) \
    118120    \
    119121    /* Nodes for arithmetic operations. */\
  • trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp

    r166662 r167325  
    270270        switch (recovery.technique()) {
    271271        case InPair:
    272         case InFPR:
    273272        case DisplacedInJSStack:
    274         case DoubleDisplacedInJSStack:
    275273            m_jit.load32(
    276274                &bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.tag,
     
    287285            break;
    288286           
     287        case InFPR:
     288        case DoubleDisplacedInJSStack:
     289            m_jit.move(AssemblyHelpers::TrustedImmPtr(scratch + index), GPRInfo::regT0);
     290            m_jit.loadDouble(GPRInfo::regT0, FPRInfo::fpRegT0);
     291            m_jit.sanitizeDouble(FPRInfo::fpRegT0);
     292            m_jit.storeDouble(FPRInfo::fpRegT0, AssemblyHelpers::addressFor(operand));
     293            break;
     294
    289295        case UnboxedInt32InGPR:
    290296        case Int32DisplacedInJSStack:
  • trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp

    r166662 r167325  
    298298            m_jit.move(AssemblyHelpers::TrustedImmPtr(scratch + index), GPRInfo::regT0);
    299299            m_jit.loadDouble(GPRInfo::regT0, FPRInfo::fpRegT0);
     300            m_jit.sanitizeDouble(FPRInfo::fpRegT0);
    300301            m_jit.boxDouble(FPRInfo::fpRegT0, GPRInfo::regT0);
    301302            m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r167189 r167325  
    491491        case GetArrayLength:
    492492        case GetTypedArrayByteOffset:
    493         case Int32ToDouble:
    494493        case DoubleAsInt32:
    495494        case GetLocalUnlinked:
     
    505504        case CheckTierUpAndOSREnter:
    506505        case InvalidationPoint:
    507         case Int52ToValue:
    508         case Int52ToDouble:
    509506        case CheckInBounds:
    510507        case ValueToInt32:
    511         case HardPhantom: {
     508        case HardPhantom:
     509        case DoubleRep:
     510        case Int52Rep:
     511        case ValueRep:
     512        case DoubleConstant:
     513        case Int52Constant:
     514        case Identity: {
    512515            // This node should never be visible at this stage of compilation. It is
    513516            // inserted by fixup(), which follows this phase.
     
    534537        case In:
    535538            changed |= setPrediction(SpecBoolean);
    536             break;
    537 
    538         case Identity:
    539             changed |= mergePrediction(node->child1()->prediction());
    540539            break;
    541540
  • trunk/Source/JavaScriptCore/dfg/DFGResurrectionForValidationPhase.cpp

    r164229 r167325  
    5858                    continue;
    5959                insertionSet.insertNode(
    60                     nodeIndex + 1, SpecNone, Phantom, node->origin, Edge(node));
     60                    nodeIndex + 1, SpecNone, Phantom, node->origin, node->defaultEdge());
    6161            }
    6262           
  • trunk/Source/JavaScriptCore/dfg/DFGSSAConversionPhase.cpp

    r165995 r167325  
    193193                            m_insertionSet.insertNode(
    194194                                0, SpecNone, MovHint, NodeOrigin(),
    195                                 OpInfo(variable->local().offset()), Edge(node));
     195                                OpInfo(variable->local().offset()), node->defaultEdge());
    196196                        }
    197197                    }
     
    351351                    if (variable->isCaptured())
    352352                        break;
    353                     node->child1().setNode(block->variablesAtHead.operand(variable->local()));
     353                    ASSERT(node->child1().useKind() == UntypedUse);
     354                    node->child1() =
     355                        block->variablesAtHead.operand(variable->local())->defaultEdge();
    354356                    node->convertToPhantom();
    355357                    // This is only for Upsilons. An Upsilon will only refer to a
     
    364366                        break;
    365367                    node->setOpAndDefaultFlags(GetArgument);
    366                     node->mergeFlags(resultFor(node->variableAccessData()->flushFormat()));
     368                    node->setResult(resultFor(node->variableAccessData()->flushFormat()));
    367369                    break;
    368370                }
  • trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h

    r167189 r167325  
    4747        case UntypedUse:
    4848        case Int32Use:
    49         case RealNumberUse:
     49        case DoubleRepUse:
     50        case DoubleRepRealUse:
     51        case Int52RepUse:
    5052        case NumberUse:
    5153        case BooleanUse:
     
    6264        case OtherUse:
    6365        case MiscUse:
    64         case MachineIntUse:
    6566            return;
    6667           
    6768        case KnownInt32Use:
    6869            if (m_state.forNode(edge).m_type & ~SpecInt32)
    69                 m_result = false;
    70             return;
    71            
    72         case KnownNumberUse:
    73             if (m_state.forNode(edge).m_type & ~SpecFullNumber)
    7470                m_result = false;
    7571            return;
     
    112108    switch (node->op()) {
    113109    case JSConstant:
     110    case DoubleConstant:
     111    case Int52Constant:
    114112    case WeakJSConstant:
    115113    case Identity:
     
    138136    case ValueToInt32:
    139137    case UInt32ToNumber:
    140     case Int32ToDouble:
    141138    case DoubleAsInt32:
    142139    case ArithAdd:
     
    243240    case CheckTierUpAndOSREnter:
    244241    case LoopHint:
    245     case Int52ToDouble:
    246     case Int52ToValue:
    247242    case StoreBarrier:
    248243    case StoreBarrierWithNullCheck:
     
    256251    case MultiGetByOffset:
    257252    case MultiPutByOffset:
     253    case ValueRep:
     254    case DoubleRep:
     255    case Int52Rep:
    258256        return true;
    259257       
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r167112 r167325  
    333333        if (node->hasConstant())
    334334            fillAction = SetInt52Constant;
    335         else if (isJSInt32(info.spillFormat()) || info.spillFormat() == DataFormatJS)
    336             fillAction = Load32PayloadConvertToInt52;
    337335        else if (info.spillFormat() == DataFormatInt52)
    338336            fillAction = Load64;
     
    342340            fillAction = Load64;
    343341        else {
    344             // Should never happen. Anything that qualifies as an int32 will never
    345             // be turned into a cell (immediate spec fail) or a double (to-double
    346             // conversions involve a separate node).
    347342            RELEASE_ASSERT_NOT_REACHED();
    348343            fillAction = Load64; // Make GCC happy.
     
    351346        if (node->hasConstant())
    352347            fillAction = SetStrictInt52Constant;
    353         else if (isJSInt32(info.spillFormat()) || info.spillFormat() == DataFormatJS)
    354             fillAction = Load32PayloadSignExtend;
    355348        else if (info.spillFormat() == DataFormatInt52)
    356349            fillAction = Load64ShiftInt52Right;
     
    360353            fillAction = Load64;
    361354        else {
    362             // Should never happen. Anything that qualifies as an int32 will never
    363             // be turned into a cell (immediate spec fail) or a double (to-double
    364             // conversions involve a separate node).
    365355            RELEASE_ASSERT_NOT_REACHED();
    366356            fillAction = Load64; // Make GCC happy.
     
    377367            ASSERT(registerFormat == DataFormatJSInt32);
    378368            fillAction = Load32PayloadBoxInt;
    379         } else if (info.spillFormat() == DataFormatDouble) {
    380             ASSERT(registerFormat == DataFormatJSDouble);
    381             fillAction = LoadDoubleBoxDouble;
    382369        } else
    383370            fillAction = Load64;
     
    435422        ASSERT(isNumberConstant(node));
    436423        fillAction = SetDoubleConstant;
    437     } else if (info.spillFormat() != DataFormatNone && info.spillFormat() != DataFormatDouble) {
    438         // it was already spilled previously and not as a double, which means we need unboxing.
    439         ASSERT(info.spillFormat() & DataFormatJS);
    440         fillAction = LoadJSUnboxDouble;
    441     } else
     424    } else {
     425        ASSERT(info.spillFormat() == DataFormatNone || info.spillFormat() == DataFormatDouble);
    442426        fillAction = LoadDouble;
     427    }
    443428#elif USE(JSVALUE32_64)
    444     ASSERT(info.registerFormat() == DataFormatDouble || info.registerFormat() == DataFormatJSDouble);
     429    ASSERT(info.registerFormat() == DataFormatDouble);
    445430    if (node->hasConstant()) {
    446431        ASSERT(isNumberConstant(node));
     
    528513        m_jit.load32(JITCompiler::payloadFor(plan.node()->virtualRegister()), plan.gpr());
    529514        m_jit.signExtend32ToPtr(plan.gpr(), plan.gpr());
    530         break;
    531     case LoadDoubleBoxDouble:
    532         m_jit.load64(JITCompiler::addressFor(plan.node()->virtualRegister()), plan.gpr());
    533         m_jit.sub64(GPRInfo::tagTypeNumberRegister, plan.gpr());
    534         break;
    535     case LoadJSUnboxDouble:
    536         m_jit.load64(JITCompiler::addressFor(plan.node()->virtualRegister()), canTrample);
    537         unboxDouble(canTrample, plan.fpr());
    538515        break;
    539516#else
     
    10401017#endif // USE(JSVALUE32_64)
    10411018
     1019JSValueRegsTemporary::JSValueRegsTemporary() { }
     1020
     1021JSValueRegsTemporary::JSValueRegsTemporary(SpeculativeJIT* jit)
     1022#if USE(JSVALUE64)
     1023    : m_gpr(jit)
     1024#else
     1025    : m_payloadGPR(jit)
     1026    , m_tagGPR(jit)
     1027#endif
     1028{
     1029}
     1030
     1031JSValueRegsTemporary::~JSValueRegsTemporary() { }
     1032
     1033JSValueRegs JSValueRegsTemporary::regs()
     1034{
     1035#if USE(JSVALUE64)
     1036    return JSValueRegs(m_gpr.gpr());
     1037#else
     1038    return JSValueRegs(m_tagGPR.gpr(), m_payloadGPR.gpr());
     1039#endif
     1040}
     1041
    10421042void GPRTemporary::adopt(GPRTemporary& other)
    10431043{
     
    12591259            compilePeepHoleInt32Branch(node, branchNode, condition);
    12601260#if USE(JSVALUE64)
    1261         else if (node->isBinaryUseKind(MachineIntUse))
     1261        else if (node->isBinaryUseKind(Int52RepUse))
    12621262            compilePeepHoleInt52Branch(node, branchNode, condition);
    12631263#endif // USE(JSVALUE64)
    1264         else if (node->isBinaryUseKind(NumberUse))
     1264        else if (node->isBinaryUseKind(DoubleRepUse))
    12651265            compilePeepHoleDoubleBranch(node, branchNode, doubleCondition);
    12661266        else if (node->op() == CompareEq) {
     
    18181818    case DataFormatJS:
    18191819    case DataFormatJSBoolean:
     1820    case DataFormatJSDouble:
    18201821        return GeneratedOperandJSValue;
    18211822
     
    18241825        return GeneratedOperandInteger;
    18251826
    1826     case DataFormatJSDouble:
    1827     case DataFormatDouble:
    1828         return GeneratedOperandDouble;
    1829        
    18301827    default:
    18311828        RELEASE_ASSERT_NOT_REACHED();
     
    18461843       
    18471844#if USE(JSVALUE64)
    1848     case MachineIntUse: {
     1845    case Int52RepUse: {
    18491846        SpeculateStrictInt52Operand op1(this, node->child1());
    18501847        GPRTemporary result(this, Reuse, op1);
     
    18561853    }
    18571854#endif // USE(JSVALUE64)
     1855       
     1856    case DoubleRepUse: {
     1857        GPRTemporary result(this);
     1858        SpeculateDoubleOperand op1(this, node->child1());
     1859        FPRReg fpr = op1.fpr();
     1860        GPRReg gpr = result.gpr();
     1861        JITCompiler::Jump notTruncatedToInteger = m_jit.branchTruncateDoubleToInt32(fpr, gpr, JITCompiler::BranchIfTruncateFailed);
     1862       
     1863        addSlowPathGenerator(slowPathCall(notTruncatedToInteger, this, toInt32, gpr, fpr));
     1864       
     1865        int32Result(gpr, node);
     1866        return;
     1867    }
    18581868   
    18591869    case NumberUse:
     
    18651875            m_jit.move(op1.gpr(), result.gpr());
    18661876            int32Result(result.gpr(), node, op1.format());
    1867             return;
    1868         }
    1869         case GeneratedOperandDouble: {
    1870             GPRTemporary result(this);
    1871             SpeculateDoubleOperand op1(this, node->child1(), ManualOperandSpeculation);
    1872             FPRReg fpr = op1.fpr();
    1873             GPRReg gpr = result.gpr();
    1874             JITCompiler::Jump notTruncatedToInteger = m_jit.branchTruncateDoubleToInt32(fpr, gpr, JITCompiler::BranchIfTruncateFailed);
    1875            
    1876             addSlowPathGenerator(slowPathCall(notTruncatedToInteger, this, toInt32, gpr, fpr));
    1877 
    1878             int32Result(gpr, node);
    18791877            return;
    18801878        }
     
    20672065}
    20682066
    2069 void SpeculativeJIT::compileInt32ToDouble(Node* node)
    2070 {
    2071     ASSERT(!isInt32Constant(node->child1().node())); // This should have been constant folded.
    2072    
    2073     if (isInt32Speculation(m_state.forNode(node->child1()).m_type)) {
    2074         SpeculateInt32Operand op1(this, node->child1(), ManualOperandSpeculation);
     2067void SpeculativeJIT::compileDoubleRep(Node* node)
     2068{
     2069    switch (node->child1().useKind()) {
     2070    case NumberUse: {
     2071        ASSERT(!isNumberConstant(node->child1().node())); // This should have been constant folded.
     2072   
     2073        if (isInt32Speculation(m_state.forNode(node->child1()).m_type)) {
     2074            SpeculateInt32Operand op1(this, node->child1(), ManualOperandSpeculation);
     2075            FPRTemporary result(this);
     2076            m_jit.convertInt32ToDouble(op1.gpr(), result.fpr());
     2077            doubleResult(result.fpr(), node);
     2078            return;
     2079        }
     2080   
     2081        JSValueOperand op1(this, node->child1(), ManualOperandSpeculation);
    20752082        FPRTemporary result(this);
    2076         m_jit.convertInt32ToDouble(op1.gpr(), result.fpr());
    2077         doubleResult(result.fpr(), node);
    2078         return;
    2079     }
    2080    
    2081     JSValueOperand op1(this, node->child1(), ManualOperandSpeculation);
    2082     FPRTemporary result(this);
    20832083   
    20842084#if USE(JSVALUE64)
    2085     GPRTemporary temp(this);
    2086 
    2087     GPRReg op1GPR = op1.gpr();
    2088     GPRReg tempGPR = temp.gpr();
    2089     FPRReg resultFPR = result.fpr();
    2090    
    2091     JITCompiler::Jump isInteger = m_jit.branch64(
    2092         MacroAssembler::AboveOrEqual, op1GPR, GPRInfo::tagTypeNumberRegister);
    2093    
    2094     if (needsTypeCheck(node->child1(), SpecFullNumber)) {
    2095         typeCheck(
    2096             JSValueRegs(op1GPR), node->child1(), SpecFullNumber,
    2097             m_jit.branchTest64(MacroAssembler::Zero, op1GPR, GPRInfo::tagTypeNumberRegister));
    2098     }
    2099    
    2100     m_jit.move(op1GPR, tempGPR);
    2101     unboxDouble(tempGPR, resultFPR);
    2102     JITCompiler::Jump done = m_jit.jump();
    2103    
    2104     isInteger.link(&m_jit);
    2105     m_jit.convertInt32ToDouble(op1GPR, resultFPR);
    2106     done.link(&m_jit);
    2107 #else
    2108     FPRTemporary temp(this);
    2109    
    2110     GPRReg op1TagGPR = op1.tagGPR();
    2111     GPRReg op1PayloadGPR = op1.payloadGPR();
    2112     FPRReg tempFPR = temp.fpr();
    2113     FPRReg resultFPR = result.fpr();
    2114    
    2115     JITCompiler::Jump isInteger = m_jit.branch32(
    2116         MacroAssembler::Equal, op1TagGPR, TrustedImm32(JSValue::Int32Tag));
    2117    
    2118     if (needsTypeCheck(node->child1(), SpecFullNumber)) {
    2119         typeCheck(
    2120             JSValueRegs(op1TagGPR, op1PayloadGPR), node->child1(), SpecFullNumber,
    2121             m_jit.branch32(MacroAssembler::AboveOrEqual, op1TagGPR, TrustedImm32(JSValue::LowestTag)));
    2122     }
    2123    
    2124     unboxDouble(op1TagGPR, op1PayloadGPR, resultFPR, tempFPR);
    2125     JITCompiler::Jump done = m_jit.jump();
    2126    
    2127     isInteger.link(&m_jit);
    2128     m_jit.convertInt32ToDouble(op1PayloadGPR, resultFPR);
    2129     done.link(&m_jit);
     2085        GPRTemporary temp(this);
     2086
     2087        GPRReg op1GPR = op1.gpr();
     2088        GPRReg tempGPR = temp.gpr();
     2089        FPRReg resultFPR = result.fpr();
     2090   
     2091        JITCompiler::Jump isInteger = m_jit.branch64(
     2092            MacroAssembler::AboveOrEqual, op1GPR, GPRInfo::tagTypeNumberRegister);
     2093   
     2094        if (needsTypeCheck(node->child1(), SpecBytecodeNumber)) {
     2095            typeCheck(
     2096                JSValueRegs(op1GPR), node->child1(), SpecBytecodeNumber,
     2097                m_jit.branchTest64(MacroAssembler::Zero, op1GPR, GPRInfo::tagTypeNumberRegister));
     2098        }
     2099   
     2100        m_jit.move(op1GPR, tempGPR);
     2101        unboxDouble(tempGPR, resultFPR);
     2102        JITCompiler::Jump done = m_jit.jump();
     2103   
     2104        isInteger.link(&m_jit);
     2105        m_jit.convertInt32ToDouble(op1GPR, resultFPR);
     2106        done.link(&m_jit);
     2107#else // USE(JSVALUE64) -> this is the 32_64 case
     2108        FPRTemporary temp(this);
     2109   
     2110        GPRReg op1TagGPR = op1.tagGPR();
     2111        GPRReg op1PayloadGPR = op1.payloadGPR();
     2112        FPRReg tempFPR = temp.fpr();
     2113        FPRReg resultFPR = result.fpr();
     2114   
     2115        JITCompiler::Jump isInteger = m_jit.branch32(
     2116            MacroAssembler::Equal, op1TagGPR, TrustedImm32(JSValue::Int32Tag));
     2117   
     2118        if (needsTypeCheck(node->child1(), SpecBytecodeNumber)) {
     2119            typeCheck(
     2120                JSValueRegs(op1TagGPR, op1PayloadGPR), node->child1(), SpecBytecodeNumber,
     2121                m_jit.branch32(MacroAssembler::AboveOrEqual, op1TagGPR, TrustedImm32(JSValue::LowestTag)));
     2122        }
     2123   
     2124        unboxDouble(op1TagGPR, op1PayloadGPR, resultFPR, tempFPR);
     2125        JITCompiler::Jump done = m_jit.jump();
     2126   
     2127        isInteger.link(&m_jit);
     2128        m_jit.convertInt32ToDouble(op1PayloadGPR, resultFPR);
     2129        done.link(&m_jit);
     2130#endif // USE(JSVALUE64)
     2131   
     2132        doubleResult(resultFPR, node);
     2133        return;
     2134    }
     2135       
     2136#if USE(JSVALUE64)
     2137    case Int52RepUse: {
     2138        SpeculateStrictInt52Operand value(this, node->child1());
     2139        FPRTemporary result(this);
     2140       
     2141        GPRReg valueGPR = value.gpr();
     2142        FPRReg resultFPR = result.fpr();
     2143
     2144        m_jit.convertInt64ToDouble(valueGPR, resultFPR);
     2145       
     2146        doubleResult(resultFPR, node);
     2147        return;
     2148    }
     2149#endif // USE(JSVALUE64)
     2150       
     2151    default:
     2152        RELEASE_ASSERT_NOT_REACHED();
     2153        return;
     2154    }
     2155}
     2156
     2157void SpeculativeJIT::compileValueRep(Node* node)
     2158{
     2159    switch (node->child1().useKind()) {
     2160    case DoubleRepUse: {
     2161        SpeculateDoubleOperand value(this, node->child1());
     2162        JSValueRegsTemporary result(this);
     2163       
     2164        FPRReg valueFPR = value.fpr();
     2165        JSValueRegs resultRegs = result.regs();
     2166
     2167#if CPU(X86)
     2168        // boxDouble() on X86 clobbers the source, so we need to copy.
     2169        // FIXME: Don't do that! https://bugs.webkit.org/show_bug.cgi?id=131690
     2170        FPRTemporary temp(this);
     2171        m_jit.moveDouble(valueFPR, temp.fpr());
     2172        valueFPR = temp.fpr();
    21302173#endif
    2131    
    2132     doubleResult(resultFPR, node);
     2174       
     2175        boxDouble(valueFPR, resultRegs);
     2176       
     2177        jsValueResult(resultRegs, node);
     2178        return;
     2179    }
     2180       
     2181#if USE(JSVALUE64)
     2182    case Int52RepUse: {
     2183        SpeculateStrictInt52Operand value(this, node->child1());
     2184        GPRTemporary result(this);
     2185       
     2186        GPRReg valueGPR = value.gpr();
     2187        GPRReg resultGPR = result.gpr();
     2188       
     2189        boxInt52(valueGPR, resultGPR, DataFormatStrictInt52);
     2190       
     2191        jsValueResult(resultGPR, node);
     2192        return;
     2193    }
     2194#endif // USE(JSVALUE64)
     2195       
     2196    default:
     2197        RELEASE_ASSERT_NOT_REACHED();
     2198        return;
     2199    }
    21332200}
    21342201
     
    23212388           
    23222389#if USE(JSVALUE64)
    2323         case MachineIntUse: {
     2390        case Int52RepUse: {
    23242391            SpeculateStrictInt52Operand valueOp(this, valueUse);
    23252392            GPRTemporary scratch(this);
     
    23452412#endif // USE(JSVALUE64)
    23462413           
    2347         case NumberUse: {
     2414        case DoubleRepUse: {
    23482415            if (isClamped(type)) {
    23492416                ASSERT(elementSize(type) == 1);
     
    24412508    }
    24422509   
    2443     MacroAssembler::Jump notNaN = m_jit.branchDouble(MacroAssembler::DoubleEqual, resultReg, resultReg);
    2444     static const double NaN = QNaN;
    2445     m_jit.loadDouble(&NaN, resultReg);
    2446     notNaN.link(&m_jit);
     2510    m_jit.sanitizeDouble(resultReg);
    24472511   
    24482512    doubleResult(resultReg, node);
     
    26422706       
    26432707#if USE(JSVALUE64)
    2644     case MachineIntUse: {
     2708    case Int52RepUse: {
    26452709        ASSERT(shouldCheckOverflow(node->arithMode()));
    26462710        ASSERT(!shouldCheckNegativeZero(node->arithMode()));
     
    26712735#endif // USE(JSVALUE64)
    26722736   
    2673     case NumberUse: {
     2737    case DoubleRepUse: {
    26742738        SpeculateDoubleOperand op1(this, node->child1());
    26752739        SpeculateDoubleOperand op2(this, node->child2());
     
    28082872       
    28092873#if USE(JSVALUE64)
    2810     case MachineIntUse: {
     2874    case Int52RepUse: {
    28112875        ASSERT(shouldCheckOverflow(node->arithMode()));
    28122876        ASSERT(!shouldCheckNegativeZero(node->arithMode()));
     
    28372901#endif // USE(JSVALUE64)
    28382902
    2839     case NumberUse: {
     2903    case DoubleRepUse: {
    28402904        SpeculateDoubleOperand op1(this, node->child1());
    28412905        SpeculateDoubleOperand op2(this, node->child2());
     
    28822946
    28832947#if USE(JSVALUE64)
    2884     case MachineIntUse: {
     2948    case Int52RepUse: {
    28852949        ASSERT(shouldCheckOverflow(node->arithMode()));
    28862950       
     
    29192983#endif // USE(JSVALUE64)
    29202984       
    2921     case NumberUse: {
     2985    case DoubleRepUse: {
    29222986        SpeculateDoubleOperand op1(this, node->child1());
    29232987        FPRTemporary result(this);
     
    29703034   
    29713035#if USE(JSVALUE64)   
    2972     case MachineIntUse: {
     3036    case Int52RepUse: {
    29733037        ASSERT(shouldCheckOverflow(node->arithMode()));
    29743038       
     
    30273091#endif // USE(JSVALUE64)
    30283092       
    3029     case NumberUse: {
     3093    case DoubleRepUse: {
    30303094        SpeculateDoubleOperand op1(this, node->child1());
    30313095        SpeculateDoubleOperand op2(this, node->child2());
     
    31913255    }
    31923256       
    3193     case NumberUse: {
     3257    case DoubleRepUse: {
    31943258        SpeculateDoubleOperand op1(this, node->child1());
    31953259        SpeculateDoubleOperand op2(this, node->child2());
     
    34963560    }
    34973561       
    3498     case NumberUse: {
     3562    case DoubleRepUse: {
    34993563        SpeculateDoubleOperand op1(this, node->child1());
    35003564        SpeculateDoubleOperand op2(this, node->child2());
     
    35313595   
    35323596#if USE(JSVALUE64)
    3533     if (node->isBinaryUseKind(MachineIntUse)) {
     3597    if (node->isBinaryUseKind(Int52RepUse)) {
    35343598        compileInt52Compare(node, condition);
    35353599        return false;
     
    35373601#endif // USE(JSVALUE64)
    35383602   
    3539     if (node->isBinaryUseKind(NumberUse)) {
     3603    if (node->isBinaryUseKind(DoubleRepUse)) {
    35403604        compileDoubleCompare(node, doubleCondition);
    35413605        return false;
     
    36113675   
    36123676#if USE(JSVALUE64)   
    3613     if (node->isBinaryUseKind(MachineIntUse)) {
     3677    if (node->isBinaryUseKind(Int52RepUse)) {
    36143678        unsigned branchIndexInBlock = detectPeepHoleBranch();
    36153679        if (branchIndexInBlock != UINT_MAX) {
     
    36273691#endif // USE(JSVALUE64)
    36283692
    3629     if (node->isBinaryUseKind(NumberUse)) {
     3693    if (node->isBinaryUseKind(DoubleRepUse)) {
    36303694        unsigned branchIndexInBlock = detectPeepHoleBranch();
    36313695        if (branchIndexInBlock != UINT_MAX) {
     
    44884552}
    44894553
    4490 void SpeculativeJIT::speculateMachineInt(Edge edge)
    4491 {
     4554void SpeculativeJIT::speculateNumber(Edge edge)
     4555{
     4556    if (!needsTypeCheck(edge, SpecBytecodeNumber))
     4557        return;
     4558   
     4559    JSValueOperand value(this, edge, ManualOperandSpeculation);
    44924560#if USE(JSVALUE64)
    4493     if (!needsTypeCheck(edge, SpecMachineInt))
    4494         return;
    4495    
    4496     (SpeculateWhicheverInt52Operand(this, edge)).gpr();
    4497 #else // USE(JSVALUE64)
    4498     UNUSED_PARAM(edge);
    4499     UNREACHABLE_FOR_PLATFORM();
    4500 #endif // USE(JSVALUE64)
    4501 }
    4502 
    4503 void SpeculativeJIT::speculateNumber(Edge edge)
    4504 {
    4505     if (!needsTypeCheck(edge, SpecFullNumber))
    4506         return;
    4507    
    4508     (SpeculateDoubleOperand(this, edge)).fpr();
    4509 }
    4510 
    4511 void SpeculativeJIT::speculateRealNumber(Edge edge)
    4512 {
    4513     if (!needsTypeCheck(edge, SpecFullRealNumber))
     4561    GPRReg gpr = value.gpr();
     4562    typeCheck(
     4563        JSValueRegs(gpr), edge, SpecBytecodeNumber,
     4564        m_jit.branchTest64(MacroAssembler::Zero, gpr, GPRInfo::tagTypeNumberRegister));
     4565#else
     4566    GPRReg tagGPR = value.tagGPR();
     4567    DFG_TYPE_CHECK(
     4568        value.jsValueRegs(), edge, ~SpecInt32,
     4569        m_jit.branch32(MacroAssembler::Equal, tagGPR, TrustedImm32(JSValue::Int32Tag)));
     4570    DFG_TYPE_CHECK(
     4571        value.jsValueRegs(), edge, SpecBytecodeNumber,
     4572        m_jit.branch32(MacroAssembler::AboveOrEqual, tagGPR, TrustedImm32(JSValue::LowestTag)));
     4573#endif
     4574}
     4575
     4576void SpeculativeJIT::speculateDoubleReal(Edge edge)
     4577{
     4578    if (!needsTypeCheck(edge, SpecDoubleReal))
    45144579        return;
    45154580   
    45164581    SpeculateDoubleOperand operand(this, edge);
    45174582    FPRReg fpr = operand.fpr();
    4518     DFG_TYPE_CHECK(
    4519         JSValueRegs(), edge, SpecFullRealNumber,
     4583    typeCheck(
     4584        JSValueRegs(), edge, SpecDoubleReal,
    45204585        m_jit.branchDouble(
    45214586            MacroAssembler::DoubleNotEqualOrUnordered, fpr, fpr));
     
    47694834        ASSERT(!needsTypeCheck(edge, SpecInt32));
    47704835        break;
    4771     case KnownNumberUse:
    4772         ASSERT(!needsTypeCheck(edge, SpecFullNumber));
     4836    case DoubleRepUse:
     4837        ASSERT(!needsTypeCheck(edge, SpecDouble));
     4838        break;
     4839    case Int52RepUse:
     4840        ASSERT(!needsTypeCheck(edge, SpecMachineInt));
    47734841        break;
    47744842    case KnownCellUse:
     
    47814849        speculateInt32(edge);
    47824850        break;
    4783     case MachineIntUse:
    4784         speculateMachineInt(edge);
    4785         break;
    4786     case RealNumberUse:
    4787         speculateRealNumber(edge);
    4788         break;
    47894851    case NumberUse:
    47904852        speculateNumber(edge);
     4853        break;
     4854    case DoubleRepRealUse:
     4855        speculateDoubleReal(edge);
    47914856        break;
    47924857    case BooleanUse:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r166135 r167325  
    5555class SpeculateBooleanOperand;
    5656
    57 enum GeneratedOperandType { GeneratedOperandTypeUnknown, GeneratedOperandInteger, GeneratedOperandDouble, GeneratedOperandJSValue};
     57enum GeneratedOperandType { GeneratedOperandTypeUnknown, GeneratedOperandInteger, GeneratedOperandJSValue};
    5858
    5959inline GPRReg extractResult(GPRReg result) { return result; }
     
    191191#if USE(JSVALUE32_64)
    192192            GenerationInfo& info = generationInfoFromVirtualRegister(spillMe);
    193             RELEASE_ASSERT(info.registerFormat() != DataFormatJSDouble);
    194193            if ((info.registerFormat() & DataFormatJS))
    195194                m_gprs.release(info.tagGPR() == gpr ? info.payloadGPR() : info.tagGPR());
     
    266265            m_gprs.release(info.gpr());
    267266#elif USE(JSVALUE32_64)
    268         if (registerFormat == DataFormatDouble || registerFormat == DataFormatJSDouble)
     267        if (registerFormat == DataFormatDouble)
    269268            m_fprs.release(info.fpr());
    270269        else if (registerFormat & DataFormatJS) {
     
    460459    }
    461460#endif
     461    void boxDouble(FPRReg fpr, JSValueRegs regs)
     462    {
     463        m_jit.boxDouble(fpr, regs);
     464    }
    462465
    463466    // Spill a VirtualRegister to the JSStack.
     
    529532        }
    530533
    531         case DataFormatDouble:
    532         case DataFormatJSDouble: {
     534        case DataFormatDouble: {
    533535            // On JSVALUE32_64 boxing a double is a no-op.
    534536            m_jit.storeDouble(info.fpr(), JITCompiler::addressFor(spillMe));
    535             info.spill(*m_stream, spillMe, DataFormatJSDouble);
     537            info.spill(*m_stream, spillMe, DataFormatDouble);
    536538            return;
    537539        }
     
    926928    }
    927929#endif
     930    void jsValueResult(JSValueRegs regs, Node* node, DataFormat format = DataFormatJS, UseChildrenMode mode = CallUseChildren)
     931    {
     932#if USE(JSVALUE64)
     933        jsValueResult(regs.gpr(), node, format, mode);
     934#else
     935        jsValueResult(regs.tagGPR(), regs.payloadGPR(), node, format, mode);
     936#endif
     937    }
    928938    void storageResult(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
    929939    {
     
    20812091    void compileGetArrayLength(Node*);
    20822092   
     2093    void compileValueRep(Node*);
     2094    void compileDoubleRep(Node*);
     2095   
    20832096    void compileValueToInt32(Node*);
    20842097    void compileUInt32ToNumber(Node*);
    20852098    void compileDoubleAsInt32(Node*);
    2086     void compileInt32ToDouble(Node*);
    20872099    void compileAdd(Node*);
    20882100    void compileMakeRope(Node*);
     
    21862198    void emitAllocateJSArray(GPRReg resultGPR, Structure*, GPRReg storageGPR, unsigned numElements);
    21872199
    2188 #if USE(JSVALUE64)
    2189     JITCompiler::Jump convertToDouble(GPRReg value, FPRReg result, GPRReg tmp);
    2190 #elif USE(JSVALUE32_64)
    2191     JITCompiler::Jump convertToDouble(JSValueOperand&, FPRReg result);
    2192 #endif
    2193    
    21942200    // Add a speculation check.
    21952201    void speculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail);
     
    22182224    void speculateMachineInt(Edge);
    22192225    void speculateNumber(Edge);
    2220     void speculateRealNumber(Edge);
     2226    void speculateDoubleReal(Edge);
    22212227    void speculateBoolean(Edge);
    22222228    void speculateCell(Edge);
     
    25662572};
    25672573
     2574class JSValueRegsTemporary {
     2575public:
     2576    JSValueRegsTemporary();
     2577    JSValueRegsTemporary(SpeculativeJIT*);
     2578    ~JSValueRegsTemporary();
     2579   
     2580    JSValueRegs regs();
     2581
     2582private:
     2583#if USE(JSVALUE64)
     2584    GPRTemporary m_gpr;
     2585#else
     2586    GPRTemporary m_payloadGPR;
     2587    GPRTemporary m_tagGPR;
     2588#endif
     2589};
     2590
    25682591class FPRTemporary {
    25692592public:
     
    27552778class SpeculateInt52Operand {
    27562779public:
    2757     explicit SpeculateInt52Operand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
     2780    explicit SpeculateInt52Operand(SpeculativeJIT* jit, Edge edge)
    27582781        : m_jit(jit)
    27592782        , m_edge(edge)
    27602783        , m_gprOrInvalid(InvalidGPRReg)
    27612784    {
    2762         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == MachineIntUse);
     2785        RELEASE_ASSERT(edge.useKind() == Int52RepUse);
    27632786        if (jit->isFilled(node()))
    27642787            gpr();
     
    28022825class SpeculateStrictInt52Operand {
    28032826public:
    2804     explicit SpeculateStrictInt52Operand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
     2827    explicit SpeculateStrictInt52Operand(SpeculativeJIT* jit, Edge edge)
    28052828        : m_jit(jit)
    28062829        , m_edge(edge)
    28072830        , m_gprOrInvalid(InvalidGPRReg)
    28082831    {
    2809         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == MachineIntUse);
     2832        RELEASE_ASSERT(edge.useKind() == Int52RepUse);
    28102833        if (jit->isFilled(node()))
    28112834            gpr();
     
    28502873class SpeculateWhicheverInt52Operand {
    28512874public:
    2852     explicit SpeculateWhicheverInt52Operand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
     2875    explicit SpeculateWhicheverInt52Operand(SpeculativeJIT* jit, Edge edge)
    28532876        : m_jit(jit)
    28542877        , m_edge(edge)
     
    28562879        , m_strict(jit->betterUseStrictInt52(edge))
    28572880    {
    2858         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == MachineIntUse);
     2881        RELEASE_ASSERT(edge.useKind() == Int52RepUse);
    28592882        if (jit->isFilled(node()))
    28602883            gpr();
    28612884    }
    28622885   
    2863     explicit SpeculateWhicheverInt52Operand(SpeculativeJIT* jit, Edge edge, const SpeculateWhicheverInt52Operand& other, OperandSpeculationMode mode = AutomaticOperandSpeculation)
     2886    explicit SpeculateWhicheverInt52Operand(SpeculativeJIT* jit, Edge edge, const SpeculateWhicheverInt52Operand& other)
    28642887        : m_jit(jit)
    28652888        , m_edge(edge)
     
    28672890        , m_strict(other.m_strict)
    28682891    {
    2869         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == MachineIntUse);
     2892        RELEASE_ASSERT(edge.useKind() == Int52RepUse);
    28702893        if (jit->isFilled(node()))
    28712894            gpr();
    28722895    }
    28732896   
    2874     explicit SpeculateWhicheverInt52Operand(SpeculativeJIT* jit, Edge edge, OppositeShiftTag, const SpeculateWhicheverInt52Operand& other, OperandSpeculationMode mode = AutomaticOperandSpeculation)
     2897    explicit SpeculateWhicheverInt52Operand(SpeculativeJIT* jit, Edge edge, OppositeShiftTag, const SpeculateWhicheverInt52Operand& other)
    28752898        : m_jit(jit)
    28762899        , m_edge(edge)
     
    28782901        , m_strict(!other.m_strict)
    28792902    {
    2880         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == MachineIntUse);
     2903        RELEASE_ASSERT(edge.useKind() == Int52RepUse);
    28812904        if (jit->isFilled(node()))
    28822905            gpr();
     
    29272950class SpeculateDoubleOperand {
    29282951public:
    2929     explicit SpeculateDoubleOperand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
     2952    explicit SpeculateDoubleOperand(SpeculativeJIT* jit, Edge edge)
    29302953        : m_jit(jit)
    29312954        , m_edge(edge)
     
    29332956    {
    29342957        ASSERT(m_jit);
    2935         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || isDouble(edge.useKind()));
     2958        RELEASE_ASSERT(isDouble(edge.useKind()));
    29362959        if (jit->isFilled(node()))
    29372960            fpr();
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r167189 r167325  
    135135
    136136    case DataFormatJSDouble:
    137     case DataFormatDouble: {
    138         FPRReg oldFPR = info.fpr();
    139         m_fprs.lock(oldFPR);
    140         tagGPR = allocate();
    141         payloadGPR = allocate();
    142         boxDouble(oldFPR, tagGPR, payloadGPR);
    143         m_fprs.unlock(oldFPR);
    144         m_fprs.release(oldFPR);
    145         m_gprs.retain(tagGPR, virtualRegister, SpillOrderJS);
    146         m_gprs.retain(payloadGPR, virtualRegister, SpillOrderJS);
    147         info.fillJSValue(*m_stream, tagGPR, payloadGPR, DataFormatJS);
    148         return true;
    149     }
    150 
    151137    case DataFormatJS:
    152138    case DataFormatJSInt32:
     
    161147       
    162148    case DataFormatStorage:
     149    case DataFormatDouble:
    163150        // this type currently never occurs
    164151        RELEASE_ASSERT_NOT_REACHED();
     
    757744    switch (info.registerFormat()) {
    758745    case DataFormatNone: {
    759         if (info.spillFormat() == DataFormatDouble) {
    760             terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
    761             returnFormat = DataFormatInt32;
    762             return allocate();
    763         }
    764        
    765746        if (edge->hasConstant()) {
    766747            ASSERT(isInt32Constant(edge.node()));
     
    814795    }
    815796
    816     case DataFormatDouble:
    817797    case DataFormatCell:
    818798    case DataFormatBoolean:
     
    824804        return allocate();
    825805
     806    case DataFormatDouble:
    826807    case DataFormatStorage:
    827808    default:
     
    846827FPRReg SpeculativeJIT::fillSpeculateDouble(Edge edge)
    847828{
    848     AbstractValue& value = m_state.forNode(edge);
    849     SpeculatedType type = value.m_type;
    850     ASSERT(edge.useKind() != KnownNumberUse || !(value.m_type & ~SpecFullNumber));
    851     m_interpreter.filter(value, SpecFullNumber);
     829    ASSERT(isDouble(edge.useKind()));
     830    ASSERT(edge->hasDoubleResult());
    852831    VirtualRegister virtualRegister = edge->virtualRegister();
    853832    GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
     
    856835
    857836        if (edge->hasConstant()) {
    858             if (isInt32Constant(edge.node())) {
    859                 GPRReg gpr = allocate();
    860                 m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(edge.node())), gpr);
    861                 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
    862                 info.fillInt32(*m_stream, gpr);
    863                 unlock(gpr);
    864             } else if (isNumberConstant(edge.node())) {
    865                 FPRReg fpr = fprAllocate();
    866                 m_jit.loadDouble(addressOfDoubleConstant(edge.node()), fpr);
    867                 m_fprs.retain(fpr, virtualRegister, SpillOrderConstant);
    868                 info.fillDouble(*m_stream, fpr);
    869                 return fpr;
    870             } else {
    871                 terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
    872                 return fprAllocate();
    873             }
    874         } else {
    875             DataFormat spillFormat = info.spillFormat();
    876             ASSERT((spillFormat & DataFormatJS) || spillFormat == DataFormatInt32);
    877             if (spillFormat == DataFormatJSDouble || spillFormat == DataFormatDouble) {
    878                 FPRReg fpr = fprAllocate();
    879                 m_jit.loadDouble(JITCompiler::addressFor(virtualRegister), fpr);
    880                 m_fprs.retain(fpr, virtualRegister, SpillOrderSpilled);
    881                 info.fillDouble(*m_stream, fpr);
    882                 return fpr;
    883             }
    884 
     837            RELEASE_ASSERT(isNumberConstant(edge.node()));
    885838            FPRReg fpr = fprAllocate();
    886             JITCompiler::Jump hasUnboxedDouble;
    887 
    888             if (spillFormat != DataFormatJSInt32 && spillFormat != DataFormatInt32) {
    889                 JITCompiler::Jump isInteger = m_jit.branch32(MacroAssembler::Equal, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::Int32Tag));
    890                 if (type & ~SpecFullNumber)
    891                     speculationCheck(BadType, JSValueSource(JITCompiler::addressFor(virtualRegister)), edge, m_jit.branch32(MacroAssembler::AboveOrEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::LowestTag)));
    892                 m_jit.loadDouble(JITCompiler::addressFor(virtualRegister), fpr);
    893                 hasUnboxedDouble = m_jit.jump();
    894 
    895                 isInteger.link(&m_jit);
    896             }
    897 
    898             m_jit.convertInt32ToDouble(JITCompiler::payloadFor(virtualRegister), fpr);
    899 
    900             if (hasUnboxedDouble.isSet())
    901                 hasUnboxedDouble.link(&m_jit);
    902 
    903             m_fprs.retain(fpr, virtualRegister, SpillOrderSpilled);
     839            m_jit.loadDouble(addressOfDoubleConstant(edge.node()), fpr);
     840            m_fprs.retain(fpr, virtualRegister, SpillOrderConstant);
    904841            info.fillDouble(*m_stream, fpr);
    905             info.killSpilled();
    906842            return fpr;
    907843        }
    908     }
    909 
    910     switch (info.registerFormat()) {
    911     case DataFormatJS:
    912     case DataFormatJSInt32: {
    913         GPRReg tagGPR = info.tagGPR();
    914         GPRReg payloadGPR = info.payloadGPR();
     844       
     845        RELEASE_ASSERT(info.spillFormat() == DataFormatDouble);
    915846        FPRReg fpr = fprAllocate();
    916 
    917         m_gprs.lock(tagGPR);
    918         m_gprs.lock(payloadGPR);
    919 
    920         JITCompiler::Jump hasUnboxedDouble;
    921 
    922         if (info.registerFormat() != DataFormatJSInt32) {
    923             FPRTemporary scratch(this);
    924             JITCompiler::Jump isInteger = m_jit.branch32(MacroAssembler::Equal, tagGPR, TrustedImm32(JSValue::Int32Tag));
    925             if (type & ~SpecFullNumber)
    926                 speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), edge, m_jit.branch32(MacroAssembler::AboveOrEqual, tagGPR, TrustedImm32(JSValue::LowestTag)));
    927             unboxDouble(tagGPR, payloadGPR, fpr, scratch.fpr());
    928             hasUnboxedDouble = m_jit.jump();
    929             isInteger.link(&m_jit);
    930         }
    931 
    932         m_jit.convertInt32ToDouble(payloadGPR, fpr);
    933 
    934         if (hasUnboxedDouble.isSet())
    935             hasUnboxedDouble.link(&m_jit);
    936 
    937         m_gprs.release(tagGPR);
    938         m_gprs.release(payloadGPR);
    939         m_gprs.unlock(tagGPR);
    940         m_gprs.unlock(payloadGPR);
    941         m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
     847        m_jit.loadDouble(JITCompiler::addressFor(virtualRegister), fpr);
     848        m_fprs.retain(fpr, virtualRegister, SpillOrderSpilled);
    942849        info.fillDouble(*m_stream, fpr);
    943         info.killSpilled();
    944850        return fpr;
    945851    }
    946852
    947     case DataFormatInt32: {
    948         FPRReg fpr = fprAllocate();
    949         GPRReg gpr = info.gpr();
    950         m_gprs.lock(gpr);
    951         m_jit.convertInt32ToDouble(gpr, fpr);
    952         m_gprs.unlock(gpr);
    953         return fpr;
    954     }
    955 
    956     case DataFormatJSDouble:
    957     case DataFormatDouble: {
    958         FPRReg fpr = info.fpr();
    959         m_fprs.lock(fpr);
    960         return fpr;
    961     }
    962 
    963     case DataFormatNone:
    964     case DataFormatStorage:
    965         RELEASE_ASSERT_NOT_REACHED();
    966 
    967     case DataFormatCell:
    968     case DataFormatJSCell:
    969     case DataFormatBoolean:
    970     case DataFormatJSBoolean:
    971         terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
    972         return fprAllocate();
    973 
    974     default:
    975         RELEASE_ASSERT_NOT_REACHED();
    976         return InvalidFPRReg;
    977     }
     853    RELEASE_ASSERT(info.registerFormat() == DataFormatDouble);
     854    FPRReg fpr = info.fpr();
     855    m_fprs.lock(fpr);
     856    return fpr;
    978857}
    979858
     
    989868    switch (info.registerFormat()) {
    990869    case DataFormatNone: {
    991         if (info.spillFormat() == DataFormatInt32 || info.spillFormat() == DataFormatDouble) {
     870        if (info.spillFormat() == DataFormatInt32) {
    992871            terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
    993872            return allocate();
     
    1053932    case DataFormatInt32:
    1054933    case DataFormatJSDouble:
    1055     case DataFormatDouble:
    1056934    case DataFormatJSBoolean:
    1057935    case DataFormatBoolean:
     
    1059937        return allocate();
    1060938
     939    case DataFormatDouble:
    1061940    case DataFormatStorage:
    1062941        RELEASE_ASSERT_NOT_REACHED();
     
    1078957    switch (info.registerFormat()) {
    1079958    case DataFormatNone: {
    1080         if (info.spillFormat() == DataFormatInt32 || info.spillFormat() == DataFormatDouble) {
     959        if (info.spillFormat() == DataFormatInt32) {
    1081960            terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
    1082961            return allocate();
     
    11341013    case DataFormatInt32:
    11351014    case DataFormatJSDouble:
    1136     case DataFormatDouble:
    11371015    case DataFormatJSCell:
    11381016    case DataFormatCell:
     
    11401018        return allocate();
    11411019
     1020    case DataFormatDouble:
    11421021    case DataFormatStorage:
    11431022        RELEASE_ASSERT_NOT_REACHED();
     
    11471026        return InvalidGPRReg;
    11481027    }
    1149 }
    1150 
    1151 JITCompiler::Jump SpeculativeJIT::convertToDouble(JSValueOperand& op, FPRReg result)
    1152 {
    1153     FPRTemporary scratch(this);
    1154 
    1155     GPRReg opPayloadGPR = op.payloadGPR();
    1156     GPRReg opTagGPR = op.tagGPR();
    1157     FPRReg scratchFPR = scratch.fpr();
    1158 
    1159     JITCompiler::Jump isInteger = m_jit.branch32(MacroAssembler::Equal, opTagGPR, TrustedImm32(JSValue::Int32Tag));
    1160     JITCompiler::Jump notNumber = m_jit.branch32(MacroAssembler::AboveOrEqual, opPayloadGPR, TrustedImm32(JSValue::LowestTag));
    1161 
    1162     unboxDouble(opTagGPR, opPayloadGPR, result, scratchFPR);
    1163     JITCompiler::Jump done = m_jit.jump();
    1164 
    1165     isInteger.link(&m_jit);
    1166     m_jit.convertInt32ToDouble(opPayloadGPR, result);
    1167 
    1168     done.link(&m_jit);
    1169 
    1170     return notNumber;
    11711028}
    11721029
     
    15481405    }
    15491406       
    1550     case NumberUse: {
     1407    case DoubleRepUse: {
    15511408        SpeculateDoubleOperand value(this, node->child1());
    15521409        FPRTemporary scratch(this);
     
    16771534    }
    16781535   
    1679     case NumberUse:
     1536    case DoubleRepUse:
    16801537    case Int32Use: {
    16811538        if (node->child1().useKind() == Int32Use) {
     
    18181675    switch (op) {
    18191676    case JSConstant:
     1677    case DoubleConstant:
    18201678        initConstantInfo(node);
    18211679        break;
     
    19791837        case FlushedJSValue:
    19801838        case FlushedArguments: {
    1981             if (generationInfoFromVirtualRegister(node->child1()->virtualRegister()).registerFormat() == DataFormatDouble) {
    1982                 SpeculateDoubleOperand value(this, node->child1(), ManualOperandSpeculation);
    1983                 m_jit.storeDouble(value.fpr(), JITCompiler::addressFor(node->machineLocal()));
    1984                 noResult(node);
    1985                 recordSetLocal(DataFormatDouble);
    1986                 break;
    1987             }
    1988            
    19891839            JSValueOperand value(this, node->child1());
    19901840            m_jit.store32(value.payloadGPR(), JITCompiler::payloadFor(node->machineLocal()));
     
    20781928    }
    20791929       
    2080     case Int32ToDouble: {
    2081         compileInt32ToDouble(node);
     1930    case DoubleRep: {
     1931        compileDoubleRep(node);
     1932        break;
     1933    }
     1934       
     1935    case ValueRep: {
     1936        compileValueRep(node);
    20821937        break;
    20831938    }
     
    21522007       
    21532008           
    2154         case NumberUse: {
     2009        case DoubleRepUse: {
    21552010            SpeculateDoubleOperand op1(this, node->child1());
    21562011            FPRTemporary result(this);
     
    21942049        }
    21952050       
    2196         case NumberUse: {
     2051        case DoubleRepUse: {
    21972052            SpeculateDoubleOperand op1(this, node->child1());
    21982053            SpeculateDoubleOperand op2(this, node->child2());
     
    47464601    case CheckTierUpAtReturn:
    47474602    case CheckTierUpAndOSREnter:
    4748     case Int52ToDouble:
    4749     case Int52ToValue:
     4603    case Int52Rep:
     4604    case Int52Constant:
    47504605    case CheckInBounds:
    47514606    case ArithIMul:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r167189 r167325  
    107107            }
    108108               
    109             case DataFormatInt52:
    110             case DataFormatStrictInt52: {
    111                 m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
    112                 boxInt52(gpr, gpr, spillFormat);
    113                 return gpr;
    114             }
    115                
    116109            default:
    117110                m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
    118                 if (spillFormat == DataFormatDouble) {
    119                     // Need to box the double, since we want a JSValue.
    120                     m_jit.sub64(GPRInfo::tagTypeNumberRegister, gpr);
    121                     spillFormat = DataFormatJSDouble;
    122                 } else
    123                     RELEASE_ASSERT(spillFormat & DataFormatJS);
     111                RELEASE_ASSERT(spillFormat & DataFormatJS);
    124112                break;
    125113            }
     
    142130        info.fillJSValue(*m_stream, gpr, DataFormatJSInt32);
    143131        return gpr;
    144     }
    145 
    146     case DataFormatDouble: {
    147         FPRReg fpr = info.fpr();
    148         GPRReg gpr = boxDouble(fpr);
    149 
    150         // Update all info
    151         info.fillJSValue(*m_stream, gpr, DataFormatJSDouble);
    152         m_fprs.release(fpr);
    153         m_gprs.retain(gpr, virtualRegister, SpillOrderJS);
    154 
    155         return gpr;
    156     }
    157        
    158     case DataFormatInt52:
    159     case DataFormatStrictInt52: {
    160         GPRReg gpr = info.gpr();
    161         lock(gpr);
    162         GPRReg resultGPR = allocate();
    163         boxInt52(gpr, resultGPR, info.registerFormat());
    164         unlock(gpr);
    165         return resultGPR;
    166132    }
    167133
     
    180146    case DataFormatBoolean:
    181147    case DataFormatStorage:
     148    case DataFormatDouble:
     149    case DataFormatInt52:
    182150        // this type currently never occurs
    183151        RELEASE_ASSERT_NOT_REACHED();
     
    770738    switch (info.registerFormat()) {
    771739    case DataFormatNone: {
    772         if (info.spillFormat() == DataFormatDouble) {
    773             terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
    774             returnFormat = DataFormatInt32;
    775             return allocate();
    776         }
    777        
    778740        GPRReg gpr = allocate();
    779741
     
    789751        DataFormat spillFormat = info.spillFormat();
    790752       
    791         RELEASE_ASSERT((spillFormat & DataFormatJS) || spillFormat == DataFormatInt32 || spillFormat == DataFormatInt52 || spillFormat == DataFormatStrictInt52);
     753        RELEASE_ASSERT((spillFormat & DataFormatJS) || spillFormat == DataFormatInt32);
    792754       
    793755        m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
     
    808770            info.fillJSValue(*m_stream, gpr, DataFormatJSInt32);
    809771            returnFormat = DataFormatJSInt32;
    810             return gpr;
    811         }
    812         if (spillFormat == DataFormatInt52 || spillFormat == DataFormatStrictInt52) {
    813             // Generally, this can only happen if we've already proved that the
    814             // value is an int32. That's because if a value originated as a JSValue
    815             // then we would speculate that it's an int32 before representing it as
    816             // an int52. Otherwise, if we knowingly produced an int52, then we would
    817             // be boxing it into a value using Int52ToValue. This assertion is valid
    818             // only because Int52 is something that we introduce at prediction time.
    819             // However: we may have an int32-producing node replaced by an
    820             // int52-producing node due to CSE. So we must do a check.
    821             RELEASE_ASSERT(!(type & ~SpecMachineInt));
    822             if (type & SpecInt52) {
    823                 GPRReg temp = allocate();
    824                 m_jit.signExtend32ToPtr(gpr, temp);
    825                 // Currently, we can't supply value profiling information here. :-/
    826                 speculationCheck(
    827                     BadType, JSValueRegs(), 0,
    828                     m_jit.branch64(MacroAssembler::NotEqual, gpr, temp));
    829                 unlock(temp);
    830             }
    831             if (spillFormat == DataFormatStrictInt52)
    832                 m_jit.load32(JITCompiler::addressFor(virtualRegister), gpr);
    833             else {
    834                 m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
    835                 m_jit.rshift64(TrustedImm32(JSValue::int52ShiftAmount), gpr);
    836                 m_jit.zeroExtend32ToPtr(gpr, gpr);
    837             }
    838             info.fillInt32(*m_stream, gpr);
    839             returnFormat = DataFormatInt32;
    840772            return gpr;
    841773        }
     
    898830    }
    899831       
    900     case DataFormatStrictInt52:
    901     case DataFormatInt52: {
    902         GPRReg gpr = info.gpr();
    903         GPRReg result;
    904         DataFormat oldFormat = info.registerFormat();
    905         if (m_gprs.isLocked(gpr)) {
    906             result = allocate();
    907             m_jit.move(gpr, result);
    908         } else {
    909             lock(gpr);
    910             info.fillInt32(*m_stream, gpr);
    911             result = gpr;
    912         }
    913         RELEASE_ASSERT(!(type & ~SpecMachineInt));
    914         if (oldFormat == DataFormatInt52)
    915             m_jit.rshift64(TrustedImm32(JSValue::int52ShiftAmount), result);
    916         if (type & SpecInt52) {
    917             GPRReg temp = allocate();
    918             m_jit.signExtend32ToPtr(result, temp);
    919             // Currently, we can't supply value profiling information here. :-/
    920             speculationCheck(
    921                 BadType, JSValueRegs(), 0,
    922                 m_jit.branch64(MacroAssembler::NotEqual, result, temp));
    923             unlock(temp);
    924         }
    925         m_jit.zeroExtend32ToPtr(result, result);
    926         returnFormat = DataFormatInt32;
    927         return gpr;
    928     }
    929 
    930     case DataFormatDouble:
    931     case DataFormatJSDouble: {
    932         if (edge->hasConstant() && isInt32Constant(edge.node())) {
    933             GPRReg gpr = allocate();
    934             ASSERT(isInt32Constant(edge.node()));
    935             m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(edge.node())), gpr);
    936             returnFormat = DataFormatInt32;
    937             return gpr;
    938         }
    939         FALLTHROUGH;
    940     }
     832    case DataFormatJSDouble:
    941833    case DataFormatCell:
    942834    case DataFormatBoolean:
     
    948840    }
    949841
     842    case DataFormatDouble:
    950843    case DataFormatStorage:
     844    case DataFormatInt52:
     845    case DataFormatStrictInt52:
    951846        RELEASE_ASSERT_NOT_REACHED();
    952847       
     
    977872    ASSERT(desiredFormat == DataFormatInt52 || desiredFormat == DataFormatStrictInt52);
    978873    AbstractValue& value = m_state.forNode(edge);
    979     SpeculatedType type = value.m_type;
    980874    m_interpreter.filter(value, SpecMachineInt);
    981875    VirtualRegister virtualRegister = edge->virtualRegister();
     
    984878    switch (info.registerFormat()) {
    985879    case DataFormatNone: {
    986         if ((edge->hasConstant() && !valueOfJSConstant(edge.node()).isMachineInt()) || info.spillFormat() == DataFormatDouble) {
     880        if ((edge->hasConstant() && !valueOfJSConstant(edge.node()).isMachineInt())) {
    987881            terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
    988882            return allocate();
     
    1005899        DataFormat spillFormat = info.spillFormat();
    1006900       
    1007         RELEASE_ASSERT((spillFormat & DataFormatJS) || spillFormat == DataFormatInt32 || spillFormat == DataFormatInt52 || spillFormat == DataFormatStrictInt52);
     901        RELEASE_ASSERT(spillFormat == DataFormatInt52 || spillFormat == DataFormatStrictInt52);
    1008902       
    1009903        m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
    1010904       
    1011         if (spillFormat == DataFormatJSInt32 || spillFormat == DataFormatInt32) {
    1012             // If we know this was spilled as an integer we can fill without checking.
    1013             m_jit.load32(JITCompiler::addressFor(virtualRegister), gpr);
    1014             m_jit.signExtend32ToPtr(gpr, gpr);
    1015             if (desiredFormat == DataFormatStrictInt52) {
    1016                 info.fillStrictInt52(*m_stream, gpr);
    1017                 return gpr;
    1018             }
     905        m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
     906        if (desiredFormat == DataFormatStrictInt52) {
     907            if (spillFormat == DataFormatInt52)
     908                m_jit.rshift64(TrustedImm32(JSValue::int52ShiftAmount), gpr);
     909            info.fillStrictInt52(*m_stream, gpr);
     910            return gpr;
     911        }
     912        if (spillFormat == DataFormatStrictInt52)
    1019913            m_jit.lshift64(TrustedImm32(JSValue::int52ShiftAmount), gpr);
    1020             info.fillInt52(*m_stream, gpr);
    1021             return gpr;
    1022         }
    1023         if (spillFormat == DataFormatInt52 || spillFormat == DataFormatStrictInt52) {
    1024             m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
    1025             if (desiredFormat == DataFormatStrictInt52) {
    1026                 if (spillFormat == DataFormatInt52)
    1027                     m_jit.rshift64(TrustedImm32(JSValue::int52ShiftAmount), gpr);
    1028                 info.fillStrictInt52(*m_stream, gpr);
    1029                 return gpr;
    1030             }
    1031             if (spillFormat == DataFormatStrictInt52)
    1032                 m_jit.lshift64(TrustedImm32(JSValue::int52ShiftAmount), gpr);
    1033             info.fillInt52(*m_stream, gpr);
    1034             return gpr;
    1035         }
    1036         m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
    1037 
    1038         // Fill as JSValue, and fall through.
    1039         info.fillJSValue(*m_stream, gpr, DataFormatJSInt32);
    1040         m_gprs.unlock(gpr);
    1041         FALLTHROUGH;
    1042     }
    1043 
    1044     case DataFormatJS: {
    1045         // Check the value is an integer. Note that we would *like* to unbox an Int52
    1046         // at this point but this is too costly. We only *prove* that this is an Int52
    1047         // even though we check if it's an int32.
    1048         GPRReg gpr = info.gpr();
    1049         GPRReg result;
    1050         if (m_gprs.isLocked(gpr)) {
    1051             result = allocate();
    1052             m_jit.move(gpr, result);
    1053         } else {
    1054             m_gprs.lock(gpr);
    1055             result = gpr;
    1056         }
    1057         if (type & ~SpecInt32)
    1058             speculationCheck(BadType, JSValueRegs(result), edge, m_jit.branch64(MacroAssembler::Below, result, GPRInfo::tagTypeNumberRegister));
    1059         if (result == gpr) // The not-already-locked, so fill in-place, case.
    1060             info.fillInt52(*m_stream, gpr, desiredFormat);
    1061         m_jit.signExtend32ToPtr(result, result);
    1062         if (desiredFormat == DataFormatInt52)
    1063             m_jit.lshift64(TrustedImm32(JSValue::int52ShiftAmount), result);
    1064         return result;
    1065     }
    1066 
    1067     case DataFormatInt32:
    1068     case DataFormatJSInt32: {
    1069         GPRReg gpr = info.gpr();
    1070         GPRReg result;
    1071         if (m_gprs.isLocked(gpr)) {
    1072             result = allocate();
    1073             m_jit.move(gpr, result);
    1074         } else {
    1075             m_gprs.lock(gpr);
    1076             info.fillInt52(*m_stream, gpr, desiredFormat);
    1077             result = gpr;
    1078         }
    1079         m_jit.signExtend32ToPtr(result, result);
    1080         if (desiredFormat == DataFormatInt52)
    1081             m_jit.lshift64(TrustedImm32(JSValue::int52ShiftAmount), result);
    1082         return result;
     914        info.fillInt52(*m_stream, gpr);
     915        return gpr;
    1083916    }
    1084917
     
    1117950    }
    1118951
    1119     case DataFormatDouble:
    1120     case DataFormatJSDouble:
    1121         if (edge->hasConstant()) {
    1122             JSValue jsValue = valueOfJSConstant(edge.node());
    1123             if (jsValue.isMachineInt()) {
    1124                 int64_t value = jsValue.asMachineInt();
    1125                 if (desiredFormat == DataFormatInt52)
    1126                     value = value << JSValue::int52ShiftAmount;
    1127                 GPRReg gpr = allocate();
    1128                 m_jit.move(MacroAssembler::Imm64(value), gpr);
    1129                 return gpr;
    1130             }
    1131         }
    1132         FALLTHROUGH;
    1133     case DataFormatCell:
    1134     case DataFormatBoolean:
    1135     case DataFormatJSCell:
    1136     case DataFormatJSBoolean: {
    1137         terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
    1138         return allocate();
    1139     }
    1140 
    1141     case DataFormatStorage:
    1142         RELEASE_ASSERT_NOT_REACHED();
    1143        
    1144952    default:
    1145953        RELEASE_ASSERT_NOT_REACHED();
     
    1150958FPRReg SpeculativeJIT::fillSpeculateDouble(Edge edge)
    1151959{
    1152     AbstractValue& value = m_state.forNode(edge);
    1153     SpeculatedType type = value.m_type;
    1154     ASSERT(edge.useKind() != KnownNumberUse || !(value.m_type & ~SpecFullNumber));
    1155     m_interpreter.filter(value, SpecFullNumber);
     960    ASSERT(edge.useKind() == DoubleRepUse || edge.useKind() == DoubleRepRealUse);
     961    ASSERT(edge->hasDoubleResult());
    1156962    VirtualRegister virtualRegister = edge->virtualRegister();
    1157963    GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
     
    1161967            GPRReg gpr = allocate();
    1162968
    1163             if (isInt32Constant(edge.node())) {
    1164                 FPRReg fpr = fprAllocate();
    1165                 m_jit.move(MacroAssembler::Imm64(reinterpretDoubleToInt64(static_cast<double>(valueOfInt32Constant(edge.node())))), gpr);
    1166                 m_jit.move64ToDouble(gpr, fpr);
    1167                 unlock(gpr);
    1168 
    1169                 // Don't fill double here since that will lead to confusion: the
    1170                 // register allocator will now think that this is a double while
    1171                 // everyone else thinks it's an integer.
    1172                 return fpr;
    1173             }
    1174969            if (isNumberConstant(edge.node())) {
    1175970                FPRReg fpr = fprAllocate();
     
    1187982       
    1188983        DataFormat spillFormat = info.spillFormat();
    1189         switch (spillFormat) {
    1190         case DataFormatDouble: {
    1191             FPRReg fpr = fprAllocate();
    1192             m_jit.loadDouble(JITCompiler::addressFor(virtualRegister), fpr);
    1193             m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
    1194             info.fillDouble(*m_stream, fpr);
    1195             return fpr;
    1196         }
    1197            
    1198         case DataFormatInt32: {
    1199             GPRReg gpr = allocate();
    1200            
    1201             m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
    1202             m_jit.load32(JITCompiler::addressFor(virtualRegister), gpr);
    1203             info.fillInt32(*m_stream, gpr);
    1204             unlock(gpr);
    1205             break;
    1206         }
    1207            
    1208         case DataFormatInt52: {
    1209             GPRReg gpr = allocate();
    1210             m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
    1211             m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
    1212             info.fillInt52(*m_stream, gpr);
    1213             unlock(gpr);
    1214             break;
    1215         }
    1216            
    1217         case DataFormatStrictInt52: {
    1218             GPRReg gpr = allocate();
    1219             m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
    1220             m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
    1221             info.fillStrictInt52(*m_stream, gpr);
    1222             unlock(gpr);
    1223             break;
    1224         }
    1225 
    1226         default:
    1227             GPRReg gpr = allocate();
    1228 
    1229             RELEASE_ASSERT(spillFormat & DataFormatJS);
    1230             m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
    1231             m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
    1232             info.fillJSValue(*m_stream, gpr, spillFormat);
    1233             unlock(gpr);
    1234             break;
    1235         }
    1236     }
    1237 
    1238     switch (info.registerFormat()) {
    1239     case DataFormatNone: // Should have filled, above.
    1240     case DataFormatBoolean: // This type never occurs.
    1241     case DataFormatStorage:
    1242         RELEASE_ASSERT_NOT_REACHED();
    1243 
    1244     case DataFormatCell:
    1245         terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
    1246         return fprAllocate();
    1247 
    1248     case DataFormatJSCell:
    1249     case DataFormatJS:
    1250     case DataFormatJSBoolean: {
    1251         GPRReg jsValueGpr = info.gpr();
    1252         m_gprs.lock(jsValueGpr);
     984        RELEASE_ASSERT(spillFormat == DataFormatDouble);
    1253985        FPRReg fpr = fprAllocate();
    1254         GPRReg tempGpr = allocate();
    1255 
    1256         JITCompiler::Jump isInteger = m_jit.branch64(MacroAssembler::AboveOrEqual, jsValueGpr, GPRInfo::tagTypeNumberRegister);
    1257 
    1258         if (type & ~SpecFullNumber)
    1259             speculationCheck(BadType, JSValueRegs(jsValueGpr), edge, m_jit.branchTest64(MacroAssembler::Zero, jsValueGpr, GPRInfo::tagTypeNumberRegister));
    1260 
    1261         // First, if we get here we have a double encoded as a JSValue
    1262         m_jit.move(jsValueGpr, tempGpr);
    1263         unboxDouble(tempGpr, fpr);
    1264         JITCompiler::Jump hasUnboxedDouble = m_jit.jump();
    1265 
    1266         // Finally, handle integers.
    1267         isInteger.link(&m_jit);
    1268         m_jit.convertInt32ToDouble(jsValueGpr, fpr);
    1269         hasUnboxedDouble.link(&m_jit);
    1270 
    1271         m_gprs.release(jsValueGpr);
    1272         m_gprs.unlock(jsValueGpr);
    1273         m_gprs.unlock(tempGpr);
     986        m_jit.loadDouble(JITCompiler::addressFor(virtualRegister), fpr);
    1274987        m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
    1275988        info.fillDouble(*m_stream, fpr);
    1276         info.killSpilled();
    1277989        return fpr;
    1278990    }
    1279991
    1280     case DataFormatJSInt32:
    1281     case DataFormatInt32: {
    1282         FPRReg fpr = fprAllocate();
    1283         GPRReg gpr = info.gpr();
    1284         m_gprs.lock(gpr);
    1285         m_jit.convertInt32ToDouble(gpr, fpr);
    1286         m_gprs.unlock(gpr);
    1287         return fpr;
    1288     }
    1289        
    1290     case DataFormatInt52: {
    1291         FPRReg fpr = fprAllocate();
    1292         GPRReg gpr = info.gpr();
    1293         m_gprs.lock(gpr);
    1294         GPRReg temp = allocate();
    1295         m_jit.move(gpr, temp);
    1296         m_jit.rshift64(TrustedImm32(JSValue::int52ShiftAmount), temp);
    1297         m_jit.convertInt64ToDouble(temp, fpr);
    1298         unlock(temp);
    1299         m_gprs.unlock(gpr);
    1300         return fpr;
    1301     }
    1302        
    1303     case DataFormatStrictInt52: {
    1304         FPRReg fpr = fprAllocate();
    1305         GPRReg gpr = info.gpr();
    1306         m_gprs.lock(gpr);
    1307         m_jit.convertInt64ToDouble(gpr, fpr);
    1308         m_gprs.unlock(gpr);
    1309         return fpr;
    1310     }
    1311 
    1312     // Unbox the double
    1313     case DataFormatJSDouble: {
    1314         GPRReg gpr = info.gpr();
    1315         FPRReg fpr = fprAllocate();
    1316         if (m_gprs.isLocked(gpr)) {
    1317             // Make sure we don't trample gpr if it is in use.
    1318             GPRReg temp = allocate();
    1319             m_jit.move(gpr, temp);
    1320             unboxDouble(temp, fpr);
    1321             unlock(temp);
    1322         } else
    1323             unboxDouble(gpr, fpr);
    1324 
    1325         m_gprs.release(gpr);
    1326         m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
    1327 
    1328         info.fillDouble(*m_stream, fpr);
    1329         return fpr;
    1330     }
    1331 
    1332     case DataFormatDouble: {
    1333         FPRReg fpr = info.fpr();
    1334         m_fprs.lock(fpr);
    1335         return fpr;
    1336     }
    1337        
    1338     default:
    1339         RELEASE_ASSERT_NOT_REACHED();
    1340         return InvalidFPRReg;
    1341     }
     992    RELEASE_ASSERT(info.registerFormat() == DataFormatDouble);
     993    FPRReg fpr = info.fpr();
     994    m_fprs.lock(fpr);
     995    return fpr;
    1342996}
    1343997
     
    13531007    switch (info.registerFormat()) {
    13541008    case DataFormatNone: {
    1355         if (info.spillFormat() == DataFormatInt32 || info.spillFormat() == DataFormatDouble) {
    1356             terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
    1357             return allocate();
    1358         }
    1359        
    13601009        GPRReg gpr = allocate();
    13611010
     
    14061055    case DataFormatInt32:
    14071056    case DataFormatJSDouble:
    1408     case DataFormatDouble:
    14091057    case DataFormatJSBoolean:
    1410     case DataFormatBoolean:
    1411     case DataFormatInt52:
    1412     case DataFormatStrictInt52: {
     1058    case DataFormatBoolean: {
    14131059        terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
    14141060        return allocate();
    14151061    }
    14161062
     1063    case DataFormatDouble:
    14171064    case DataFormatStorage:
     1065    case DataFormatInt52:
     1066    case DataFormatStrictInt52:
    14181067        RELEASE_ASSERT_NOT_REACHED();
    14191068       
     
    14341083    switch (info.registerFormat()) {
    14351084    case DataFormatNone: {
    1436         if (info.spillFormat() == DataFormatInt32 || info.spillFormat() == DataFormatDouble) {
     1085        if (info.spillFormat() == DataFormatInt32) {
    14371086            terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
    14381087            return allocate();
     
    14881137    case DataFormatInt32:
    14891138    case DataFormatJSDouble:
    1490     case DataFormatDouble:
    14911139    case DataFormatJSCell:
    14921140    case DataFormatCell:
    1493     case DataFormatInt52:
    1494     case DataFormatStrictInt52: {
    14951141        terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
    14961142        return allocate();
    1497     }
    1498        
     1143       
     1144    case DataFormatDouble:
    14991145    case DataFormatStorage:
     1146    case DataFormatInt52:
     1147    case DataFormatStrictInt52:
    15001148        RELEASE_ASSERT_NOT_REACHED();
    15011149       
     
    15041152        return InvalidGPRReg;
    15051153    }
    1506 }
    1507 
    1508 JITCompiler::Jump SpeculativeJIT::convertToDouble(GPRReg value, FPRReg result, GPRReg tmp)
    1509 {
    1510     JITCompiler::Jump isInteger = m_jit.branch64(MacroAssembler::AboveOrEqual, value, GPRInfo::tagTypeNumberRegister);
    1511    
    1512     JITCompiler::Jump notNumber = m_jit.branchTest64(MacroAssembler::Zero, value, GPRInfo::tagTypeNumberRegister);
    1513    
    1514     m_jit.move(value, tmp);
    1515     unboxDouble(tmp, result);
    1516    
    1517     JITCompiler::Jump done = m_jit.jump();
    1518    
    1519     isInteger.link(&m_jit);
    1520    
    1521     m_jit.convertInt32ToDouble(value, result);
    1522    
    1523     done.link(&m_jit);
    1524 
    1525     return notNumber;
    15261154}
    15271155
     
    19221550    }
    19231551       
    1924     case NumberUse: {
     1552    case DoubleRepUse: {
    19251553        SpeculateDoubleOperand value(this, node->child1());
    19261554        FPRTemporary scratch(this);
     
    20611689       
    20621690    case Int32Use:
    2063     case NumberUse: {
     1691    case DoubleRepUse: {
    20641692        if (node->child1().useKind() == Int32Use) {
    20651693            bool invert = false;
     
    21541782    switch (op) {
    21551783    case JSConstant:
     1784    case DoubleConstant:
     1785    case Int52Constant:
    21561786        initConstantInfo(node);
    21571787        break;
     
    24012031    }
    24022032       
    2403     case Int32ToDouble: {
    2404         compileInt32ToDouble(node);
    2405         break;
    2406     }
    2407        
    2408     case Int52ToValue: {
    2409         JSValueOperand operand(this, node->child1());
     2033    case DoubleRep: {
     2034        compileDoubleRep(node);
     2035        break;
     2036    }
     2037       
     2038    case ValueRep: {
     2039        compileValueRep(node);
     2040        break;
     2041    }
     2042       
     2043    case Int52Rep: {
     2044        SpeculateInt32Operand operand(this, node->child1());
    24102045        GPRTemporary result(this, Reuse, operand);
    2411         m_jit.move(operand.gpr(), result.gpr());
    2412         jsValueResult(result.gpr(), node);
    2413         break;
    2414     }
    2415        
    2416     case Int52ToDouble: {
    2417         SpeculateDoubleOperand operand(this, node->child1());
    2418         FPRTemporary result(this, operand);
    2419         m_jit.moveDouble(operand.fpr(), result.fpr());
    2420         doubleResult(result.fpr(), node);
     2046       
     2047        m_jit.signExtend32ToPtr(operand.gpr(), result.gpr());
     2048       
     2049        strictInt52Result(result.gpr(), node);
    24212050        break;
    24222051    }
     
    24872116        }
    24882117       
    2489         case NumberUse: {
     2118        case DoubleRepUse: {
    24902119            SpeculateDoubleOperand op1(this, node->child1());
    24912120            FPRTemporary result(this);
     
    25252154        }
    25262155       
    2527         case NumberUse: {
     2156        case DoubleRepUse: {
    25282157            SpeculateDoubleOperand op1(this, node->child1());
    25292158            SpeculateDoubleOperand op2(this, node->child2());
  • trunk/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp

    r164229 r167325  
    171171            break;
    172172           
     173        case ValueRep:
     174        case Int52Rep:
     175        case DoubleRep: {
     176            // This short-circuits circuitous conversions, like ValueRep(DoubleRep(value)) or
     177            // even more complicated things. Like, it can handle a beast like
     178            // ValueRep(DoubleRep(Int52Rep(value))).
     179           
     180            // The only speculation that we would do beyond validating that we have a type that
     181            // can be represented a certain way is an Int32 check that would appear on Int52Rep
     182            // nodes. For now, if we see this and the final type we want is an Int52, we use it
     183            // as an excuse not to fold. The only thing we would need is a Int52RepInt32Use kind.
     184            bool hadInt32Check = false;
     185            if (m_node->op() == Int52Rep) {
     186                ASSERT(m_node->child1().useKind() == Int32Use);
     187                hadInt32Check = true;
     188            }
     189            for (Node* node = m_node->child1().node(); ; node = node->child1().node()) {
     190                if (canonicalResultRepresentation(node->result()) ==
     191                    canonicalResultRepresentation(m_node->result())) {
     192                    m_insertionSet.insertNode(
     193                        m_nodeIndex, SpecNone, Phantom, m_node->origin, m_node->child1());
     194                    if (hadInt32Check) {
     195                        // FIXME: Consider adding Int52RepInt32Use or even DoubleRepInt32Use,
     196                        // which would be super weird. The latter would only arise in some
     197                        // seriously circuitous conversions.
     198                        if (canonicalResultRepresentation(node->result()) != NodeResultJS)
     199                            break;
     200                       
     201                        m_insertionSet.insertNode(
     202                            m_nodeIndex, SpecNone, Phantom, m_node->origin,
     203                            Edge(node, Int32Use));
     204                    }
     205                    m_node->child1() = node->defaultEdge();
     206                    m_node->convertToIdentity();
     207                    m_changed = true;
     208                    break;
     209                }
     210               
     211                switch (node->op()) {
     212                case Int52Rep:
     213                    ASSERT(node->child1().useKind() == Int32Use);
     214                    hadInt32Check = true;
     215                    continue;
     216                   
     217                case DoubleRep:
     218                case ValueRep:
     219                    continue;
     220                   
     221                default:
     222                    break;
     223                }
     224                break;
     225            }
     226            break;
     227        }
     228           
    173229        default:
    174230            break;
  • trunk/Source/JavaScriptCore/dfg/DFGUseKind.cpp

    r165842 r167325  
    4747        out.print("KnownInt32");
    4848        break;
    49     case MachineIntUse:
    50         out.print("MachineInt");
    51         break;
    52     case RealNumberUse:
    53         out.print("RealNumber");
     49    case Int52RepUse:
     50        out.print("Int52Rep");
    5451        break;
    5552    case NumberUse:
    5653        out.print("Number");
    5754        break;
    58     case KnownNumberUse:
    59         out.print("KnownNumber");
     55    case DoubleRepUse:
     56        out.print("DoubleRep");
     57        break;
     58    case DoubleRepRealUse:
     59        out.print("DoubleRepReal");
    6060        break;
    6161    case BooleanUse:
  • trunk/Source/JavaScriptCore/dfg/DFGUseKind.h

    r165842 r167325  
    2929#if ENABLE(DFG_JIT)
    3030
     31#include "DFGNodeFlags.h"
    3132#include "SpeculatedType.h"
    3233#include <wtf/PrintStream.h>
     
    3839    Int32Use,
    3940    KnownInt32Use,
    40     MachineIntUse,
    41     RealNumberUse,
     41    Int52RepUse,
    4242    NumberUse,
    43     KnownNumberUse,
     43    DoubleRepUse,
     44    DoubleRepRealUse,
    4445    BooleanUse,
    4546    CellUse,
     
    6061};
    6162
    62 ALWAYS_INLINE SpeculatedType typeFilterFor(UseKind useKind)
     63inline SpeculatedType typeFilterFor(UseKind useKind)
    6364{
    6465    switch (useKind) {
     
    6869    case KnownInt32Use:
    6970        return SpecInt32;
    70     case MachineIntUse:
     71    case Int52RepUse:
    7172        return SpecMachineInt;
    72     case RealNumberUse:
    73         return SpecFullRealNumber;
    7473    case NumberUse:
    75     case KnownNumberUse:
    76         return SpecFullNumber;
     74        return SpecBytecodeNumber;
     75    case DoubleRepUse:
     76        return SpecDouble;
     77    case DoubleRepRealUse:
     78        return SpecDoubleReal;
    7779    case BooleanUse:
    7880        return SpecBoolean;
     
    109111}
    110112
    111 ALWAYS_INLINE bool shouldNotHaveTypeCheck(UseKind kind)
     113inline bool shouldNotHaveTypeCheck(UseKind kind)
    112114{
    113115    switch (kind) {
    114116    case UntypedUse:
    115117    case KnownInt32Use:
    116     case KnownNumberUse:
    117118    case KnownCellUse:
    118119    case KnownStringUse:
    119         return true;
    120     default:
    121         return false;
    122     }
    123 }
    124 
    125 ALWAYS_INLINE bool mayHaveTypeCheck(UseKind kind)
     120    case Int52RepUse:
     121    case DoubleRepUse:
     122        return true;
     123    default:
     124        return false;
     125    }
     126}
     127
     128inline bool mayHaveTypeCheck(UseKind kind)
    126129{
    127130    return !shouldNotHaveTypeCheck(kind);
    128131}
    129132
    130 ALWAYS_INLINE bool isNumerical(UseKind kind)
     133inline bool isNumerical(UseKind kind)
    131134{
    132135    switch (kind) {
    133136    case Int32Use:
    134137    case KnownInt32Use:
    135     case MachineIntUse:
    136     case RealNumberUse:
    137138    case NumberUse:
    138     case KnownNumberUse:
    139         return true;
    140     default:
    141         return false;
    142     }
    143 }
    144 
    145 ALWAYS_INLINE bool isDouble(UseKind kind)
    146 {
    147     switch (kind) {
    148     case RealNumberUse:
    149     case NumberUse:
    150     case KnownNumberUse:
    151         return true;
    152     default:
    153         return false;
    154     }
    155 }
    156 
    157 ALWAYS_INLINE bool isCell(UseKind kind)
     139    case Int52RepUse:
     140    case DoubleRepUse:
     141    case DoubleRepRealUse:
     142        return true;
     143    default:
     144        return false;
     145    }
     146}
     147
     148inline bool isDouble(UseKind kind)
     149{
     150    switch (kind) {
     151    case DoubleRepUse:
     152    case DoubleRepRealUse:
     153        return true;
     154    default:
     155        return false;
     156    }
     157}
     158
     159inline bool isCell(UseKind kind)
    158160{
    159161    switch (kind) {
     
    175177// Returns true if it uses structure in a way that could be clobbered by
    176178// things that change the structure.
    177 ALWAYS_INLINE bool usesStructure(UseKind kind)
     179inline bool usesStructure(UseKind kind)
    178180{
    179181    switch (kind) {
     
    186188}
    187189
     190inline UseKind useKindForResult(NodeFlags result)
     191{
     192    ASSERT(!(result & ~NodeResultMask));
     193    switch (result) {
     194    case NodeResultInt52:
     195        return Int52RepUse;
     196    case NodeResultDouble:
     197        return DoubleRepUse;
     198    default:
     199        return UntypedUse;
     200    }
     201}
     202
    188203} } // namespace JSC::DFG
    189204
  • trunk/Source/JavaScriptCore/dfg/DFGValidate.cpp

    r164229 r167325  
    11/*
    2  * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012-2014 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    116116                    m_myRefCounts.find(edge.node())->value++;
    117117                   
     118                    VALIDATE((node, edge), edge->hasDoubleResult() == (edge.useKind() == DoubleRepUse || edge.useKind() == DoubleRepRealUse));
     119                    VALIDATE((node, edge), edge->hasInt52Result() == (edge.useKind() == Int52RepUse));
     120                   
    118121                    if (m_graph.m_form == SSA) {
    119122                        // In SSA, all edges must hasResult().
  • trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp

    r167189 r167325  
    9191    case ArithNegate:
    9292    case UInt32ToNumber:
    93     case Int32ToDouble:
    9493    case CompareEqConstant:
    9594    case Jump:
     
    104103    case GetClosureVar:
    105104    case PutClosureVar:
    106     case Int52ToValue:
    107105    case InvalidationPoint:
    108106    case StringCharAt:
     
    153151    case CheckHasInstance:
    154152    case InstanceOf:
     153    case DoubleRep:
     154    case ValueRep:
     155    case Int52Rep:
     156    case DoubleConstant:
     157    case Int52Constant:
    155158        // These are OK.
     159        break;
     160    case Identity:
     161        // No backend handles this because it will be optimized out. But we may check
     162        // for capabilities before optimization. It would be a deep error to remove this
     163        // case because it would prevent us from catching bugs where the FTL backend
     164        // pipeline failed to optimize out an Identity.
    156165        break;
    157166    case PutByIdDirect:
     
    236245        if (node->isBinaryUseKind(Int32Use))
    237246            break;
    238         if (node->isBinaryUseKind(MachineIntUse))
    239             break;
    240         if (node->isBinaryUseKind(NumberUse))
     247        if (node->isBinaryUseKind(Int52RepUse))
     248            break;
     249        if (node->isBinaryUseKind(DoubleRepUse))
    241250            break;
    242251        if (node->isBinaryUseKind(StringIdentUse))
     
    256265        if (node->isBinaryUseKind(Int32Use))
    257266            break;
    258         if (node->isBinaryUseKind(MachineIntUse))
    259             break;
    260         if (node->isBinaryUseKind(NumberUse))
     267        if (node->isBinaryUseKind(Int52RepUse))
     268            break;
     269        if (node->isBinaryUseKind(DoubleRepUse))
    261270            break;
    262271        if (node->isBinaryUseKind(StringIdentUse))
     
    281290        if (node->isBinaryUseKind(Int32Use))
    282291            break;
    283         if (node->isBinaryUseKind(MachineIntUse))
    284             break;
    285         if (node->isBinaryUseKind(NumberUse))
     292        if (node->isBinaryUseKind(Int52RepUse))
     293            break;
     294        if (node->isBinaryUseKind(DoubleRepUse))
    286295            break;
    287296        if (node->isBinaryUseKind(UntypedUse))
     
    351360                case Int32Use:
    352361                case KnownInt32Use:
    353                 case MachineIntUse:
     362                case Int52RepUse:
    354363                case NumberUse:
    355                 case KnownNumberUse:
    356                 case RealNumberUse:
     364                case DoubleRepUse:
     365                case DoubleRepRealUse:
    357366                case BooleanUse:
    358367                case CellUse:
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp

    r167189 r167325  
    187187                LType type;
    188188                switch (node->flags() & NodeResultMask) {
    189                 case NodeResultNumber:
     189                case NodeResultDouble:
    190190                    type = m_out.doubleType;
    191191                    break;
     
    283283        case JSConstant:
    284284            break;
     285        case DoubleConstant:
     286            compileDoubleConstant();
     287            break;
     288        case Int52Constant:
     289            compileInt52Constant();
     290            break;
    285291        case WeakJSConstant:
    286292            compileWeakJSConstant();
     
    288294        case PhantomArguments:
    289295            compilePhantomArguments();
     296            break;
     297        case DoubleRep:
     298            compileDoubleRep();
     299            break;
     300        case ValueRep:
     301            compileValueRep();
     302            break;
     303        case Int52Rep:
     304            compileInt52Rep();
     305            break;
     306        case ValueToInt32:
     307            compileValueToInt32();
    290308            break;
    291309        case GetArgument:
     
    378396        case UInt32ToNumber:
    379397            compileUInt32ToNumber();
    380             break;
    381         case Int32ToDouble:
    382             compileInt32ToDouble();
    383398            break;
    384399        case CheckStructure:
     
    569584        case InvalidationPoint:
    570585            compileInvalidationPoint();
    571             break;
    572         case ValueToInt32:
    573             compileValueToInt32();
    574             break;
    575         case Int52ToValue:
    576             compileInt52ToValue();
    577586            break;
    578587        case CheckArgumentsNotCreated:
     
    634643    }
    635644
     645    void compileUpsilon()
     646    {
     647        LValue destination = m_phis.get(m_node->phi());
     648       
     649        switch (m_node->child1().useKind()) {
     650        case DoubleRepUse:
     651            m_out.set(lowDouble(m_node->child1()), destination);
     652            break;
     653        case Int32Use:
     654            m_out.set(lowInt32(m_node->child1()), destination);
     655            break;
     656        case Int52RepUse:
     657            m_out.set(lowInt52(m_node->child1()), destination);
     658            break;
     659        case BooleanUse:
     660            m_out.set(lowBoolean(m_node->child1()), destination);
     661            break;
     662        case CellUse:
     663            m_out.set(lowCell(m_node->child1()), destination);
     664            break;
     665        case UntypedUse:
     666            m_out.set(lowJSValue(m_node->child1()), destination);
     667            break;
     668        default:
     669            RELEASE_ASSERT_NOT_REACHED();
     670            break;
     671        }
     672    }
     673   
     674    void compilePhi()
     675    {
     676        LValue source = m_phis.get(m_node);
     677       
     678        switch (m_node->flags() & NodeResultMask) {
     679        case NodeResultDouble:
     680            setDouble(m_out.get(source));
     681            break;
     682        case NodeResultInt32:
     683            setInt32(m_out.get(source));
     684            break;
     685        case NodeResultInt52:
     686            setInt52(m_out.get(source));
     687            break;
     688        case NodeResultBoolean:
     689            setBoolean(m_out.get(source));
     690            break;
     691        case NodeResultJS:
     692            setJSValue(m_out.get(source));
     693            break;
     694        default:
     695            RELEASE_ASSERT_NOT_REACHED();
     696            break;
     697        }
     698    }
     699   
     700    void compileDoubleConstant()
     701    {
     702        setDouble(m_out.constDouble(m_graph.valueOfNumberConstant(m_node)));
     703    }
     704   
     705    void compileInt52Constant()
     706    {
     707        int64_t value = m_graph.valueOfJSConstant(m_node).asMachineInt();
     708       
     709        setInt52(m_out.constInt64(value << JSValue::int52ShiftAmount));
     710        setStrictInt52(m_out.constInt64(value));
     711    }
     712
     713    void compileWeakJSConstant()
     714    {
     715        setJSValue(weakPointer(m_node->weakConstant()));
     716    }
     717   
     718    void compilePhantomArguments()
     719    {
     720        setJSValue(m_out.constInt64(JSValue::encode(JSValue())));
     721    }
     722   
     723    void compileDoubleRep()
     724    {
     725        switch (m_node->child1().useKind()) {
     726        case NumberUse: {
     727            LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
     728            setDouble(jsValueToDouble(m_node->child1(), value));
     729            return;
     730        }
     731           
     732        case Int52RepUse: {
     733            setDouble(strictInt52ToDouble(lowStrictInt52(m_node->child1())));
     734            return;
     735        }
     736           
     737        default:
     738            RELEASE_ASSERT_NOT_REACHED();
     739        }
     740    }
     741   
     742    void compileValueRep()
     743    {
     744        switch (m_node->child1().useKind()) {
     745        case DoubleRepUse: {
     746            setJSValue(boxDouble(lowDouble(m_node->child1())));
     747            return;
     748        }
     749           
     750        case Int52RepUse: {
     751            setJSValue(strictInt52ToJSValue(lowStrictInt52(m_node->child1())));
     752            return;
     753        }
     754           
     755        default:
     756            RELEASE_ASSERT_NOT_REACHED();
     757        }
     758    }
     759   
     760    void compileInt52Rep()
     761    {
     762        setStrictInt52(m_out.signExt(lowInt32(m_node->child1()), m_out.int64));
     763    }
     764   
    636765    void compileValueToInt32()
    637766    {
     
    641770            break;
    642771           
    643         case MachineIntUse:
     772        case Int52RepUse:
    644773            setInt32(m_out.castToInt32(lowStrictInt52(m_node->child1())));
     774            break;
     775           
     776        case DoubleRepUse:
     777            setInt32(doubleToInt32(lowDouble(m_node->child1())));
    645778            break;
    646779           
     
    659792            }
    660793           
    661             value = m_doubleValues.get(m_node->child1().node());
    662             if (isValid(value)) {
    663                 setInt32(doubleToInt32(value.value()));
    664                 break;
    665             }
    666            
    667794            // We'll basically just get here for constants. But it's good to have this
    668795            // catch-all since we often add new representations into the mix.
     
    684811    }
    685812
    686     void compileInt52ToValue()
    687     {
    688         setJSValue(lowJSValue(m_node->child1()));
    689     }
    690 
    691     void compileUpsilon()
    692     {
    693         LValue destination = m_phis.get(m_node->phi());
    694        
    695         switch (m_node->child1().useKind()) {
    696         case NumberUse:
    697             m_out.set(lowDouble(m_node->child1()), destination);
    698             break;
    699         case Int32Use:
    700             m_out.set(lowInt32(m_node->child1()), destination);
    701             break;
    702         case MachineIntUse:
    703             m_out.set(lowInt52(m_node->child1()), destination);
    704             break;
    705         case BooleanUse:
    706             m_out.set(lowBoolean(m_node->child1()), destination);
    707             break;
    708         case CellUse:
    709             m_out.set(lowCell(m_node->child1()), destination);
    710             break;
    711         case UntypedUse:
    712             m_out.set(lowJSValue(m_node->child1()), destination);
    713             break;
    714         default:
    715             RELEASE_ASSERT_NOT_REACHED();
    716             break;
    717         }
    718     }
    719    
    720     void compilePhi()
    721     {
    722         LValue source = m_phis.get(m_node);
    723        
    724         switch (m_node->flags() & NodeResultMask) {
    725         case NodeResultNumber:
    726             setDouble(m_out.get(source));
    727             break;
    728         case NodeResultInt32:
    729             setInt32(m_out.get(source));
    730             break;
    731         case NodeResultInt52:
    732             setInt52(m_out.get(source));
    733             break;
    734         case NodeResultBoolean:
    735             setBoolean(m_out.get(source));
    736             break;
    737         case NodeResultJS:
    738             setJSValue(m_out.get(source));
    739             break;
    740         default:
    741             RELEASE_ASSERT_NOT_REACHED();
    742             break;
    743         }
    744     }
    745 
    746     void compilePhantomArguments()
    747     {
    748         setJSValue(m_out.constInt64(JSValue::encode(JSValue())));
    749     }
    750    
    751     void compileWeakJSConstant()
    752     {
    753         setJSValue(weakPointer(m_node->weakConstant()));
    754     }
    755    
    756813    void compileGetArgument()
    757814    {
     
    9671024        }
    9681025           
    969         case MachineIntUse: {
     1026        case Int52RepUse: {
    9701027            if (!m_state.forNode(m_node->child1()).couldBeType(SpecInt52)
    9711028                && !m_state.forNode(m_node->child2()).couldBeType(SpecInt52)) {
     
    10171074        }
    10181075           
    1019         case NumberUse: {
     1076        case DoubleRepUse: {
    10201077            LValue C1 = lowDouble(m_node->child1());
    10211078            LValue C2 = lowDouble(m_node->child2());
     
    10661123        }
    10671124           
    1068         case MachineIntUse: {
     1125        case Int52RepUse: {
    10691126            Int52Kind kind;
    10701127            LValue left = lowWhicheverInt52(m_node->child1(), kind);
     
    10931150        }
    10941151           
    1095         case NumberUse: {
     1152        case DoubleRepUse: {
    10961153            setDouble(
    10971154                m_out.doubleMul(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
     
    11961253        }
    11971254           
    1198         case NumberUse: {
     1255        case DoubleRepUse: {
    11991256            setDouble(m_out.doubleDiv(
    12001257                lowDouble(m_node->child1()), lowDouble(m_node->child2())));
     
    12941351        }
    12951352           
    1296         case NumberUse: {
     1353        case DoubleRepUse: {
    12971354            setDouble(
    12981355                m_out.doubleRem(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
     
    13221379        }
    13231380           
    1324         case NumberUse: {
     1381        case DoubleRepUse: {
    13251382            LValue left = lowDouble(m_node->child1());
    13261383            LValue right = lowDouble(m_node->child2());
     
    13721429        }
    13731430           
    1374         case NumberUse: {
     1431        case DoubleRepUse: {
    13751432            setDouble(m_out.doubleAbs(lowDouble(m_node->child1())));
    13761433            break;
     
    14191476        }
    14201477           
    1421         case MachineIntUse: {
     1478        case Int52RepUse: {
    14221479            if (!m_state.forNode(m_node->child1()).couldBeType(SpecInt52)) {
    14231480                Int52Kind kind;
     
    14391496        }
    14401497           
    1441         case NumberUse: {
     1498        case DoubleRepUse: {
    14421499            setDouble(m_out.doubleNeg(lowDouble(m_node->child1())));
    14431500            break;
     
    14971554        speculate(Overflow, noValue(), 0, m_out.lessThan(value, m_out.int32Zero));
    14981555        setInt32(value);
    1499     }
    1500    
    1501     void compileInt32ToDouble()
    1502     {
    1503         setDouble(lowDouble(m_node->child1()));
    15041556    }
    15051557   
     
    22142266                    LValue intValue;
    22152267                    switch (child3.useKind()) {
    2216                     case MachineIntUse:
     2268                    case Int52RepUse:
    22172269                    case Int32Use: {
    22182270                        if (child3.useKind() == Int32Use)
     
    22472299                    }
    22482300                       
    2249                     case NumberUse: {
     2301                    case DoubleRepUse: {
    22502302                        LValue doubleValue = lowDouble(child3);
    22512303                       
     
    33293381    {
    33303382        if (m_node->isBinaryUseKind(Int32Use)
    3331             || m_node->isBinaryUseKind(MachineIntUse)
    3332             || m_node->isBinaryUseKind(NumberUse)
     3383            || m_node->isBinaryUseKind(Int52RepUse)
     3384            || m_node->isBinaryUseKind(DoubleRepUse)
    33333385            || m_node->isBinaryUseKind(ObjectUse)
    33343386            || m_node->isBinaryUseKind(BooleanUse)
     
    33723424        }
    33733425       
    3374         if (m_node->isBinaryUseKind(MachineIntUse)) {
     3426        if (m_node->isBinaryUseKind(Int52RepUse)) {
    33753427            Int52Kind kind;
    33763428            LValue left = lowWhicheverInt52(m_node->child1(), kind);
     
    33803432        }
    33813433       
    3382         if (m_node->isBinaryUseKind(NumberUse)) {
     3434        if (m_node->isBinaryUseKind(DoubleRepUse)) {
    33833435            setBoolean(
    33843436                m_out.doubleEqual(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
     
    41244176        }
    41254177       
    4126         if (m_node->isBinaryUseKind(MachineIntUse)) {
     4178        if (m_node->isBinaryUseKind(Int52RepUse)) {
    41274179            Int52Kind kind;
    41284180            LValue left = lowWhicheverInt52(m_node->child1(), kind);
     
    41324184        }
    41334185       
    4134         if (m_node->isBinaryUseKind(NumberUse)) {
     4186        if (m_node->isBinaryUseKind(DoubleRepUse)) {
    41354187            LValue left = lowDouble(m_node->child1());
    41364188            LValue right = lowDouble(m_node->child2());
     
    43894441        case Int32Use:
    43904442            return m_out.notZero32(lowInt32(m_node->child1()));
    4391         case NumberUse:
     4443        case DoubleRepUse:
    43924444            return m_out.doubleNotEqual(lowDouble(edge), m_out.doubleZero);
    43934445        case ObjectOrOtherUse:
     
    47354787   
    47364788    enum Int52Kind { StrictInt52, Int52 };
    4737     LValue lowInt52(Edge edge, Int52Kind kind, OperandSpeculationMode mode = AutomaticOperandSpeculation)
    4738     {
    4739         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == MachineIntUse);
    4740        
    4741         if (edge->hasConstant()) {
    4742             JSValue value = m_graph.valueOfJSConstant(edge.node());
    4743             if (!value.isMachineInt()) {
    4744                 terminate(Uncountable);
    4745                 return m_out.int64Zero;
    4746             }
    4747             int64_t result = value.asMachineInt();
    4748             if (kind == Int52)
    4749                 result <<= JSValue::int52ShiftAmount;
    4750             return m_out.constInt64(result);
    4751         }
     4789    LValue lowInt52(Edge edge, Int52Kind kind)
     4790    {
     4791        RELEASE_ASSERT(edge.useKind() == Int52RepUse);
    47524792       
    47534793        LoweredNodeValue value;
     
    47744814            break;
    47754815        }
    4776        
    4777         value = m_int32Values.get(edge.node());
    4778         if (isValid(value)) {
    4779             return setInt52WithStrictValue(
    4780                 edge.node(), m_out.signExt(value.value(), m_out.int64), kind);
    4781         }
    4782        
    4783         RELEASE_ASSERT(!(m_state.forNode(edge).m_type & SpecInt52));
    4784        
    4785         value = m_jsValueValues.get(edge.node());
    4786         if (isValid(value)) {
    4787             LValue boxedResult = value.value();
    4788             FTL_TYPE_CHECK(
    4789                 jsValueValue(boxedResult), edge, SpecMachineInt, isNotInt32(boxedResult));
    4790             return setInt52WithStrictValue(
    4791                 edge.node(), m_out.signExt(unboxInt32(boxedResult), m_out.int64), kind);
    4792         }
    4793        
    4794         RELEASE_ASSERT(!(m_state.forNode(edge).m_type & SpecMachineInt));
     4816
     4817        RELEASE_ASSERT(!m_state.forNode(edge).m_type);
    47954818        terminate(Uncountable);
    47964819        return m_out.int64Zero;
    47974820    }
    47984821   
    4799     LValue lowInt52(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
    4800     {
    4801         return lowInt52(edge, Int52, mode);
    4802     }
    4803    
    4804     LValue lowStrictInt52(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
    4805     {
    4806         return lowInt52(edge, StrictInt52, mode);
     4822    LValue lowInt52(Edge edge)
     4823    {
     4824        return lowInt52(edge, Int52);
     4825    }
     4826   
     4827    LValue lowStrictInt52(Edge edge)
     4828    {
     4829        return lowInt52(edge, StrictInt52);
    48074830    }
    48084831   
     
    48314854    }
    48324855   
    4833     LValue lowWhicheverInt52(Edge edge, Int52Kind& kind, OperandSpeculationMode mode = AutomaticOperandSpeculation)
     4856    LValue lowWhicheverInt52(Edge edge, Int52Kind& kind)
    48344857    {
    48354858        kind = bestInt52Kind(edge);
    4836         return lowInt52(edge, kind, mode);
     4859        return lowInt52(edge, kind);
    48374860    }
    48384861   
     
    49324955    }
    49334956   
    4934     LValue lowDouble(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
    4935     {
    4936         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || isDouble(edge.useKind()));
    4937        
    4938         if (edge->hasConstant()) {
    4939             JSValue value = m_graph.valueOfJSConstant(edge.node());
    4940             if (!value.isNumber()) {
    4941                 terminate(Uncountable);
    4942                 return m_out.doubleZero;
    4943             }
    4944             return m_out.constDouble(value.asNumber());
    4945         }
     4957    LValue lowDouble(Edge edge)
     4958    {
     4959        RELEASE_ASSERT(isDouble(edge.useKind()));
    49464960       
    49474961        LoweredNodeValue value = m_doubleValues.get(edge.node());
     
    49494963            return value.value();
    49504964       
    4951         value = m_int32Values.get(edge.node());
    4952         if (isValid(value)) {
    4953             LValue result = m_out.intToDouble(value.value());
    4954             setDouble(edge.node(), result);
    4955             return result;
    4956         }
    4957        
    4958         value = m_strictInt52Values.get(edge.node());
    4959         if (isValid(value))
    4960             return strictInt52ToDouble(edge, value.value());
    4961        
    4962         value = m_int52Values.get(edge.node());
    4963         if (isValid(value))
    4964             return strictInt52ToDouble(edge, int52ToStrictInt52(value.value()));
    4965        
    4966         value = m_jsValueValues.get(edge.node());
    4967         if (isValid(value)) {
    4968             LValue boxedResult = value.value();
    4969            
    4970             LBasicBlock intCase = FTL_NEW_BLOCK(m_out, ("Double unboxing int case"));
    4971             LBasicBlock doubleCase = FTL_NEW_BLOCK(m_out, ("Double unboxing double case"));
    4972             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("Double unboxing continuation"));
    4973            
    4974             m_out.branch(isNotInt32(boxedResult), unsure(doubleCase), unsure(intCase));
    4975            
    4976             LBasicBlock lastNext = m_out.appendTo(intCase, doubleCase);
    4977            
    4978             ValueFromBlock intToDouble = m_out.anchor(
    4979                 m_out.intToDouble(unboxInt32(boxedResult)));
    4980             m_out.jump(continuation);
    4981            
    4982             m_out.appendTo(doubleCase, continuation);
    4983            
    4984             FTL_TYPE_CHECK(
    4985                 jsValueValue(boxedResult), edge, SpecFullNumber, isCellOrMisc(boxedResult));
    4986            
    4987             ValueFromBlock unboxedDouble = m_out.anchor(unboxDouble(boxedResult));
    4988             m_out.jump(continuation);
    4989            
    4990             m_out.appendTo(continuation, lastNext);
    4991            
    4992             LValue result = m_out.phi(m_out.doubleType, intToDouble, unboxedDouble);
    4993            
    4994             setDouble(edge.node(), result);
    4995             return result;
    4996         }
    4997        
    4998         RELEASE_ASSERT(!(m_state.forNode(edge).m_type & SpecFullNumber));
     4965        RELEASE_ASSERT(!m_state.forNode(edge).m_type);
    49994966        terminate(Uncountable);
    50004967        return m_out.doubleZero;
     
    50044971    {
    50054972        ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == UntypedUse);
     4973        RELEASE_ASSERT(!isDouble(edge.useKind()));
     4974        RELEASE_ASSERT(edge.useKind() != Int52RepUse);
    50064975       
    50074976        if (edge->hasConstant())
     
    50194988        }
    50204989       
    5021         value = m_strictInt52Values.get(edge.node());
    5022         if (isValid(value))
    5023             return strictInt52ToJSValue(value.value());
    5024        
    5025         value = m_int52Values.get(edge.node());
    5026         if (isValid(value))
    5027             return strictInt52ToJSValue(int52ToStrictInt52(value.value()));
    5028        
    50294990        value = m_booleanValues.get(edge.node());
    50304991        if (isValid(value)) {
    50314992            LValue result = boxBoolean(value.value());
    5032             setJSValue(edge.node(), result);
    5033             return result;
    5034         }
    5035        
    5036         value = m_doubleValues.get(edge.node());
    5037         if (isValid(value)) {
    5038             LValue result = boxDouble(value.value());
    50394993            setJSValue(edge.node(), result);
    50404994            return result;
     
    50665020    }
    50675021   
    5068     LValue strictInt52ToDouble(Edge edge, LValue value)
    5069     {
    5070         LValue result = m_out.intToDouble(value);
    5071         setDouble(edge.node(), result);
    5072         return result;
     5022    LValue strictInt52ToDouble(LValue value)
     5023    {
     5024        return m_out.intToDouble(value);
    50735025    }
    50745026   
     
    51005052    }
    51015053   
    5102     LValue setInt52WithStrictValue(Node* node, LValue value, Int52Kind kind)
    5103     {
    5104         switch (kind) {
    5105         case StrictInt52:
    5106             setStrictInt52(node, value);
    5107             return value;
    5108            
    5109         case Int52:
    5110             value = strictInt52ToInt52(value);
    5111             setInt52(node, value);
    5112             return value;
    5113         }
    5114        
    5115         RELEASE_ASSERT_NOT_REACHED();
    5116         return 0;
    5117     }
    5118 
    51195054    LValue strictInt52ToInt52(LValue value)
    51205055    {
     
    51485083        return m_out.testNonZero64(jsValue, m_tagTypeNumber);
    51495084    }
     5085   
    51505086    LValue unboxDouble(LValue jsValue)
    51515087    {
     
    51555091    {
    51565092        return m_out.sub(m_out.bitCast(doubleValue, m_out.int64), m_tagTypeNumber);
     5093    }
     5094    LValue jsValueToDouble(Edge edge, LValue boxedValue)
     5095    {
     5096        LBasicBlock intCase = FTL_NEW_BLOCK(m_out, ("DoubleRep unboxing int case"));
     5097        LBasicBlock doubleCase = FTL_NEW_BLOCK(m_out, ("DoubleRep unboxing double case"));
     5098        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("DoubleRep unboxing continuation"));
     5099           
     5100        LValue isNotInt32;
     5101        if (!m_interpreter.needsTypeCheck(edge, SpecInt32))
     5102            isNotInt32 = m_out.booleanFalse;
     5103        else if (!m_interpreter.needsTypeCheck(edge, ~SpecInt32))
     5104            isNotInt32 = m_out.booleanTrue;
     5105        else
     5106            isNotInt32 = this->isNotInt32(boxedValue);
     5107        m_out.branch(isNotInt32, unsure(doubleCase), unsure(intCase));
     5108           
     5109        LBasicBlock lastNext = m_out.appendTo(intCase, doubleCase);
     5110           
     5111        ValueFromBlock intToDouble = m_out.anchor(
     5112            m_out.intToDouble(unboxInt32(boxedValue)));
     5113        m_out.jump(continuation);
     5114           
     5115        m_out.appendTo(doubleCase, continuation);
     5116           
     5117        FTL_TYPE_CHECK(
     5118            jsValueValue(boxedValue), edge, SpecBytecodeNumber, isCellOrMisc(boxedValue));
     5119           
     5120        ValueFromBlock unboxedDouble = m_out.anchor(unboxDouble(boxedValue));
     5121        m_out.jump(continuation);
     5122           
     5123        m_out.appendTo(continuation, lastNext);
     5124           
     5125        return m_out.phi(m_out.doubleType, intToDouble, unboxedDouble);
    51575126    }
    51585127   
     
    52275196            break;
    52285197        case KnownInt32Use:
    5229         case KnownNumberUse:
    52305198        case KnownStringUse:
     5199        case DoubleRepUse:
     5200        case Int52RepUse:
    52315201            ASSERT(!m_interpreter.needsTypeCheck(edge));
    52325202            break;
     
    52615231            speculateStringOrStringObject(edge);
    52625232            break;
    5263         case RealNumberUse:
    5264             speculateRealNumber(edge);
    5265             break;
    52665233        case NumberUse:
    52675234            speculateNumber(edge);
    52685235            break;
    5269         case MachineIntUse:
    5270             speculateMachineInt(edge);
     5236        case DoubleRepRealUse:
     5237            speculateDoubleReal(edge);
    52715238            break;
    52725239        case BooleanUse:
     
    55305497    void speculateNumber(Edge edge)
    55315498    {
     5499        LValue value = lowJSValue(edge, ManualOperandSpeculation);
     5500        FTL_TYPE_CHECK(jsValueValue(value), edge, SpecBytecodeNumber, isNotNumber(value));
     5501    }
     5502   
     5503    void speculateDoubleReal(Edge edge)
     5504    {
    55325505        // Do an early return here because lowDouble() can create a lot of control flow.
    55335506        if (!m_interpreter.needsTypeCheck(edge))
    55345507            return;
    55355508       
    5536         lowDouble(edge);
    5537     }
    5538    
    5539     void speculateRealNumber(Edge edge)
    5540     {
    5541         // Do an early return here because lowDouble() can create a lot of control flow.
    5542         if (!m_interpreter.needsTypeCheck(edge))
    5543             return;
    5544        
    55455509        LValue value = lowDouble(edge);
    55465510        FTL_TYPE_CHECK(
    5547             doubleValue(value), edge, SpecFullRealNumber,
     5511            doubleValue(value), edge, SpecDoubleReal,
    55485512            m_out.doubleNotEqualOrUnordered(value, value));
    5549     }
    5550    
    5551     void speculateMachineInt(Edge edge)
    5552     {
    5553         if (!m_interpreter.needsTypeCheck(edge))
    5554             return;
    5555        
    5556         Int52Kind kind;
    5557         lowWhicheverInt52(edge, kind);
    55585513    }
    55595514   
  • trunk/Source/JavaScriptCore/ftl/FTLValueFormat.cpp

    r160587 r167325  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    7272        jit.moveDoubleTo64(FPRInfo::fpRegT0, scratch1);
    7373        jit.move64ToDouble(value, FPRInfo::fpRegT0);
     74        jit.sanitizeDouble(FPRInfo::fpRegT0);
    7475        jit.boxDouble(FPRInfo::fpRegT0, value);
    7576        jit.move64ToDouble(scratch1, FPRInfo::fpRegT0);
  • trunk/Source/JavaScriptCore/jit/AssemblyHelpers.cpp

    r163844 r167325  
    11/*
    2  * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    5555}
    5656
     57void AssemblyHelpers::sanitizeDouble(FPRReg fpr)
     58{
     59    MacroAssembler::Jump notNaN = branchDouble(DoubleEqual, fpr, fpr);
     60    static const double NaN = QNaN;
     61    loadDouble(&NaN, fpr);
     62    notNaN.link(this);
     63}
     64
    5765#if ENABLE(SAMPLING_FLAGS)
    5866void AssemblyHelpers::setSamplingFlag(int32_t flag)
  • trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h

    r166908 r167325  
    11/*
    2  * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    418418    void jitAssertArgumentCountSane() { }
    419419#endif
     420   
     421    void sanitizeDouble(FPRReg);
    420422
    421423    // These methods convert between doubles, and doubles boxed and JSValues.
     
    434436        move64ToDouble(gpr, fpr);
    435437        return fpr;
     438    }
     439   
     440    void boxDouble(FPRReg fpr, JSValueRegs regs)
     441    {
     442        boxDouble(fpr, regs.gpr());
    436443    }
    437444   
     
    468475        moveIntsToDouble(payloadGPR, tagGPR, fpr, scratchFPR);
    469476    }
     477   
     478    void boxDouble(FPRReg fpr, JSValueRegs regs)
     479    {
     480        boxDouble(fpr, regs.tagGPR(), regs.payloadGPR());
     481    }
    470482#endif
    471483   
Note: See TracChangeset for help on using the changeset viewer.