Changeset 156019 in webkit


Ignore:
Timestamp:
Sep 17, 2013 6:31:04 PM (11 years ago)
Author:
fpizlo@apple.com
Message:

DFG should support Int52 for local variables
https://bugs.webkit.org/show_bug.cgi?id=121064

Source/JavaScriptCore:

Reviewed by Oliver Hunt.

This adds Int52 support for local variables to the DFG and FTL. It's a speed-up on
programs that have local int32 overflows but where a larger int representation can
prevent us from having to convert all the way up to double.

It's a small speed-up for now. But we're just supporting Int52 for a handful of
operations (add, sub, mul, neg, compare, bitops, typed array access) and this lays
the groundwork for adding Int52 to JSValue, which will probably be a bigger
speed-up.

The basic approach is:

  • We have a notion of Int52 in our typesystem. Int52 doesn't belong to BytecodeTop or HeapTop - i.e. it doesn't arise from JSValues.


  • DFG treats Int52 as being part of its FullTop and will treat it as being a subtype of double unless instructed otherwise.


  • Prediction propagator creates Int52s whenever we have a node going doubly but due to large values rather than fractional values, and that node is known to be able to produce Int52 natively in the DFG backend.


  • Fixup phase converts edges to MachineIntUses in nodes that are known to be able to deal with Int52, and where we have a subtype of Int32|Int52 as the predicted input.


  • The DFG backend and FTL LLVM IR lowering have two notions of Int52s - ones that are left-shifted by 16 (great for overflow checks) and ones that are sign-extended. Both backends know how to convert between Int52s and the other representations.
  • assembler/MacroAssemblerX86_64.h:

(JSC::MacroAssemblerX86_64::rshift64):
(JSC::MacroAssemblerX86_64::mul64):
(JSC::MacroAssemblerX86_64::branchMul64):
(JSC::MacroAssemblerX86_64::branchNeg64):
(JSC::MacroAssemblerX86_64::convertInt64ToDouble):

  • assembler/X86Assembler.h:

(JSC::X86Assembler::imulq_rr):
(JSC::X86Assembler::cvtsi2sdq_rr):

  • bytecode/DataFormat.h:

(JSC::dataFormatToString):

  • bytecode/OperandsInlines.h:

(JSC::::dumpInContext):

  • bytecode/SpeculatedType.cpp:

(JSC::dumpSpeculation):
(JSC::speculationToAbbreviatedString):
(JSC::speculationFromValue):

  • bytecode/SpeculatedType.h:

(JSC::isInt32SpeculationForArithmetic):
(JSC::isMachineIntSpeculationForArithmetic):
(JSC::isBytecodeRealNumberSpeculation):
(JSC::isFullRealNumberSpeculation):
(JSC::isBytecodeNumberSpeculation):
(JSC::isFullNumberSpeculation):
(JSC::isBytecodeNumberSpeculationExpectingDefined):
(JSC::isFullNumberSpeculationExpectingDefined):

  • bytecode/ValueRecovery.h:

(JSC::ValueRecovery::alreadyInJSStackAsUnboxedInt52):
(JSC::ValueRecovery::inGPR):
(JSC::ValueRecovery::displacedInJSStack):
(JSC::ValueRecovery::isAlreadyInJSStack):
(JSC::ValueRecovery::gpr):
(JSC::ValueRecovery::virtualRegister):
(JSC::ValueRecovery::dumpInContext):

  • dfg/DFGAbstractInterpreter.h:

(JSC::DFG::AbstractInterpreter::needsTypeCheck):
(JSC::DFG::AbstractInterpreter::filterByType):

  • dfg/DFGAbstractInterpreterInlines.h:

(JSC::DFG::::executeEffects):

  • dfg/DFGAbstractValue.cpp:

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

  • dfg/DFGAbstractValue.h:

(JSC::DFG::AbstractValue::couldBeType):
(JSC::DFG::AbstractValue::isType):
(JSC::DFG::AbstractValue::checkConsistency):
(JSC::DFG::AbstractValue::validateType):

  • dfg/DFGArrayMode.cpp:

(JSC::DFG::ArrayMode::refine):

  • dfg/DFGAssemblyHelpers.h:

(JSC::DFG::AssemblyHelpers::boxInt52):

  • dfg/DFGCSEPhase.cpp:

(JSC::DFG::CSEPhase::pureCSE):
(JSC::DFG::CSEPhase::getByValLoadElimination):
(JSC::DFG::CSEPhase::performNodeCSE):

  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

  • dfg/DFGCommon.h:

(JSC::DFG::enableInt52):

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::run):
(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::fixupSetLocalsInBlock):
(JSC::DFG::FixupPhase::fixupUntypedSetLocalsInBlock):
(JSC::DFG::FixupPhase::observeUseKindOnNode):
(JSC::DFG::FixupPhase::fixEdge):
(JSC::DFG::FixupPhase::injectInt32ToDoubleNode):
(JSC::DFG::FixupPhase::attemptToMakeIntegerAdd):

  • dfg/DFGFlushFormat.cpp:

(WTF::printInternal):

  • dfg/DFGFlushFormat.h:

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

  • dfg/DFGGenerationInfo.h:

(JSC::DFG::GenerationInfo::initInt52):
(JSC::DFG::GenerationInfo::initStrictInt52):
(JSC::DFG::GenerationInfo::isFormat):
(JSC::DFG::GenerationInfo::isInt52):
(JSC::DFG::GenerationInfo::isStrictInt52):
(JSC::DFG::GenerationInfo::fillInt52):
(JSC::DFG::GenerationInfo::fillStrictInt52):

  • dfg/DFGGraph.cpp:

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

  • dfg/DFGGraph.h:

(JSC::DFG::Graph::addShouldSpeculateMachineInt):
(JSC::DFG::Graph::mulShouldSpeculateMachineInt):
(JSC::DFG::Graph::negateShouldSpeculateMachineInt):

  • dfg/DFGInPlaceAbstractState.cpp:

(JSC::DFG::InPlaceAbstractState::mergeStateAtTail):

  • dfg/DFGJITCode.cpp:

(JSC::DFG::JITCode::reconstruct):

  • dfg/DFGMinifiedNode.h:

(JSC::DFG::belongsInMinifiedGraph):
(JSC::DFG::MinifiedNode::hasChild):

  • dfg/DFGNode.h:

(JSC::DFG::Node::shouldSpeculateNumber):
(JSC::DFG::Node::shouldSpeculateNumberExpectingDefined):

  • dfg/DFGNodeFlags.h:
  • dfg/DFGNodeType.h:

(JSC::DFG::forwardRewiringSelectionScore):

  • dfg/DFGOSRExitCompiler.cpp:
  • dfg/DFGOSRExitCompiler64.cpp:

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

  • dfg/DFGPredictionPropagationPhase.cpp:

(JSC::DFG::PredictionPropagationPhase::speculatedDoubleTypeForPrediction):
(JSC::DFG::PredictionPropagationPhase::propagate):
(JSC::DFG::PredictionPropagationPhase::doDoubleVoting):

  • dfg/DFGSafeToExecute.h:

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

  • dfg/DFGSilentRegisterSavePlan.h:
  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::silentSavePlanForGPR):
(JSC::DFG::SpeculativeJIT::silentFill):
(JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
(JSC::DFG::SpeculativeJIT::compileInlineStart):
(JSC::DFG::SpeculativeJIT::compileDoublePutByVal):
(JSC::DFG::SpeculativeJIT::compileValueToInt32):
(JSC::DFG::SpeculativeJIT::compileInt32ToDouble):
(JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray):
(JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
(JSC::DFG::SpeculativeJIT::compileAdd):
(JSC::DFG::SpeculativeJIT::compileArithSub):
(JSC::DFG::SpeculativeJIT::compileArithNegate):
(JSC::DFG::SpeculativeJIT::compileArithMul):
(JSC::DFG::SpeculativeJIT::compare):
(JSC::DFG::SpeculativeJIT::compileStrictEq):
(JSC::DFG::SpeculativeJIT::speculateMachineInt):
(JSC::DFG::SpeculativeJIT::speculateNumber):
(JSC::DFG::SpeculativeJIT::speculateRealNumber):
(JSC::DFG::SpeculativeJIT::speculate):

  • dfg/DFGSpeculativeJIT.h:

(JSC::DFG::SpeculativeJIT::canReuse):
(JSC::DFG::SpeculativeJIT::isFilled):
(JSC::DFG::SpeculativeJIT::isFilledDouble):
(JSC::DFG::SpeculativeJIT::use):
(JSC::DFG::SpeculativeJIT::isKnownInteger):
(JSC::DFG::SpeculativeJIT::isKnownCell):
(JSC::DFG::SpeculativeJIT::isKnownNotNumber):
(JSC::DFG::SpeculativeJIT::int52Result):
(JSC::DFG::SpeculativeJIT::strictInt52Result):
(JSC::DFG::SpeculativeJIT::initConstantInfo):
(JSC::DFG::SpeculativeJIT::isInteger):
(JSC::DFG::SpeculativeJIT::betterUseStrictInt52):
(JSC::DFG::SpeculativeJIT::generationInfo):
(JSC::DFG::SpeculateInt52Operand::SpeculateInt52Operand):
(JSC::DFG::SpeculateInt52Operand::~SpeculateInt52Operand):
(JSC::DFG::SpeculateInt52Operand::edge):
(JSC::DFG::SpeculateInt52Operand::node):
(JSC::DFG::SpeculateInt52Operand::gpr):
(JSC::DFG::SpeculateInt52Operand::use):
(JSC::DFG::SpeculateStrictInt52Operand::SpeculateStrictInt52Operand):
(JSC::DFG::SpeculateStrictInt52Operand::~SpeculateStrictInt52Operand):
(JSC::DFG::SpeculateStrictInt52Operand::edge):
(JSC::DFG::SpeculateStrictInt52Operand::node):
(JSC::DFG::SpeculateStrictInt52Operand::gpr):
(JSC::DFG::SpeculateStrictInt52Operand::use):
(JSC::DFG::SpeculateWhicheverInt52Operand::SpeculateWhicheverInt52Operand):
(JSC::DFG::SpeculateWhicheverInt52Operand::~SpeculateWhicheverInt52Operand):
(JSC::DFG::SpeculateWhicheverInt52Operand::edge):
(JSC::DFG::SpeculateWhicheverInt52Operand::node):
(JSC::DFG::SpeculateWhicheverInt52Operand::gpr):
(JSC::DFG::SpeculateWhicheverInt52Operand::use):
(JSC::DFG::SpeculateWhicheverInt52Operand::format):

  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::boxInt52):
(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::compileInt52Compare):
(JSC::DFG::SpeculativeJIT::compilePeepHoleInt52Branch):
(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGUseKind.cpp:

(WTF::printInternal):

  • dfg/DFGUseKind.h:

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

  • dfg/DFGValueSource.cpp:

(JSC::DFG::ValueSource::dump):

  • dfg/DFGValueSource.h:

(JSC::DFG::dataFormatToValueSourceKind):
(JSC::DFG::valueSourceKindToDataFormat):
(JSC::DFG::ValueSource::forFlushFormat):
(JSC::DFG::ValueSource::valueRecovery):

  • dfg/DFGVariableAccessData.h:

(JSC::DFG::VariableAccessData::shouldUseDoubleFormatAccordingToVote):
(JSC::DFG::VariableAccessData::flushFormat):

  • ftl/FTLCArgumentGetter.cpp:

(JSC::FTL::CArgumentGetter::loadNextAndBox):

  • ftl/FTLCArgumentGetter.h:
  • ftl/FTLCapabilities.cpp:

(JSC::FTL::canCompile):

  • ftl/FTLExitValue.cpp:

(JSC::FTL::ExitValue::dumpInContext):

  • ftl/FTLExitValue.h:

(JSC::FTL::ExitValue::inJSStackAsInt52):

  • ftl/FTLIntrinsicRepository.h:
  • ftl/FTLLowerDFGToLLVM.cpp:

(JSC::FTL::LowerDFGToLLVM::createPhiVariables):
(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compileUpsilon):
(JSC::FTL::LowerDFGToLLVM::compilePhi):
(JSC::FTL::LowerDFGToLLVM::compileSetLocal):
(JSC::FTL::LowerDFGToLLVM::compileAdd):
(JSC::FTL::LowerDFGToLLVM::compileArithSub):
(JSC::FTL::LowerDFGToLLVM::compileArithMul):
(JSC::FTL::LowerDFGToLLVM::compileArithNegate):
(JSC::FTL::LowerDFGToLLVM::compilePutByVal):
(JSC::FTL::LowerDFGToLLVM::compileCompareEq):
(JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
(JSC::FTL::LowerDFGToLLVM::compileCompareLess):
(JSC::FTL::LowerDFGToLLVM::compileCompareLessEq):
(JSC::FTL::LowerDFGToLLVM::compileCompareGreater):
(JSC::FTL::LowerDFGToLLVM::compileCompareGreaterEq):
(JSC::FTL::LowerDFGToLLVM::lowInt32):
(JSC::FTL::LowerDFGToLLVM::lowInt52):
(JSC::FTL::LowerDFGToLLVM::lowStrictInt52):
(JSC::FTL::LowerDFGToLLVM::betterUseStrictInt52):
(JSC::FTL::LowerDFGToLLVM::bestInt52Kind):
(JSC::FTL::LowerDFGToLLVM::opposite):
(JSC::FTL::LowerDFGToLLVM::Int52s::operator[]):
(JSC::FTL::LowerDFGToLLVM::lowWhicheverInt52):
(JSC::FTL::LowerDFGToLLVM::lowWhicheverInt52s):
(JSC::FTL::LowerDFGToLLVM::lowOpposingInt52s):
(JSC::FTL::LowerDFGToLLVM::lowCell):
(JSC::FTL::LowerDFGToLLVM::lowBoolean):
(JSC::FTL::LowerDFGToLLVM::lowDouble):
(JSC::FTL::LowerDFGToLLVM::lowJSValue):
(JSC::FTL::LowerDFGToLLVM::strictInt52ToInt32):
(JSC::FTL::LowerDFGToLLVM::strictInt52ToDouble):
(JSC::FTL::LowerDFGToLLVM::strictInt52ToJSValue):
(JSC::FTL::LowerDFGToLLVM::setInt52WithStrictValue):
(JSC::FTL::LowerDFGToLLVM::strictInt52ToInt52):
(JSC::FTL::LowerDFGToLLVM::int52ToStrictInt52):
(JSC::FTL::LowerDFGToLLVM::speculateRealNumber):
(JSC::FTL::LowerDFGToLLVM::initializeOSRExitStateForBlock):
(JSC::FTL::LowerDFGToLLVM::emitOSRExitCall):
(JSC::FTL::LowerDFGToLLVM::addExitArgumentForNode):
(JSC::FTL::LowerDFGToLLVM::setInt52):
(JSC::FTL::LowerDFGToLLVM::setStrictInt52):

  • ftl/FTLOSRExitCompiler.cpp:

(JSC::FTL::compileStub):

  • ftl/FTLOutput.h:

(JSC::FTL::Output::addWithOverflow64):
(JSC::FTL::Output::subWithOverflow64):
(JSC::FTL::Output::mulWithOverflow64):

  • ftl/FTLValueFormat.cpp:

(WTF::printInternal):

  • ftl/FTLValueFormat.h:
  • ftl/FTLValueSource.cpp:

(JSC::FTL::ValueSource::dump):

  • ftl/FTLValueSource.h:
  • interpreter/Register.h:

(JSC::Register::unboxedInt52):

  • runtime/Arguments.cpp:

(JSC::Arguments::tearOffForInlineCallFrame):

  • runtime/IndexingType.cpp:

(JSC::leastUpperBoundOfIndexingTypeAndType):

  • runtime/JSCJSValue.h:
  • runtime/JSCJSValueInlines.h:

(JSC::JSValue::isMachineInt):
(JSC::JSValue::asMachineInt):

Source/WTF:

Reviewed by Oliver Hunt.

  • wtf/PrintStream.h:

(WTF::ValueIgnoringContext::ValueIgnoringContext):
(WTF::ValueIgnoringContext::dump):
(WTF::ignoringContext):

Tools:

Reviewed by Oliver Hunt.

  • Scripts/run-jsc-stress-tests:

LayoutTests:

Reviewed by Oliver Hunt.

  • js/regress/large-int-captured-expected.txt: Added.
  • js/regress/large-int-captured.html: Added.
  • js/regress/large-int-expected.txt: Added.
  • js/regress/large-int-neg-expected.txt: Added.
  • js/regress/large-int-neg.html: Added.
  • js/regress/large-int.html: Added.
  • js/regress/marsaglia-larger-ints-expected.txt: Added.
  • js/regress/marsaglia-larger-ints.html: Added.
  • js/regress/script-tests/large-int-captured.js: Added.

(.bar):
(foo):

  • js/regress/script-tests/large-int-neg.js: Added.

(foo):

  • js/regress/script-tests/large-int.js: Added.

(foo):

  • js/regress/script-tests/marsaglia-larger-ints.js: Added.

(uint):
(marsaglia):

Location:
trunk
Files:
12 added
69 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r156013 r156019  
     12013-09-17  Filip Pizlo  <fpizlo@apple.com>
     2
     3        DFG should support Int52 for local variables
     4        https://bugs.webkit.org/show_bug.cgi?id=121064
     5
     6        Reviewed by Oliver Hunt.
     7
     8        * js/regress/large-int-captured-expected.txt: Added.
     9        * js/regress/large-int-captured.html: Added.
     10        * js/regress/large-int-expected.txt: Added.
     11        * js/regress/large-int-neg-expected.txt: Added.
     12        * js/regress/large-int-neg.html: Added.
     13        * js/regress/large-int.html: Added.
     14        * js/regress/marsaglia-larger-ints-expected.txt: Added.
     15        * js/regress/marsaglia-larger-ints.html: Added.
     16        * js/regress/script-tests/large-int-captured.js: Added.
     17        (.bar):
     18        (foo):
     19        * js/regress/script-tests/large-int-neg.js: Added.
     20        (foo):
     21        * js/regress/script-tests/large-int.js: Added.
     22        (foo):
     23        * js/regress/script-tests/marsaglia-larger-ints.js: Added.
     24        (uint):
     25        (marsaglia):
     26
    1272013-09-17  Alexey Proskuryakov  <ap@apple.com>
    228
  • trunk/Source/JavaScriptCore/ChangeLog

    r156017 r156019  
     12013-09-16  Filip Pizlo  <fpizlo@apple.com>
     2
     3        DFG should support Int52 for local variables
     4        https://bugs.webkit.org/show_bug.cgi?id=121064
     5
     6        Reviewed by Oliver Hunt.
     7       
     8        This adds Int52 support for local variables to the DFG and FTL. It's a speed-up on
     9        programs that have local int32 overflows but where a larger int representation can
     10        prevent us from having to convert all the way up to double.
     11       
     12        It's a small speed-up for now. But we're just supporting Int52 for a handful of
     13        operations (add, sub, mul, neg, compare, bitops, typed array access) and this lays
     14        the groundwork for adding Int52 to JSValue, which will probably be a bigger
     15        speed-up.
     16       
     17        The basic approach is:
     18       
     19        - We have a notion of Int52 in our typesystem. Int52 doesn't belong to BytecodeTop
     20          or HeapTop - i.e. it doesn't arise from JSValues.
     21       
     22        - DFG treats Int52 as being part of its FullTop and will treat it as being a
     23          subtype of double unless instructed otherwise.
     24       
     25        - Prediction propagator creates Int52s whenever we have a node going doubly but due
     26          to large values rather than fractional values, and that node is known to be able
     27          to produce Int52 natively in the DFG backend.
     28       
     29        - Fixup phase converts edges to MachineIntUses in nodes that are known to be able
     30          to deal with Int52, and where we have a subtype of Int32|Int52 as the predicted
     31          input.
     32       
     33        - The DFG backend and FTL LLVM IR lowering have two notions of Int52s - ones that
     34          are left-shifted by 16 (great for overflow checks) and ones that are
     35          sign-extended. Both backends know how to convert between Int52s and the other
     36          representations.
     37
     38        * assembler/MacroAssemblerX86_64.h:
     39        (JSC::MacroAssemblerX86_64::rshift64):
     40        (JSC::MacroAssemblerX86_64::mul64):
     41        (JSC::MacroAssemblerX86_64::branchMul64):
     42        (JSC::MacroAssemblerX86_64::branchNeg64):
     43        (JSC::MacroAssemblerX86_64::convertInt64ToDouble):
     44        * assembler/X86Assembler.h:
     45        (JSC::X86Assembler::imulq_rr):
     46        (JSC::X86Assembler::cvtsi2sdq_rr):
     47        * bytecode/DataFormat.h:
     48        (JSC::dataFormatToString):
     49        * bytecode/OperandsInlines.h:
     50        (JSC::::dumpInContext):
     51        * bytecode/SpeculatedType.cpp:
     52        (JSC::dumpSpeculation):
     53        (JSC::speculationToAbbreviatedString):
     54        (JSC::speculationFromValue):
     55        * bytecode/SpeculatedType.h:
     56        (JSC::isInt32SpeculationForArithmetic):
     57        (JSC::isMachineIntSpeculationForArithmetic):
     58        (JSC::isBytecodeRealNumberSpeculation):
     59        (JSC::isFullRealNumberSpeculation):
     60        (JSC::isBytecodeNumberSpeculation):
     61        (JSC::isFullNumberSpeculation):
     62        (JSC::isBytecodeNumberSpeculationExpectingDefined):
     63        (JSC::isFullNumberSpeculationExpectingDefined):
     64        * bytecode/ValueRecovery.h:
     65        (JSC::ValueRecovery::alreadyInJSStackAsUnboxedInt52):
     66        (JSC::ValueRecovery::inGPR):
     67        (JSC::ValueRecovery::displacedInJSStack):
     68        (JSC::ValueRecovery::isAlreadyInJSStack):
     69        (JSC::ValueRecovery::gpr):
     70        (JSC::ValueRecovery::virtualRegister):
     71        (JSC::ValueRecovery::dumpInContext):
     72        * dfg/DFGAbstractInterpreter.h:
     73        (JSC::DFG::AbstractInterpreter::needsTypeCheck):
     74        (JSC::DFG::AbstractInterpreter::filterByType):
     75        * dfg/DFGAbstractInterpreterInlines.h:
     76        (JSC::DFG::::executeEffects):
     77        * dfg/DFGAbstractValue.cpp:
     78        (JSC::DFG::AbstractValue::set):
     79        (JSC::DFG::AbstractValue::checkConsistency):
     80        * dfg/DFGAbstractValue.h:
     81        (JSC::DFG::AbstractValue::couldBeType):
     82        (JSC::DFG::AbstractValue::isType):
     83        (JSC::DFG::AbstractValue::checkConsistency):
     84        (JSC::DFG::AbstractValue::validateType):
     85        * dfg/DFGArrayMode.cpp:
     86        (JSC::DFG::ArrayMode::refine):
     87        * dfg/DFGAssemblyHelpers.h:
     88        (JSC::DFG::AssemblyHelpers::boxInt52):
     89        * dfg/DFGCSEPhase.cpp:
     90        (JSC::DFG::CSEPhase::pureCSE):
     91        (JSC::DFG::CSEPhase::getByValLoadElimination):
     92        (JSC::DFG::CSEPhase::performNodeCSE):
     93        * dfg/DFGClobberize.h:
     94        (JSC::DFG::clobberize):
     95        * dfg/DFGCommon.h:
     96        (JSC::DFG::enableInt52):
     97        * dfg/DFGFixupPhase.cpp:
     98        (JSC::DFG::FixupPhase::run):
     99        (JSC::DFG::FixupPhase::fixupNode):
     100        (JSC::DFG::FixupPhase::fixupSetLocalsInBlock):
     101        (JSC::DFG::FixupPhase::fixupUntypedSetLocalsInBlock):
     102        (JSC::DFG::FixupPhase::observeUseKindOnNode):
     103        (JSC::DFG::FixupPhase::fixEdge):
     104        (JSC::DFG::FixupPhase::injectInt32ToDoubleNode):
     105        (JSC::DFG::FixupPhase::attemptToMakeIntegerAdd):
     106        * dfg/DFGFlushFormat.cpp:
     107        (WTF::printInternal):
     108        * dfg/DFGFlushFormat.h:
     109        (JSC::DFG::resultFor):
     110        (JSC::DFG::useKindFor):
     111        * dfg/DFGGenerationInfo.h:
     112        (JSC::DFG::GenerationInfo::initInt52):
     113        (JSC::DFG::GenerationInfo::initStrictInt52):
     114        (JSC::DFG::GenerationInfo::isFormat):
     115        (JSC::DFG::GenerationInfo::isInt52):
     116        (JSC::DFG::GenerationInfo::isStrictInt52):
     117        (JSC::DFG::GenerationInfo::fillInt52):
     118        (JSC::DFG::GenerationInfo::fillStrictInt52):
     119        * dfg/DFGGraph.cpp:
     120        (JSC::DFG::Graph::dump):
     121        * dfg/DFGGraph.h:
     122        (JSC::DFG::Graph::addShouldSpeculateMachineInt):
     123        (JSC::DFG::Graph::mulShouldSpeculateMachineInt):
     124        (JSC::DFG::Graph::negateShouldSpeculateMachineInt):
     125        * dfg/DFGInPlaceAbstractState.cpp:
     126        (JSC::DFG::InPlaceAbstractState::mergeStateAtTail):
     127        * dfg/DFGJITCode.cpp:
     128        (JSC::DFG::JITCode::reconstruct):
     129        * dfg/DFGMinifiedNode.h:
     130        (JSC::DFG::belongsInMinifiedGraph):
     131        (JSC::DFG::MinifiedNode::hasChild):
     132        * dfg/DFGNode.h:
     133        (JSC::DFG::Node::shouldSpeculateNumber):
     134        (JSC::DFG::Node::shouldSpeculateNumberExpectingDefined):
     135        * dfg/DFGNodeFlags.h:
     136        * dfg/DFGNodeType.h:
     137        (JSC::DFG::forwardRewiringSelectionScore):
     138        * dfg/DFGOSRExitCompiler.cpp:
     139        * dfg/DFGOSRExitCompiler64.cpp:
     140        (JSC::DFG::OSRExitCompiler::compileExit):
     141        * dfg/DFGPredictionPropagationPhase.cpp:
     142        (JSC::DFG::PredictionPropagationPhase::speculatedDoubleTypeForPrediction):
     143        (JSC::DFG::PredictionPropagationPhase::propagate):
     144        (JSC::DFG::PredictionPropagationPhase::doDoubleVoting):
     145        * dfg/DFGSafeToExecute.h:
     146        (JSC::DFG::SafeToExecuteEdge::operator()):
     147        (JSC::DFG::safeToExecute):
     148        * dfg/DFGSilentRegisterSavePlan.h:
     149        * dfg/DFGSpeculativeJIT.cpp:
     150        (JSC::DFG::SpeculativeJIT::silentSavePlanForGPR):
     151        (JSC::DFG::SpeculativeJIT::silentFill):
     152        (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
     153        (JSC::DFG::SpeculativeJIT::compileInlineStart):
     154        (JSC::DFG::SpeculativeJIT::compileDoublePutByVal):
     155        (JSC::DFG::SpeculativeJIT::compileValueToInt32):
     156        (JSC::DFG::SpeculativeJIT::compileInt32ToDouble):
     157        (JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray):
     158        (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
     159        (JSC::DFG::SpeculativeJIT::compileAdd):
     160        (JSC::DFG::SpeculativeJIT::compileArithSub):
     161        (JSC::DFG::SpeculativeJIT::compileArithNegate):
     162        (JSC::DFG::SpeculativeJIT::compileArithMul):
     163        (JSC::DFG::SpeculativeJIT::compare):
     164        (JSC::DFG::SpeculativeJIT::compileStrictEq):
     165        (JSC::DFG::SpeculativeJIT::speculateMachineInt):
     166        (JSC::DFG::SpeculativeJIT::speculateNumber):
     167        (JSC::DFG::SpeculativeJIT::speculateRealNumber):
     168        (JSC::DFG::SpeculativeJIT::speculate):
     169        * dfg/DFGSpeculativeJIT.h:
     170        (JSC::DFG::SpeculativeJIT::canReuse):
     171        (JSC::DFG::SpeculativeJIT::isFilled):
     172        (JSC::DFG::SpeculativeJIT::isFilledDouble):
     173        (JSC::DFG::SpeculativeJIT::use):
     174        (JSC::DFG::SpeculativeJIT::isKnownInteger):
     175        (JSC::DFG::SpeculativeJIT::isKnownCell):
     176        (JSC::DFG::SpeculativeJIT::isKnownNotNumber):
     177        (JSC::DFG::SpeculativeJIT::int52Result):
     178        (JSC::DFG::SpeculativeJIT::strictInt52Result):
     179        (JSC::DFG::SpeculativeJIT::initConstantInfo):
     180        (JSC::DFG::SpeculativeJIT::isInteger):
     181        (JSC::DFG::SpeculativeJIT::betterUseStrictInt52):
     182        (JSC::DFG::SpeculativeJIT::generationInfo):
     183        (JSC::DFG::SpeculateInt52Operand::SpeculateInt52Operand):
     184        (JSC::DFG::SpeculateInt52Operand::~SpeculateInt52Operand):
     185        (JSC::DFG::SpeculateInt52Operand::edge):
     186        (JSC::DFG::SpeculateInt52Operand::node):
     187        (JSC::DFG::SpeculateInt52Operand::gpr):
     188        (JSC::DFG::SpeculateInt52Operand::use):
     189        (JSC::DFG::SpeculateStrictInt52Operand::SpeculateStrictInt52Operand):
     190        (JSC::DFG::SpeculateStrictInt52Operand::~SpeculateStrictInt52Operand):
     191        (JSC::DFG::SpeculateStrictInt52Operand::edge):
     192        (JSC::DFG::SpeculateStrictInt52Operand::node):
     193        (JSC::DFG::SpeculateStrictInt52Operand::gpr):
     194        (JSC::DFG::SpeculateStrictInt52Operand::use):
     195        (JSC::DFG::SpeculateWhicheverInt52Operand::SpeculateWhicheverInt52Operand):
     196        (JSC::DFG::SpeculateWhicheverInt52Operand::~SpeculateWhicheverInt52Operand):
     197        (JSC::DFG::SpeculateWhicheverInt52Operand::edge):
     198        (JSC::DFG::SpeculateWhicheverInt52Operand::node):
     199        (JSC::DFG::SpeculateWhicheverInt52Operand::gpr):
     200        (JSC::DFG::SpeculateWhicheverInt52Operand::use):
     201        (JSC::DFG::SpeculateWhicheverInt52Operand::format):
     202        * dfg/DFGSpeculativeJIT32_64.cpp:
     203        (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
     204        (JSC::DFG::SpeculativeJIT::compile):
     205        * dfg/DFGSpeculativeJIT64.cpp:
     206        (JSC::DFG::SpeculativeJIT::boxInt52):
     207        (JSC::DFG::SpeculativeJIT::fillJSValue):
     208        (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
     209        (JSC::DFG::SpeculativeJIT::fillSpeculateInt52):
     210        (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
     211        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
     212        (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
     213        (JSC::DFG::SpeculativeJIT::compileInt52Compare):
     214        (JSC::DFG::SpeculativeJIT::compilePeepHoleInt52Branch):
     215        (JSC::DFG::SpeculativeJIT::compile):
     216        * dfg/DFGUseKind.cpp:
     217        (WTF::printInternal):
     218        * dfg/DFGUseKind.h:
     219        (JSC::DFG::typeFilterFor):
     220        (JSC::DFG::isNumerical):
     221        * dfg/DFGValueSource.cpp:
     222        (JSC::DFG::ValueSource::dump):
     223        * dfg/DFGValueSource.h:
     224        (JSC::DFG::dataFormatToValueSourceKind):
     225        (JSC::DFG::valueSourceKindToDataFormat):
     226        (JSC::DFG::ValueSource::forFlushFormat):
     227        (JSC::DFG::ValueSource::valueRecovery):
     228        * dfg/DFGVariableAccessData.h:
     229        (JSC::DFG::VariableAccessData::shouldUseDoubleFormatAccordingToVote):
     230        (JSC::DFG::VariableAccessData::flushFormat):
     231        * ftl/FTLCArgumentGetter.cpp:
     232        (JSC::FTL::CArgumentGetter::loadNextAndBox):
     233        * ftl/FTLCArgumentGetter.h:
     234        * ftl/FTLCapabilities.cpp:
     235        (JSC::FTL::canCompile):
     236        * ftl/FTLExitValue.cpp:
     237        (JSC::FTL::ExitValue::dumpInContext):
     238        * ftl/FTLExitValue.h:
     239        (JSC::FTL::ExitValue::inJSStackAsInt52):
     240        * ftl/FTLIntrinsicRepository.h:
     241        * ftl/FTLLowerDFGToLLVM.cpp:
     242        (JSC::FTL::LowerDFGToLLVM::createPhiVariables):
     243        (JSC::FTL::LowerDFGToLLVM::compileNode):
     244        (JSC::FTL::LowerDFGToLLVM::compileUpsilon):
     245        (JSC::FTL::LowerDFGToLLVM::compilePhi):
     246        (JSC::FTL::LowerDFGToLLVM::compileSetLocal):
     247        (JSC::FTL::LowerDFGToLLVM::compileAdd):
     248        (JSC::FTL::LowerDFGToLLVM::compileArithSub):
     249        (JSC::FTL::LowerDFGToLLVM::compileArithMul):
     250        (JSC::FTL::LowerDFGToLLVM::compileArithNegate):
     251        (JSC::FTL::LowerDFGToLLVM::compilePutByVal):
     252        (JSC::FTL::LowerDFGToLLVM::compileCompareEq):
     253        (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
     254        (JSC::FTL::LowerDFGToLLVM::compileCompareLess):
     255        (JSC::FTL::LowerDFGToLLVM::compileCompareLessEq):
     256        (JSC::FTL::LowerDFGToLLVM::compileCompareGreater):
     257        (JSC::FTL::LowerDFGToLLVM::compileCompareGreaterEq):
     258        (JSC::FTL::LowerDFGToLLVM::lowInt32):
     259        (JSC::FTL::LowerDFGToLLVM::lowInt52):
     260        (JSC::FTL::LowerDFGToLLVM::lowStrictInt52):
     261        (JSC::FTL::LowerDFGToLLVM::betterUseStrictInt52):
     262        (JSC::FTL::LowerDFGToLLVM::bestInt52Kind):
     263        (JSC::FTL::LowerDFGToLLVM::opposite):
     264        (JSC::FTL::LowerDFGToLLVM::Int52s::operator[]):
     265        (JSC::FTL::LowerDFGToLLVM::lowWhicheverInt52):
     266        (JSC::FTL::LowerDFGToLLVM::lowWhicheverInt52s):
     267        (JSC::FTL::LowerDFGToLLVM::lowOpposingInt52s):
     268        (JSC::FTL::LowerDFGToLLVM::lowCell):
     269        (JSC::FTL::LowerDFGToLLVM::lowBoolean):
     270        (JSC::FTL::LowerDFGToLLVM::lowDouble):
     271        (JSC::FTL::LowerDFGToLLVM::lowJSValue):
     272        (JSC::FTL::LowerDFGToLLVM::strictInt52ToInt32):
     273        (JSC::FTL::LowerDFGToLLVM::strictInt52ToDouble):
     274        (JSC::FTL::LowerDFGToLLVM::strictInt52ToJSValue):
     275        (JSC::FTL::LowerDFGToLLVM::setInt52WithStrictValue):
     276        (JSC::FTL::LowerDFGToLLVM::strictInt52ToInt52):
     277        (JSC::FTL::LowerDFGToLLVM::int52ToStrictInt52):
     278        (JSC::FTL::LowerDFGToLLVM::speculateRealNumber):
     279        (JSC::FTL::LowerDFGToLLVM::initializeOSRExitStateForBlock):
     280        (JSC::FTL::LowerDFGToLLVM::emitOSRExitCall):
     281        (JSC::FTL::LowerDFGToLLVM::addExitArgumentForNode):
     282        (JSC::FTL::LowerDFGToLLVM::setInt52):
     283        (JSC::FTL::LowerDFGToLLVM::setStrictInt52):
     284        * ftl/FTLOSRExitCompiler.cpp:
     285        (JSC::FTL::compileStub):
     286        * ftl/FTLOutput.h:
     287        (JSC::FTL::Output::addWithOverflow64):
     288        (JSC::FTL::Output::subWithOverflow64):
     289        (JSC::FTL::Output::mulWithOverflow64):
     290        * ftl/FTLValueFormat.cpp:
     291        (WTF::printInternal):
     292        * ftl/FTLValueFormat.h:
     293        * ftl/FTLValueSource.cpp:
     294        (JSC::FTL::ValueSource::dump):
     295        * ftl/FTLValueSource.h:
     296        * interpreter/Register.h:
     297        (JSC::Register::unboxedInt52):
     298        * runtime/Arguments.cpp:
     299        (JSC::Arguments::tearOffForInlineCallFrame):
     300        * runtime/IndexingType.cpp:
     301        (JSC::leastUpperBoundOfIndexingTypeAndType):
     302        * runtime/JSCJSValue.h:
     303        * runtime/JSCJSValueInlines.h:
     304        (JSC::JSValue::isMachineInt):
     305        (JSC::JSValue::asMachineInt):
     306
    13072013-09-17  Filip Pizlo  <fpizlo@apple.com>
    2308
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h

    r155711 r156019  
    231231    }
    232232   
     233    void rshift64(TrustedImm32 imm, RegisterID dest)
     234    {
     235        m_assembler.sarq_i8r(imm.m_value, dest);
     236    }
     237   
     238    void mul64(RegisterID src, RegisterID dest)
     239    {
     240        m_assembler.imulq_rr(src, dest);
     241    }
     242   
    233243    void neg64(RegisterID dest)
    234244    {
     
    531541    }
    532542
     543    Jump branchMul64(ResultCondition cond, RegisterID src, RegisterID dest)
     544    {
     545        mul64(src, dest);
     546        if (cond != Overflow)
     547            m_assembler.testq_rr(dest, dest);
     548        return Jump(m_assembler.jCC(x86Condition(cond)));
     549    }
     550
    533551    Jump branchSub64(ResultCondition cond, TrustedImm32 imm, RegisterID dest)
    534552    {
     
    547565        move(src1, dest);
    548566        return branchSub64(cond, src2, dest);
     567    }
     568
     569    Jump branchNeg64(ResultCondition cond, RegisterID srcDest)
     570    {
     571        neg64(srcDest);
     572        return Jump(m_assembler.jCC(x86Condition(cond)));
    549573    }
    550574
     
    594618        MacroAssemblerX86Common::move(TrustedImmPtr(address.m_ptr), scratchRegister);
    595619        return MacroAssemblerX86Common::branchTest8(cond, Address(scratchRegister), mask);
     620    }
     621
     622    void convertInt64ToDouble(RegisterID src, FPRegisterID dest)
     623    {
     624        m_assembler.cvtsi2sdq_rr(src, dest);
    596625    }
    597626
  • trunk/Source/JavaScriptCore/assembler/X86Assembler.h

    r155711 r156019  
    830830        }
    831831    }
    832 #endif
     832#endif // CPU(X86_64)
    833833
    834834    void imull_rr(RegisterID src, RegisterID dst)
     
    836836        m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, src);
    837837    }
     838
     839#if CPU(X86_64)
     840    void imulq_rr(RegisterID src, RegisterID dst)
     841    {
     842        m_formatter.twoByteOp64(OP2_IMUL_GvEv, dst, src);
     843    }
     844#endif // CPU(X86_64)
    838845
    839846    void imull_mr(int offset, RegisterID base, RegisterID dst)
     
    16111618        m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src);
    16121619    }
     1620
     1621#if CPU(X86_64)
     1622    void cvtsi2sdq_rr(RegisterID src, XMMRegisterID dst)
     1623    {
     1624        m_formatter.prefix(PRE_SSE_F2);
     1625        m_formatter.twoByteOp64(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src);
     1626    }
     1627#endif
    16131628
    16141629    void cvtsi2sd_mr(int offset, RegisterID base, XMMRegisterID dst)
  • trunk/Source/JavaScriptCore/bytecode/DataFormat.h

    r155578 r156019  
    4040    DataFormatNone = 0,
    4141    DataFormatInt32 = 1,
    42     DataFormatDouble = 2,
    43     DataFormatBoolean = 3,
    44     DataFormatCell = 4,
    45     DataFormatStorage = 5,
     42    DataFormatInt52 = 2, // Int52's are left-shifted by 16 by default.
     43    DataFormatStrictInt52 = 3, // "Strict" Int52 means it's not shifted.
     44    DataFormatDouble = 4,
     45    DataFormatBoolean = 5,
     46    DataFormatCell = 6,
     47    DataFormatStorage = 7,
    4648    DataFormatJS = 8,
    4749    DataFormatJSInt32 = DataFormatJS | DataFormatInt32,
     
    6567    case DataFormatInt32:
    6668        return "Int32";
     69    case DataFormatInt52:
     70        return "Int52";
     71    case DataFormatStrictInt52:
     72        return "StrictInt52";
    6773    case DataFormatDouble:
    6874        return "Double";
  • trunk/Source/JavaScriptCore/bytecode/ExitKind.cpp

    r155499 r156019  
    5353    case NegativeZero:
    5454        return "NegativeZero";
    55     case Int48Overflow:
    56         return "Int48Overflow";
     55    case Int52Overflow:
     56        return "Int52Overflow";
    5757    case StoreToHole:
    5858        return "StoreToHole";
  • trunk/Source/JavaScriptCore/bytecode/ExitKind.h

    r155499 r156019  
    3939    Overflow, // We exited because of overflow.
    4040    NegativeZero, // We exited because we encountered negative zero.
    41     Int48Overflow, // We exited because of an Int48 overflow.
     41    Int52Overflow, // We exited because of an Int52 overflow.
    4242    StoreToHole, // We had a store to a hole.
    4343    LoadFromHole, // We had a load from a hole.
  • trunk/Source/JavaScriptCore/bytecode/OperandsInlines.h

    r153296 r156019  
    4444        if (Traits::isEmptyForDump(local(localIndex)))
    4545            continue;
    46         out.print(comma, "r", localIndex, ":", inContext(local(localIndex), context));
     46        out.print(comma, "loc", localIndex, ":", inContext(local(localIndex), context));
    4747    }
    4848}
  • trunk/Source/JavaScriptCore/bytecode/SpeculatedType.cpp

    r155499 r156019  
    155155   
    156156    if (value & SpecInt32)
    157         myOut.print("Int");
     157        myOut.print("Int32");
    158158    else
    159159        isTop = false;
    160160   
     161    if (value & SpecInt52)
     162        myOut.print("Int52");
     163       
    161164    if ((value & SpecDouble) == SpecDouble)
    162165        myOut.print("Double");
    163166    else {
    164         if (value & SpecInt48AsDouble)
    165             myOut.print("Int48asdouble");
    166         else
    167             isTop = false;
    168        
    169         if (value & SpecInt48)
    170             myOut.print("Int48");
     167        if (value & SpecInt52AsDouble)
     168            myOut.print("Int52asdouble");
    171169        else
    172170            isTop = false;
     
    244242    if (isInt32Speculation(prediction))
    245243        return "<Int32>";
    246     if (isInt48AsDoubleSpeculation(prediction))
    247         return "<Int48AsDouble>";
    248     if (isInt48Speculation(prediction))
    249         return "<Int48>";
     244    if (isInt52AsDoubleSpeculation(prediction))
     245        return "<Int52AsDouble>";
     246    if (isInt52Speculation(prediction))
     247        return "<Int52>";
     248    if (isMachineIntSpeculation(prediction))
     249        return "<MachineInt>";
    250250    if (isDoubleSpeculation(prediction))
    251251        return "<Double>";
    252     if (isNumberSpeculation(prediction))
     252    if (isFullNumberSpeculation(prediction))
    253253        return "<Number>";
    254254    if (isBooleanSpeculation(prediction))
     
    346346    if (value.isDouble()) {
    347347        double number = value.asNumber();
    348         if (number == number) {
    349             int64_t asInt64 = static_cast<int64_t>(number);
    350             if (asInt64 == number && (asInt64 || !std::signbit(number))
    351                 && asInt64 < (static_cast<int64_t>(1) << 47)
    352                 && asInt64 >= -(static_cast<int64_t>(1) << 47)) {
    353                 return SpecInt48AsDouble;
    354             }
    355             return SpecNonIntAsDouble;
    356         }
    357         return SpecDoubleNaN;
     348        if (number != number)
     349            return SpecDoubleNaN;
     350        if (value.isMachineInt())
     351            return SpecInt52AsDouble;
     352        return SpecNonIntAsDouble;
    358353    }
    359354    if (value.isCell())
  • trunk/Source/JavaScriptCore/bytecode/SpeculatedType.h

    r155499 r156019  
    3939
    4040typedef uint32_t SpeculatedType;
    41 static const SpeculatedType SpecNone              = 0x00000000; // We don't know anything yet.
    42 static const SpeculatedType SpecFinalObject       = 0x00000001; // It's definitely a JSFinalObject.
    43 static const SpeculatedType SpecArray             = 0x00000002; // It's definitely a JSArray.
    44 static const SpeculatedType SpecFunction          = 0x00000008; // It's definitely a JSFunction or one of its subclasses.
    45 static const SpeculatedType SpecInt8Array         = 0x00000010; // It's definitely an Int8Array or one of its subclasses.
    46 static const SpeculatedType SpecInt16Array        = 0x00000020; // It's definitely an Int16Array or one of its subclasses.
    47 static const SpeculatedType SpecInt32Array        = 0x00000040; // It's definitely an Int32Array or one of its subclasses.
    48 static const SpeculatedType SpecUint8Array        = 0x00000080; // It's definitely an Uint8Array or one of its subclasses.
    49 static const SpeculatedType SpecUint8ClampedArray = 0x00000100; // It's definitely an Uint8ClampedArray or one of its subclasses.
    50 static const SpeculatedType SpecUint16Array       = 0x00000200; // It's definitely an Uint16Array or one of its subclasses.
    51 static const SpeculatedType SpecUint32Array       = 0x00000400; // It's definitely an Uint32Array or one of its subclasses.
    52 static const SpeculatedType SpecFloat32Array      = 0x00000800; // It's definitely an Uint16Array or one of its subclasses.
    53 static const SpeculatedType SpecFloat64Array      = 0x00001000; // It's definitely an Uint16Array or one of its subclasses.
    54 static const SpeculatedType SpecTypedArrayView    = SpecInt8Array | SpecInt16Array | SpecInt32Array | SpecUint8Array | SpecUint8ClampedArray | SpecUint16Array | SpecUint32Array | SpecFloat32Array | SpecFloat64Array;
    55 static const SpeculatedType SpecArguments         = 0x00002000; // It's definitely an Arguments object.
    56 static const SpeculatedType SpecStringObject      = 0x00004000; // It's definitely a StringObject.
    57 static const SpeculatedType SpecObjectOther       = 0x00008000; // It's definitely an object but not JSFinalObject, JSArray, or JSFunction.
    58 static const SpeculatedType SpecObject            = 0x0000ffff; // Bitmask used for testing for any kind of object prediction.
    59 static const SpeculatedType SpecStringIdent       = 0x00010000; // It's definitely a JSString, and it's an identifier.
    60 static const SpeculatedType SpecStringVar         = 0x00020000; // It's definitely a JSString, and it's not an identifier.
    61 static const SpeculatedType SpecString            = 0x00030000; // It's definitely a JSString.
    62 static const SpeculatedType SpecCellOther         = 0x00040000; // It's definitely a JSCell but not a subclass of JSObject and definitely not a JSString.
    63 static const SpeculatedType SpecCell              = 0x0007ffff; // It's definitely a JSCell.
    64 static const SpeculatedType SpecInt32             = 0x00800000; // It's definitely an Int32.
    65 static const SpeculatedType SpecInt48             = 0x01000000; // It's definitely an Int48, it's inside a double, but it doesn't need to be.
    66 static const SpeculatedType SpecMachineInt        = 0x01800000; // It's something that we can do machine int arithmetic on.
    67 static const SpeculatedType SpecInt48AsDouble     = 0x02000000; // It's definitely an Int48 and it's inside a double.
    68 static const SpeculatedType SpecInteger           = 0x03800000; // It's definitely some kind of integer.
    69 static const SpeculatedType SpecNonIntAsDouble    = 0x04000000; // It's definitely not an Int48 but it's a real number and it's a double.
    70 static const SpeculatedType SpecDoubleReal        = 0x07000000; // It's definitely a non-NaN double.
    71 static const SpeculatedType SpecDoubleNaN         = 0x08000000; // It's definitely a NaN.
    72 static const SpeculatedType SpecDouble            = 0x0f000000; // It's either a non-NaN or a NaN double.
    73 static const SpeculatedType SpecRealNumber        = 0x07800000; // It's either an Int32 or a DoubleReal.
    74 static const SpeculatedType SpecNumber            = 0x0f800000; // It's either an Int32 or a Double.
    75 static const SpeculatedType SpecBoolean           = 0x10000000; // It's definitely a Boolean.
    76 static const SpeculatedType SpecOther             = 0x20000000; // It's definitely none of the above.
    77 static const SpeculatedType SpecHeapTop           = 0x3fffffff; // It can be any of the above.
    78 static const SpeculatedType SpecEmpty             = 0x40000000; // It's definitely an empty value marker.
    79 static const SpeculatedType SpecBytecodeTop       = 0x7fffffff; // It can be any of the above.
    80 static const SpeculatedType SpecFullTop           = 0x7fffffff; // It can be any of the above plus anything the DFG chooses.
     41static const SpeculatedType SpecNone               = 0x00000000; // We don't know anything yet.
     42static const SpeculatedType SpecFinalObject        = 0x00000001; // It's definitely a JSFinalObject.
     43static const SpeculatedType SpecArray              = 0x00000002; // It's definitely a JSArray.
     44static const SpeculatedType SpecFunction           = 0x00000008; // It's definitely a JSFunction or one of its subclasses.
     45static const SpeculatedType SpecInt8Array          = 0x00000010; // It's definitely an Int8Array or one of its subclasses.
     46static const SpeculatedType SpecInt16Array         = 0x00000020; // It's definitely an Int16Array or one of its subclasses.
     47static const SpeculatedType SpecInt32Array         = 0x00000040; // It's definitely an Int32Array or one of its subclasses.
     48static const SpeculatedType SpecUint8Array         = 0x00000080; // It's definitely an Uint8Array or one of its subclasses.
     49static const SpeculatedType SpecUint8ClampedArray  = 0x00000100; // It's definitely an Uint8ClampedArray or one of its subclasses.
     50static const SpeculatedType SpecUint16Array        = 0x00000200; // It's definitely an Uint16Array or one of its subclasses.
     51static const SpeculatedType SpecUint32Array        = 0x00000400; // It's definitely an Uint32Array or one of its subclasses.
     52static const SpeculatedType SpecFloat32Array       = 0x00000800; // It's definitely an Uint16Array or one of its subclasses.
     53static const SpeculatedType SpecFloat64Array       = 0x00001000; // It's definitely an Uint16Array or one of its subclasses.
     54static const SpeculatedType SpecTypedArrayView     = SpecInt8Array | SpecInt16Array | SpecInt32Array | SpecUint8Array | SpecUint8ClampedArray | SpecUint16Array | SpecUint32Array | SpecFloat32Array | SpecFloat64Array;
     55static const SpeculatedType SpecArguments          = 0x00002000; // It's definitely an Arguments object.
     56static const SpeculatedType SpecStringObject       = 0x00004000; // It's definitely a StringObject.
     57static const SpeculatedType SpecObjectOther        = 0x00008000; // It's definitely an object but not JSFinalObject, JSArray, or JSFunction.
     58static const SpeculatedType SpecObject             = 0x0000ffff; // Bitmask used for testing for any kind of object prediction.
     59static const SpeculatedType SpecStringIdent        = 0x00010000; // It's definitely a JSString, and it's an identifier.
     60static const SpeculatedType SpecStringVar          = 0x00020000; // It's definitely a JSString, and it's not an identifier.
     61static const SpeculatedType SpecString             = 0x00030000; // It's definitely a JSString.
     62static const SpeculatedType SpecCellOther          = 0x00040000; // It's definitely a JSCell but not a subclass of JSObject and definitely not a JSString.
     63static const SpeculatedType SpecCell               = 0x0007ffff; // It's definitely a JSCell.
     64static const SpeculatedType SpecInt32              = 0x00800000; // It's definitely an Int32.
     65static const SpeculatedType SpecInt52              = 0x01000000; // It's definitely an Int52 and we intend it to unbox it.
     66static const SpeculatedType SpecMachineInt         = 0x01800000; // It's something that we can do machine int arithmetic on.
     67static const SpeculatedType SpecInt52AsDouble      = 0x02000000; // It's definitely an Int52 and it's inside a double.
     68static const SpeculatedType SpecInteger            = 0x03800000; // It's definitely some kind of integer.
     69static const SpeculatedType SpecNonIntAsDouble     = 0x04000000; // It's definitely not an Int52 but it's a real number and it's a double.
     70static const SpeculatedType SpecDoubleReal         = 0x06000000; // It's definitely a non-NaN double.
     71static const SpeculatedType SpecDoubleNaN          = 0x08000000; // It's definitely a NaN.
     72static const SpeculatedType SpecDouble             = 0x0e000000; // It's either a non-NaN or a NaN double.
     73static const SpeculatedType SpecBytecodeRealNumber = 0x06800000; // It's either an Int32 or a DoubleReal.
     74static const SpeculatedType SpecFullRealNumber     = 0x07800000; // It's either an Int32 or a DoubleReal, or a Int52.
     75static const SpeculatedType SpecBytecodeNumber     = 0x0e800000; // It's either an Int32 or a Double.
     76static const SpeculatedType SpecFullNumber         = 0x0f800000; // It's either an Int32, Int52, or a Double.
     77static const SpeculatedType SpecBoolean            = 0x10000000; // It's definitely a Boolean.
     78static const SpeculatedType SpecOther              = 0x20000000; // It's definitely none of the above.
     79static const SpeculatedType SpecHeapTop            = 0x3effffff; // It can be any of the above, except for SpecInt52.
     80static const SpeculatedType SpecEmpty              = 0x40000000; // It's definitely an empty value marker.
     81static const SpeculatedType SpecBytecodeTop        = 0x7effffff; // It can be any of the above, except for SpecInt52.
     82static const SpeculatedType SpecFullTop            = 0x7fffffff; // It can be any of the above plus anything the DFG chooses.
    8183
    8284typedef bool (*SpeculatedTypeChecker)(SpeculatedType);
     
    241243inline bool isInt32SpeculationForArithmetic(SpeculatedType value)
    242244{
     245    return !(value & (SpecDouble | SpecInt52));
     246}
     247
     248inline bool isInt32SpeculationExpectingDefined(SpeculatedType value)
     249{
     250    return isInt32Speculation(value & ~SpecOther);
     251}
     252
     253inline bool isInt52Speculation(SpeculatedType value)
     254{
     255    return value == SpecInt52;
     256}
     257
     258inline bool isMachineIntSpeculation(SpeculatedType value)
     259{
     260    return !!value && (value & SpecMachineInt) == value;
     261}
     262
     263inline bool isMachineIntSpeculationExpectingDefined(SpeculatedType value)
     264{
     265    return isMachineIntSpeculation(value & ~SpecOther);
     266}
     267
     268inline bool isMachineIntSpeculationForArithmetic(SpeculatedType value)
     269{
    243270    return !(value & SpecDouble);
    244271}
    245272
    246 inline bool isInt32SpeculationExpectingDefined(SpeculatedType value)
    247 {
    248     return isInt32Speculation(value & ~SpecOther);
    249 }
    250 
    251 inline bool isInt48Speculation(SpeculatedType value)
    252 {
    253     return value == SpecInt48;
    254 }
    255 
    256 inline bool isMachineIntSpeculation(SpeculatedType value)
    257 {
    258     return !!value && (value & SpecMachineInt) == value;
    259 }
    260 
    261 inline bool isMachineIntSpeculationExpectingDefined(SpeculatedType value)
    262 {
    263     return isMachineIntSpeculation(value & ~SpecOther);
    264 }
    265 
    266 inline bool isMachineIntSpeculationForArithmetic(SpeculatedType value)
    267 {
    268     return !(value & (SpecDouble & ~SpecMachineInt));
    269 }
    270 
    271 inline bool isInt48AsDoubleSpeculation(SpeculatedType value)
    272 {
    273     return value == SpecInt48AsDouble;
     273inline bool isInt52AsDoubleSpeculation(SpeculatedType value)
     274{
     275    return value == SpecInt52AsDouble;
    274276}
    275277
     
    294296}
    295297
    296 inline bool isRealNumberSpeculation(SpeculatedType value)
    297 {
    298     return !!(value & SpecRealNumber) && !(value & ~SpecRealNumber);
    299 }
    300 
    301 inline bool isNumberSpeculation(SpeculatedType value)
    302 {
    303     return !!(value & SpecNumber) && !(value & ~SpecNumber);
    304 }
    305 
    306 inline bool isNumberSpeculationExpectingDefined(SpeculatedType value)
    307 {
    308     return isNumberSpeculation(value & ~SpecOther);
     298inline bool isBytecodeRealNumberSpeculation(SpeculatedType value)
     299{
     300    return !!(value & SpecBytecodeRealNumber) && !(value & ~SpecBytecodeRealNumber);
     301}
     302
     303inline bool isFullRealNumberSpeculation(SpeculatedType value)
     304{
     305    return !!(value & SpecFullRealNumber) && !(value & ~SpecFullRealNumber);
     306}
     307
     308inline bool isBytecodeNumberSpeculation(SpeculatedType value)
     309{
     310    return !!(value & SpecBytecodeNumber) && !(value & ~SpecBytecodeNumber);
     311}
     312
     313inline bool isFullNumberSpeculation(SpeculatedType value)
     314{
     315    return !!(value & SpecFullNumber) && !(value & ~SpecFullNumber);
     316}
     317
     318inline bool isBytecodeNumberSpeculationExpectingDefined(SpeculatedType value)
     319{
     320    return isBytecodeNumberSpeculation(value & ~SpecOther);
     321}
     322
     323inline bool isFullNumberSpeculationExpectingDefined(SpeculatedType value)
     324{
     325    return isFullNumberSpeculation(value & ~SpecOther);
    309326}
    310327
  • trunk/Source/JavaScriptCore/bytecode/ValueRecovery.h

    r155820 r156019  
    4545    // It's already in the stack but unboxed.
    4646    AlreadyInJSStackAsUnboxedInt32,
     47    AlreadyInJSStackAsUnboxedInt52,
    4748    AlreadyInJSStackAsUnboxedCell,
    4849    AlreadyInJSStackAsUnboxedBoolean,
     
    5152    InGPR,
    5253    UnboxedInt32InGPR,
     54    UnboxedInt52InGPR,
     55    UnboxedStrictInt52InGPR,
    5356    UnboxedBooleanInGPR,
    5457#if USE(JSVALUE32_64)
     
    6164    // It's in the stack, at a different location, and it's unboxed.
    6265    Int32DisplacedInJSStack,
     66    Int52DisplacedInJSStack,
     67    StrictInt52DisplacedInJSStack,
    6368    DoubleDisplacedInJSStack,
    6469    CellDisplacedInJSStack,
     
    96101    }
    97102   
     103    static ValueRecovery alreadyInJSStackAsUnboxedInt52()
     104    {
     105        ValueRecovery result;
     106        result.m_technique = AlreadyInJSStackAsUnboxedInt52;
     107        return result;
     108    }
     109   
    98110    static ValueRecovery alreadyInJSStackAsUnboxedCell()
    99111    {
     
    126138        if (dataFormat == DataFormatInt32)
    127139            result.m_technique = UnboxedInt32InGPR;
     140        else if (dataFormat == DataFormatInt52)
     141            result.m_technique = UnboxedInt52InGPR;
     142        else if (dataFormat == DataFormatStrictInt52)
     143            result.m_technique = UnboxedStrictInt52InGPR;
    128144        else if (dataFormat == DataFormatBoolean)
    129145            result.m_technique = UnboxedBooleanInGPR;
     
    169185            break;
    170186           
     187        case DataFormatInt52:
     188            result.m_technique = Int52DisplacedInJSStack;
     189            break;
     190           
     191        case DataFormatStrictInt52:
     192            result.m_technique = StrictInt52DisplacedInJSStack;
     193            break;
     194           
    171195        case DataFormatDouble:
    172196            result.m_technique = DoubleDisplacedInJSStack;
     
    230254        case AlreadyInJSStack:
    231255        case AlreadyInJSStackAsUnboxedInt32:
     256        case AlreadyInJSStackAsUnboxedInt52:
    232257        case AlreadyInJSStackAsUnboxedCell:
    233258        case AlreadyInJSStackAsUnboxedBoolean:
     
    241266    MacroAssembler::RegisterID gpr() const
    242267    {
    243         ASSERT(m_technique == InGPR || m_technique == UnboxedInt32InGPR || m_technique == UnboxedBooleanInGPR || m_technique == UInt32InGPR);
     268        ASSERT(m_technique == InGPR || m_technique == UnboxedInt32InGPR || m_technique == UnboxedBooleanInGPR || m_technique == UInt32InGPR || m_technique == UnboxedInt52InGPR || m_technique == UnboxedStrictInt52InGPR);
    244269        return m_source.gpr;
    245270    }
     
    267292    VirtualRegister virtualRegister() const
    268293    {
    269         ASSERT(m_technique == DisplacedInJSStack || m_technique == Int32DisplacedInJSStack || m_technique == DoubleDisplacedInJSStack || m_technique == CellDisplacedInJSStack || m_technique == BooleanDisplacedInJSStack);
     294        ASSERT(m_technique == DisplacedInJSStack || m_technique == Int32DisplacedInJSStack || m_technique == DoubleDisplacedInJSStack || m_technique == CellDisplacedInJSStack || m_technique == BooleanDisplacedInJSStack || m_technique == Int52DisplacedInJSStack || m_technique == StrictInt52DisplacedInJSStack);
    270295        return m_source.virtualReg;
    271296    }
     
    286311            out.printf("(int32)");
    287312            return;
     313        case AlreadyInJSStackAsUnboxedInt52:
     314            out.printf("(int52)");
     315            return;
    288316        case AlreadyInJSStackAsUnboxedCell:
    289317            out.printf("(cell)");
     
    301329            out.printf("int32(%%r%d)", gpr());
    302330            return;
     331        case UnboxedInt52InGPR:
     332            out.printf("int52(%%r%d)", gpr());
     333            return;
     334        case UnboxedStrictInt52InGPR:
     335            out.printf("strictInt52(%%r%d)", gpr());
     336            return;
    303337        case UnboxedBooleanInGPR:
    304338            out.printf("bool(%%r%d)", gpr());
     
    320354        case Int32DisplacedInJSStack:
    321355            out.printf("*int32(%d)", virtualRegister());
     356            return;
     357        case Int52DisplacedInJSStack:
     358            out.printf("*int52(%d)", virtualRegister());
     359            return;
     360        case StrictInt52DisplacedInJSStack:
     361            out.printf("*strictInt52(%d)", virtualRegister());
    322362            return;
    323363        case DoubleDisplacedInJSStack:
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h

    r155567 r156019  
    6161    bool needsTypeCheck(Node* node, SpeculatedType typesPassedThrough)
    6262    {
    63         return forNode(node).m_type & ~typesPassedThrough;
     63        return !forNode(node).isType(typesPassedThrough);
    6464    }
    6565   
     
    169169    {
    170170        AbstractValue& value = forNode(edge);
    171         if (value.m_type & ~type) {
     171        if (!value.isType(type)) {
    172172            node->setCanExit(true);
    173173            edge.setProofStatus(NeedsCheck);
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

    r155730 r156019  
    311311    }
    312312       
     313    case Int52ToDouble: {
     314        JSValue child = forNode(node->child1()).value();
     315        if (child && child.isNumber()) {
     316            setConstant(node, child);
     317            break;
     318        }
     319        forNode(node).setType(SpecDouble);
     320        break;
     321    }
     322       
     323    case Int52ToValue: {
     324        JSValue child = forNode(node->child1()).value();
     325        if (child && child.isNumber()) {
     326            setConstant(node, child);
     327            break;
     328        }
     329        SpeculatedType type = forNode(node->child1()).m_type;
     330        if (type & SpecInt52)
     331            type = (type | SpecInt32 | SpecInt52AsDouble) & ~SpecInt52;
     332        forNode(node).setType(type);
     333        break;
     334    }
     335       
    313336    case ValueAdd:
    314337    case ArithAdd: {
     
    325348                node->setCanExit(true);
    326349            break;
     350        case MachineIntUse:
     351            forNode(node).setType(SpecInt52);
     352            if (!forNode(node->child1()).isType(SpecInt32)
     353                || !forNode(node->child2()).isType(SpecInt32))
     354                node->setCanExit(true);
     355            break;
    327356        case NumberUse:
    328             if (isRealNumberSpeculation(forNode(node->child1()).m_type)
    329                 && isRealNumberSpeculation(forNode(node->child2()).m_type))
     357            if (isFullRealNumberSpeculation(forNode(node->child1()).m_type)
     358                && isFullRealNumberSpeculation(forNode(node->child2()).m_type))
    330359                forNode(node).setType(SpecDoubleReal);
    331360            else
     
    335364            RELEASE_ASSERT(node->op() == ValueAdd);
    336365            clobberWorld(node->codeOrigin, clobberLimit);
    337             forNode(node).setType(SpecString | SpecInt32 | SpecNumber);
     366            forNode(node).setType(SpecString | SpecBytecodeNumber);
    338367            break;
    339368        }
     
    359388                node->setCanExit(true);
    360389            break;
     390        case MachineIntUse:
     391            forNode(node).setType(SpecInt52);
     392            if (!forNode(node->child1()).isType(SpecInt32)
     393                || !forNode(node->child2()).isType(SpecInt32))
     394                node->setCanExit(true);
     395            break;
    361396        case NumberUse:
    362397            forNode(node).setType(SpecDouble);
     
    379414            forNode(node).setType(SpecInt32);
    380415            if (!bytecodeCanTruncateInteger(node->arithNodeFlags()))
     416                node->setCanExit(true);
     417            break;
     418        case MachineIntUse:
     419            forNode(node).setType(SpecInt52);
     420            if (m_state.forNode(node->child1()).couldBeType(SpecInt52))
     421                node->setCanExit(true);
     422            if (!bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
    381423                node->setCanExit(true);
    382424            break;
     
    405447                node->setCanExit(true);
    406448            break;
     449        case MachineIntUse:
     450            forNode(node).setType(SpecInt52);
     451            node->setCanExit(true);
     452            break;
    407453        case NumberUse:
    408             if (isRealNumberSpeculation(forNode(node->child1()).m_type)
    409                 || isRealNumberSpeculation(forNode(node->child2()).m_type))
     454            if (isFullRealNumberSpeculation(forNode(node->child1()).m_type)
     455                || isFullRealNumberSpeculation(forNode(node->child2()).m_type))
    410456                forNode(node).setType(SpecDoubleReal);
    411457            else
     
    587633        }
    588634       
    589         if (isNumberSpeculation(abstractChild.m_type)) {
     635        if (isFullNumberSpeculation(abstractChild.m_type)) {
    590636            setConstant(node, vm->smallStrings.numberString());
    591637            break;
     
    812858            if (node->shouldSpeculateInt32())
    813859                forNode(node).setType(SpecInt32);
     860            else if (enableInt52() && node->shouldSpeculateMachineInt())
     861                forNode(node).setType(SpecInt52);
    814862            else
    815863                forNode(node).setType(SpecDouble);
     
    864912        node->setCanExit(true);
    865913        clobberWorld(node->codeOrigin, clobberLimit);
    866         forNode(node).setType(SpecNumber);
     914        forNode(node).setType(SpecBytecodeNumber);
    867915        break;
    868916           
     
    935983        //
    936984        // destination = source;
    937         // if (destination.m_type & !(SpecNumber | SpecString | SpecBoolean)) {
    938         //     destination.filter(SpecNumber | SpecString | SpecBoolean);
     985        // if (destination.m_type & !(SpecFullNumber | SpecString | SpecBoolean)) {
     986        //     destination.filter(SpecFullNumber | SpecString | SpecBoolean);
    939987        //     AbstractValue string;
    940988        //     string.set(vm->stringStructure);
     
    9561004       
    9571005        SpeculatedType type = source.m_type;
    958         if (type & ~(SpecNumber | SpecString | SpecBoolean))
     1006        if (type & ~(SpecFullNumber | SpecString | SpecBoolean))
    9591007            type = (SpecHeapTop & ~SpecCell) | SpecString;
    9601008
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp

    r155480 r156019  
    6868       
    6969    m_type = speculationFromValue(value);
     70    if (m_type == SpecInt52AsDouble)
     71        m_type = SpecInt52;
    7072    m_value = value;
    7173       
     
    228230}
    229231
     232#if !ASSERT_DISABLED
    230233void AbstractValue::checkConsistency() const
    231234{
     
    239242        ASSERT(!m_value);
    240243   
    241     if (!!m_value)
    242         ASSERT(mergeSpeculations(m_type, speculationFromValue(m_value)) == m_type);
     244    if (!!m_value) {
     245        SpeculatedType type = m_type;
     246        if (type & SpecInt52)
     247            type |= SpecInt52AsDouble;
     248        ASSERT(mergeSpeculations(type, speculationFromValue(m_value)) == type);
     249    }
    243250   
    244251    // Note that it's possible for a prediction like (Final, []). This really means that
     
    247254    // complexity of the code.
    248255}
     256#endif
    249257
    250258void AbstractValue::dump(PrintStream& out) const
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.h

    r155480 r156019  
    186186    }
    187187   
     188    bool couldBeType(SpeculatedType desiredType)
     189    {
     190        return !!(m_type & desiredType);
     191    }
     192   
     193    bool isType(SpeculatedType desiredType)
     194    {
     195        return !(m_type & ~desiredType);
     196    }
     197   
    188198    FiltrationResult filter(Graph&, const StructureSet&);
    189199   
     
    193203   
    194204    FiltrationResult filterByValue(JSValue value);
    195    
    196     bool validateType(JSValue value) const
    197     {
    198         if (isHeapTop())
    199             return true;
    200        
    201         if (mergeSpeculations(m_type, speculationFromValue(value)) != m_type)
    202             return false;
    203        
    204         if (value.isEmpty()) {
    205             ASSERT(m_type & SpecEmpty);
    206             return true;
    207         }
    208        
    209         return true;
    210     }
    211205   
    212206    bool validate(JSValue value) const
     
    252246    }
    253247   
     248#if ASSERT_DISABLED
     249    void checkConsistency() const { }
     250#else
    254251    void checkConsistency() const;
     252#endif
    255253   
    256254    void dumpInContext(PrintStream&, DumpContext*) const;
     
    364362    }
    365363   
     364    bool validateType(JSValue value) const
     365    {
     366        if (isHeapTop())
     367            return true;
     368       
     369        // Constant folding always represents Int52's in a double (i.e. Int52AsDouble).
     370        // So speculationFromValue(value) for an Int52 value will return Int52AsDouble,
     371        // and that's fine - the type validates just fine.
     372        SpeculatedType type = m_type;
     373        if (type & SpecInt52)
     374            type |= SpecInt52AsDouble;
     375       
     376        if (mergeSpeculations(type, speculationFromValue(value)) != type)
     377            return false;
     378       
     379        if (value.isEmpty()) {
     380            ASSERT(m_type & SpecEmpty);
     381            return true;
     382        }
     383       
     384        return true;
     385    }
     386   
    366387    void makeTop(SpeculatedType top)
    367388    {
  • trunk/Source/JavaScriptCore/dfg/DFGArrayMode.cpp

    r156017 r156019  
    164164        if (isInt32Speculation(value))
    165165            return withTypeAndConversion(Array::Int32, Array::Convert);
    166         if (isNumberSpeculation(value))
     166        if (isFullNumberSpeculation(value))
    167167            return withTypeAndConversion(Array::Double, Array::Convert);
    168168        return withTypeAndConversion(Array::Contiguous, Array::Convert);
     
    171171        if (!value || isInt32Speculation(value))
    172172            return *this;
    173         if (isNumberSpeculation(value))
     173        if (isFullNumberSpeculation(value))
    174174            return withTypeAndConversion(Array::Double, Array::Convert);
    175175        return withTypeAndConversion(Array::Contiguous, Array::Convert);
     
    178178        if (flags & NodeBytecodeUsesAsInt)
    179179            return withTypeAndConversion(Array::Contiguous, Array::RageConvert);
    180         if (!value || isNumberSpeculation(value))
     180        if (!value || isFullNumberSpeculation(value))
    181181            return *this;
    182182        return withTypeAndConversion(Array::Contiguous, Array::Convert);
  • trunk/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h

    r154797 r156019  
    294294        return fpr;
    295295    }
     296   
     297    void boxInt52(GPRReg source, GPRReg target, GPRReg scratch, FPRReg fpScratch)
     298    {
     299        // Is it an int32?
     300        signExtend32ToPtr(source, scratch);
     301        Jump isInt32 = branch64(Equal, source, scratch);
     302       
     303        // Nope, it's not, but regT0 contains the int64 value.
     304        convertInt64ToDouble(source, fpScratch);
     305        boxDouble(fpScratch, target);
     306        Jump done = jump();
     307       
     308        isInt32.link(this);
     309        zeroExtend32ToPtr(source, target);
     310        or64(GPRInfo::tagTypeNumberRegister, target);
     311       
     312        done.link(this);
     313    }
    296314#endif
    297315
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r156003 r156019  
    875875        case ArithAdd:
    876876        case ArithSub:
    877         case ArithNegate:
    878877        case ValueAdd:
    879878        case ArithMod: // for ArithMod "MayOverflow" means we tried to divide by zero, or we saw double.
     
    881880            break;
    882881           
     882        case ArithNegate:
     883            // Currently we can't tell the difference between a negation overflowing
     884            // (i.e. -(1 << 31)) or generating negative zero (i.e. -0). If it took slow
     885            // path then we assume that it did both of those things.
     886            node->mergeFlags(NodeMayOverflow);
     887            node->mergeFlags(NodeMayNegZero);
     888            break;
     889
    883890        case ArithMul:
    884891            if (m_inlineStackTop->m_profiledBlock->likelyToTakeDeepestSlowCase(m_currentIndex)
  • trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp

    r155564 r156019  
    6464private:
    6565   
    66     Node* canonicalize(Node* node)
    67     {
    68         if (!node)
    69             return 0;
    70        
    71         if (node->op() == ValueToInt32)
    72             node = node->child1().node();
    73        
    74         return node;
    75     }
    76     Node* canonicalize(Edge edge)
    77     {
    78         return canonicalize(edge.node());
    79     }
    80    
    8166    unsigned endIndexForPureCSE()
    8267    {
     
    9580    Node* pureCSE(Node* node)
    9681    {
    97         Node* child1 = canonicalize(node->child1());
    98         Node* child2 = canonicalize(node->child2());
    99         Node* child3 = canonicalize(node->child3());
     82        Edge child1 = node->child1();
     83        Edge child2 = node->child2();
     84        Edge child3 = node->child3();
    10085       
    10186        for (unsigned i = endIndexForPureCSE(); i--;) {
     
    11095                continue;
    11196           
    112             Node* otherChild = canonicalize(otherNode->child1());
     97            Edge otherChild = otherNode->child1();
    11398            if (!otherChild)
    11499                return otherNode;
     
    116101                continue;
    117102           
    118             otherChild = canonicalize(otherNode->child2());
     103            otherChild = otherNode->child2();
    119104            if (!otherChild)
    120105                return otherNode;
     
    122107                continue;
    123108           
    124             otherChild = canonicalize(otherNode->child3());
     109            otherChild = otherNode->child3();
    125110            if (!otherChild)
    126111                return otherNode;
     
    378363        for (unsigned i = m_indexInBlock; i--;) {
    379364            Node* node = m_currentBlock->at(i);
    380             if (node == child1 || node == canonicalize(child2))
     365            if (node == child1 || node == child2)
    381366                break;
    382367
     
    385370                if (!m_graph.byValIsPure(node))
    386371                    return 0;
    387                 if (node->child1() == child1 && canonicalize(node->child2()) == canonicalize(child2))
     372                if (node->child1() == child1 && node->child2() == child2)
    388373                    return node;
    389374                break;
     
    392377                if (!m_graph.byValIsPure(node))
    393378                    return 0;
    394                 if (m_graph.varArgChild(node, 0) == child1 && canonicalize(m_graph.varArgChild(node, 1)) == canonicalize(child2))
     379                if (m_graph.varArgChild(node, 0) == child1 && m_graph.varArgChild(node, 1) == child2)
    395380                    return m_graph.varArgChild(node, 2).node();
    396381                // We must assume that the PutByVal will clobber the location we're getting from.
     
    10911076        case ValueToInt32:
    10921077        case MakeRope:
     1078        case Int52ToDouble:
     1079        case Int52ToValue:
    10931080            if (cseMode == StoreElimination)
    10941081                break;
  • trunk/Source/JavaScriptCore/dfg/DFGClobberize.h

    r155023 r156019  
    113113    case Int32ToDouble:
    114114    case ExtractOSREntryLocal:
     115    case Int52ToDouble:
     116    case Int52ToValue:
    115117        return;
    116118       
     
    181183        case Int32Use:
    182184        case NumberUse:
     185        case MachineIntUse:
    183186            return;
    184187        case UntypedUse:
  • trunk/Source/JavaScriptCore/dfg/DFGCommon.h

    r153296 r156019  
    139139#if ENABLE(CONCURRENT_JIT)
    140140    return Options::enableConcurrentJIT() && Options::numberOfCompilerThreads();
     141#else
     142    return false;
     143#endif
     144}
     145
     146inline bool enableInt52()
     147{
     148#if USE(JSVALUE64)
     149    return true;
    141150#else
    142151    return false;
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r155593 r156019  
    6565        }
    6666       
     67        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
     68            fixupUntypedSetLocalsInBlock(m_graph.block(blockIndex));
     69       
    6770        return true;
    6871    }
     
    9396        case SetLocal: {
    9497            // This gets handled by fixupSetLocalsInBlock().
    95             break;
     98            return;
    9699        }
    97100           
     
    125128            }
    126129           
     130            if (node->child1()->shouldSpeculateMachineInt()) {
     131                fixEdge<MachineIntUse>(node->child1());
     132                break;
     133            }
     134           
    127135            if (node->child1()->shouldSpeculateNumber()) {
    128136                fixEdge<NumberUse>(node->child1());
     
    198206                break;
    199207            }
     208            if (m_graph.negateShouldSpeculateMachineInt(node)) {
     209                fixEdge<MachineIntUse>(node->child1());
     210                break;
     211            }
    200212            fixEdge<NumberUse>(node->child1());
    201213            break;
     
    206218                fixEdge<Int32Use>(node->child1());
    207219                fixEdge<Int32Use>(node->child2());
     220                break;
     221            }
     222            if (m_graph.mulShouldSpeculateMachineInt(node)) {
     223                fixEdge<MachineIntUse>(node->child1());
     224                fixEdge<MachineIntUse>(node->child2());
    208225                break;
    209226            }
     
    301318                break;
    302319            }
     320            if (enableInt52()
     321                && Node::shouldSpeculateMachineInt(node->child1().node(), node->child2().node())) {
     322                fixEdge<MachineIntUse>(node->child1());
     323                fixEdge<MachineIntUse>(node->child2());
     324                break;
     325            }
    303326            if (Node::shouldSpeculateNumber(node->child1().node(), node->child2().node())) {
    304327                fixEdge<NumberUse>(node->child1());
     
    354377                fixEdge<Int32Use>(node->child1());
    355378                fixEdge<Int32Use>(node->child2());
     379                break;
     380            }
     381            if (enableInt52()
     382                && Node::shouldSpeculateMachineInt(node->child1().node(), node->child2().node())) {
     383                fixEdge<MachineIntUse>(node->child1());
     384                fixEdge<MachineIntUse>(node->child2());
    356385                break;
    357386            }
     
    477506                fixEdge<Int32Use>(child2);
    478507                fixEdge<Int32Use>(child3);
     508                if (child3->prediction() & SpecInt52)
     509                    fixEdge<MachineIntUse>(child3);
     510                else
     511                    fixEdge<Int32Use>(child3);
    479512                break;
    480513            case Array::Double:
     
    494527                if (child3->shouldSpeculateInt32())
    495528                    fixEdge<Int32Use>(child3);
     529                else if (child3->shouldSpeculateMachineInt())
     530                    fixEdge<MachineIntUse>(child3);
    496531                else
    497532                    fixEdge<NumberUse>(child3);
     
    848883        case CheckTierUpAtReturn:
    849884        case CheckTierUpAndOSREnter:
     885        case Int52ToDouble:
     886        case Int52ToValue:
    850887            RELEASE_ASSERT_NOT_REACHED();
    851888            break;
     
    11901227                fixEdge<Int32Use>(node->child1());
    11911228                break;
     1229            case FlushedInt52:
     1230                fixEdge<MachineIntUse>(node->child1());
     1231                break;
    11921232            case FlushedCell:
    11931233                fixEdge<CellUse>(node->child1());
     
    12001240                break;
    12011241            }
     1242        }
     1243        m_insertionSet.execute(block);
     1244    }
     1245   
     1246    void fixupUntypedSetLocalsInBlock(BasicBlock* block)
     1247    {
     1248        if (!block)
     1249            return;
     1250        ASSERT(block->isReachable);
     1251        m_block = block;
     1252        for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
     1253            Node* node = m_currentNode = block->at(m_indexInBlock);
     1254            if (node->op() != SetLocal)
     1255                continue;
     1256           
     1257            if (node->child1().useKind() == UntypedUse)
     1258                fixEdge<UntypedUse>(node->child1());
    12021259        }
    12031260        m_insertionSet.execute(block);
     
    13051362            return;
    13061363       
     1364        // FIXME: The way this uses alwaysUnboxSimplePrimitives() is suspicious.
     1365        // https://bugs.webkit.org/show_bug.cgi?id=121518
     1366       
    13071367        VariableAccessData* variable = node->variableAccessData();
    13081368        switch (useKind) {
     
    13201380            if (alwaysUnboxSimplePrimitives()
    13211381                || isBooleanSpeculation(variable->prediction()))
     1382                m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
     1383            break;
     1384        case MachineIntUse:
     1385            if (isMachineIntSpeculation(variable->prediction()))
    13221386                m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
    13231387            break;
     
    13481412    void fixEdge(Edge& edge, SpeculationDirection direction = BackwardSpeculation)
    13491413    {
    1350         if (isDouble(useKind) && edge->shouldSpeculateInt32ForArithmetic()) {
    1351             injectInt32ToDoubleNode(edge, useKind, direction);
     1414        if (isDouble(useKind)) {
     1415            if (edge->shouldSpeculateInt32ForArithmetic()) {
     1416                injectInt32ToDoubleNode(edge, useKind, direction);
     1417                return;
     1418            }
     1419           
     1420            if (enableInt52() && edge->shouldSpeculateMachineInt()) {
     1421                // Make all double uses of int52 values have an intermediate Int52ToDouble.
     1422                // This is for the same reason as Int52ToValue (see below) except that
     1423                // Int8ToDouble will convert int52's that fit in an int32 into a double
     1424                // rather than trying to create a boxed int32 like Int52ToValue does.
     1425               
     1426                Node* result = m_insertionSet.insertNode(
     1427                    m_indexInBlock, SpecInt52AsDouble, Int52ToDouble,
     1428                    m_currentNode->codeOrigin, Edge(edge.node(), NumberUse));
     1429                edge = Edge(result, useKind);
     1430                return;
     1431            }
     1432        }
     1433       
     1434        if (enableInt52() && useKind != MachineIntUse
     1435            && edge->shouldSpeculateMachineInt() && !edge->shouldSpeculateInt32()) {
     1436            // We make all non-int52 uses of int52 values have an intermediate Int52ToValue
     1437            // node to ensure that we handle this properly:
     1438            //
     1439            // a: SomeInt52
     1440            // b: ArithAdd(@a, ...)
     1441            // c: Call(..., @a)
     1442            // d: ArithAdd(@a, ...)
     1443            //
     1444            // Without an intermediate node and just labeling the uses, we will get:
     1445            //
     1446            // a: SomeInt52
     1447            // b: ArithAdd(Int52:@a, ...)
     1448            // c: Call(..., Untyped:@a)
     1449            // d: ArithAdd(Int52:@a, ...)
     1450            //
     1451            // And now the c->Untyped:@a edge will box the value of @a into a double. This
     1452            // is bad, because now the d->Int52:@a edge will either have to do double-to-int
     1453            // conversions, or will have to OSR exit unconditionally. Alternatively we could
     1454            // have the c->Untyped:@a edge box the value by copying rather than in-place.
     1455            // But these boxings are also costly so this wouldn't be great.
     1456            //
     1457            // The solution we use is to always have non-Int52 uses of predicted Int52's use
     1458            // an intervening Int52ToValue node:
     1459            //
     1460            // a: SomeInt52
     1461            // b: ArithAdd(Int52:@a, ...)
     1462            // x: Int52ToValue(Int52:@a)
     1463            // c: Call(..., Untyped:@x)
     1464            // d: ArithAdd(Int52:@a, ...)
     1465            //
     1466            // Note that even if we had multiple non-int52 uses of @a, the multiple
     1467            // Int52ToValue's would get CSE'd together. So the boxing would only happen once.
     1468            // At the same time, @a would continue to be represented as a native int52.
     1469            //
     1470            // An alternative would have been to insert ToNativeInt52 nodes on int52 uses of
     1471            // int52's. This would have handled the above example but would fall over for:
     1472            //
     1473            // a: SomeInt52
     1474            // b: Call(..., @a)
     1475            // c: ArithAdd(@a, ...)
     1476            //
     1477            // But the solution we use handles the above gracefully.
     1478           
     1479            Node* result = m_insertionSet.insertNode(
     1480                m_indexInBlock, SpecInt52, Int52ToValue,
     1481                m_currentNode->codeOrigin, Edge(edge.node(), UntypedUse));
     1482            edge = Edge(result, useKind);
    13521483            return;
    13531484        }
    13541485       
    13551486        observeUseKindOnNode<useKind>(edge.node());
     1487       
    13561488        edge.setUseKind(useKind);
    13571489    }
     
    13791511    {
    13801512        Node* result = m_insertionSet.insertNode(
    1381             m_indexInBlock, SpecInt48, Int32ToDouble,
     1513            m_indexInBlock, SpecInt52AsDouble, Int32ToDouble,
    13821514            m_currentNode->codeOrigin, Edge(edge.node(), NumberUse));
    13831515        if (direction == ForwardSpeculation)
     
    14351567    {
    14361568        AddSpeculationMode mode = m_graph.addSpeculationMode(node);
    1437         if (mode == DontSpeculateInt32)
    1438             return false;
    1439        
    1440         truncateConstantsIfNecessary(node, mode);
    1441         fixEdge<Int32Use>(node->child1());
    1442         fixEdge<Int32Use>(node->child2());
    1443         return true;
     1569        if (mode != DontSpeculateInt32) {
     1570            truncateConstantsIfNecessary(node, mode);
     1571            fixEdge<Int32Use>(node->child1());
     1572            fixEdge<Int32Use>(node->child2());
     1573            return true;
     1574        }
     1575       
     1576        if (m_graph.addShouldSpeculateMachineInt(node)) {
     1577            fixEdge<MachineIntUse>(node->child1());
     1578            fixEdge<MachineIntUse>(node->child2());
     1579            return true;
     1580        }
     1581       
     1582        return false;
    14441583    }
    14451584   
  • trunk/Source/JavaScriptCore/dfg/DFGFlushFormat.cpp

    r153274 r156019  
    4242        out.print("FlushedInt32");
    4343        return;
     44    case FlushedInt52:
     45        out.print("FlushedInt52");
     46        return;
    4447    case FlushedDouble:
    4548        out.print("FlushedDouble");
  • trunk/Source/JavaScriptCore/dfg/DFGFlushFormat.h

    r153296 r156019  
    4141    DeadFlush,
    4242    FlushedInt32,
     43    FlushedInt52,
    4344    FlushedDouble,
    4445    FlushedCell,
     
    5657    case FlushedInt32:
    5758        return NodeResultInt32;
     59    case FlushedInt52:
     60        return NodeResultInt52;
    5861    case FlushedDouble:
    5962        return NodeResultNumber;
     
    7578    case FlushedInt32:
    7679        return Int32Use;
     80    case FlushedInt52:
     81        return MachineIntUse;
    7782    case FlushedDouble:
    7883        return NumberUse;
  • trunk/Source/JavaScriptCore/dfg/DFGGenerationInfo.h

    r155645 r156019  
    8787        initGPR(node, useCount, gpr, DataFormatInt32);
    8888    }
     89    void initInt52(Node* node, uint32_t useCount, GPRReg reg, DataFormat format)
     90    {
     91        ASSERT(format == DataFormatInt52 || format == DataFormatStrictInt52);
     92        initGPR(node, useCount, reg, format);
     93    }
     94    void initInt52(Node* node, uint32_t useCount, GPRReg reg)
     95    {
     96        initGPR(node, useCount, reg, DataFormatInt52);
     97    }
     98    void initStrictInt52(Node* node, uint32_t useCount, GPRReg reg)
     99    {
     100        initGPR(node, useCount, reg, DataFormatStrictInt52);
     101    }
    89102#if USE(JSVALUE64)
    90103    void initJSValue(Node* node, uint32_t useCount, GPRReg gpr, DataFormat format = DataFormatJS)
     
    188201    DataFormat spillFormat() { return m_spillFormat; }
    189202   
     203    bool isFormat(DataFormat expectedFormat)
     204    {
     205        return registerFormat() == expectedFormat || spillFormat() == expectedFormat;
     206    }
     207   
    190208    bool isJSFormat(DataFormat expectedFormat)
    191209    {
     
    196214    {
    197215        return isJSFormat(DataFormatJSInt32);
     216    }
     217   
     218    bool isInt52()
     219    {
     220        return isFormat(DataFormatInt52);
     221    }
     222   
     223    bool isStrictInt52()
     224    {
     225        return isFormat(DataFormatStrictInt52);
    198226    }
    199227   
     
    314342    {
    315343        fillGPR(stream, gpr, DataFormatInt32);
     344    }
     345    void fillInt52(VariableEventStream& stream, GPRReg gpr, DataFormat format)
     346    {
     347        ASSERT(format == DataFormatInt52 || format == DataFormatStrictInt52);
     348        fillGPR(stream, gpr, format);
     349    }
     350    void fillInt52(VariableEventStream& stream, GPRReg gpr)
     351    {
     352        fillGPR(stream, gpr, DataFormatInt52);
     353    }
     354    void fillStrictInt52(VariableEventStream& stream, GPRReg gpr)
     355    {
     356        fillGPR(stream, gpr, DataFormatStrictInt52);
    316357    }
    317358    void fillBoolean(VariableEventStream& stream, GPRReg gpr)
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp

    r155564 r156019  
    237237            out.print(comma, "arg", operandToArgument(operand), "(", VariableAccessDataDump(*this, variableAccessData), ")");
    238238        else
    239             out.print(comma, "r", operand, "(", VariableAccessDataDump(*this, variableAccessData), ")");
     239            out.print(comma, "loc", operandToLocal(operand), "(", VariableAccessDataDump(*this, variableAccessData), ")");
    240240    }
    241241    if (node->hasUnlinkedLocal()) {
     
    244244            out.print(comma, "arg", operandToArgument(operand));
    245245        else
    246             out.print(comma, "r", operand);
     246            out.print(comma, "loc", operandToLocal(operand));
    247247    }
    248248    if (node->hasConstantBuffer()) {
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.h

    r155499 r156019  
    231231    bool addShouldSpeculateMachineInt(Node* add)
    232232    {
     233        if (!enableInt52())
     234            return false;
     235       
    233236        Node* left = add->child1().node();
    234237        Node* right = add->child2().node();
     
    236239        bool speculation;
    237240        if (add->op() == ValueAdd)
    238             speculation = Node::shouldSpeculateMachineIntExpectingDefined(left, right);
     241            speculation = Node::shouldSpeculateMachineInt(left, right);
    239242        else
    240             speculation = Node::shouldSpeculateMachineIntForArithmetic(left, right);
    241 
    242         return speculation && !hasExitSite(add, Int48Overflow);
     243            speculation = Node::shouldSpeculateMachineInt(left, right);
     244
     245        return speculation && !hasExitSite(add, Int52Overflow);
    243246    }
    244247   
     
    258261        ASSERT(mul->op() == ArithMul);
    259262       
     263        if (!enableInt52())
     264            return false;
     265       
    260266        Node* left = mul->child1().node();
    261267        Node* right = mul->child2().node();
    262268
    263         return Node::shouldSpeculateMachineIntForArithmetic(left, right)
    264             && mul->canSpeculateInt48()
    265             && !hasExitSite(mul, Int48Overflow);
     269        return Node::shouldSpeculateMachineInt(left, right)
     270            && mul->canSpeculateInt52()
     271            && !hasExitSite(mul, Int52Overflow);
    266272    }
    267273   
     
    275281    {
    276282        ASSERT(negate->op() == ArithNegate);
    277         return negate->child1()->shouldSpeculateMachineIntForArithmetic()
    278             && !hasExitSite(negate, Int48Overflow)
    279             && negate->canSpeculateInt48();
     283        if (!enableInt52())
     284            return false;
     285        return negate->child1()->shouldSpeculateMachineInt()
     286            && !hasExitSite(negate, Int52Overflow)
     287            && negate->canSpeculateInt52();
    280288    }
    281289   
  • trunk/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp

    r155564 r156019  
    314314            source = forNode(node->child1());
    315315            if (node->variableAccessData()->flushFormat() == FlushedDouble) {
    316                 ASSERT(!(source.m_type & ~SpecNumber));
    317                 ASSERT(!!(source.m_type & ~SpecDouble) == !!(source.m_type & SpecInt32));
     316                ASSERT(!(source.m_type & ~SpecFullNumber));
     317                ASSERT(!!(source.m_type & ~SpecDouble) == !!(source.m_type & SpecMachineInt));
    318318                if (!(source.m_type & ~SpecDouble)) {
    319                     source.merge(SpecInt48AsDouble);
     319                    source.merge(SpecInt52AsDouble);
    320320                    source.filter(SpecDouble);
    321321                }
  • trunk/Source/JavaScriptCore/dfg/DFGJITCode.cpp

    r155023 r156019  
    104104            value = jsNumber(exec->r(operand).unboxedInt32());
    105105            break;
     106        case AlreadyInJSStackAsUnboxedInt52:
     107            value = jsNumber(exec->r(operand).unboxedInt52());
     108            break;
    106109        case AlreadyInJSStackAsUnboxedDouble:
    107110            value = jsDoubleNumber(exec->r(operand).unboxedDouble());
  • trunk/Source/JavaScriptCore/dfg/DFGMinifiedNode.h

    r155793 r156019  
    4949    case DoubleAsInt32:
    5050    case PhantomArguments:
     51    case Int52ToValue:
     52    case Int52ToDouble:
    5153        return true;
    5254    default:
     
    105107        case UInt32ToNumber:
    106108        case DoubleAsInt32:
     109        case Int52ToDouble:
     110        case Int52ToValue:
    107111            return true;
    108112        default:
  • trunk/Source/JavaScriptCore/dfg/DFGNode.h

    r155499 r156019  
    12421242    bool shouldSpeculateNumber()
    12431243    {
    1244         return isNumberSpeculation(prediction());
     1244        return isFullNumberSpeculation(prediction());
    12451245    }
    12461246   
    12471247    bool shouldSpeculateNumberExpectingDefined()
    12481248    {
    1249         return isNumberSpeculationExpectingDefined(prediction());
     1249        return isFullNumberSpeculationExpectingDefined(prediction());
    12501250    }
    12511251   
     
    14251425    }
    14261426   
    1427     bool canSpeculateInt48()
    1428     {
    1429         return nodeCanSpeculateInt48(arithNodeFlags());
     1427    bool canSpeculateInt52()
     1428    {
     1429        return nodeCanSpeculateInt52(arithNodeFlags());
    14301430    }
    14311431   
  • trunk/Source/JavaScriptCore/dfg/DFGNodeFlags.h

    r155499 r156019  
    4242#define NodeResultNumber                 0x0002
    4343#define NodeResultInt32                  0x0003
    44 #define NodeResultBoolean                0x0004
    45 #define NodeResultStorage                0x0005
     44#define NodeResultInt52                  0x0004
     45#define NodeResultBoolean                0x0005
     46#define NodeResultStorage                0x0006
    4647                               
    4748#define NodeMustGenerate                 0x0008 // set on nodes that have side effects, and may not trivially be removed by DCE.
     
    108109}
    109110
    110 static inline bool nodeCanSpeculateInt48(NodeFlags flags)
     111static inline bool nodeCanSpeculateInt52(NodeFlags flags)
    111112{
    112113    if (nodeMayNegZero(flags))
  • trunk/Source/JavaScriptCore/dfg/DFGNodeType.h

    r155793 r156019  
    115115    /* Used to speculate that a double value is actually an integer. */\
    116116    macro(DoubleAsInt32, NodeResultInt32 | NodeExitsForward) \
     117    /* Used to separate representation and register allocation of Int52's represented */\
     118    /* as values. */\
     119    macro(Int52ToValue, NodeResultJS) \
     120    macro(Int52ToDouble, NodeResultNumber) \
    117121    \
    118122    /* Nodes for arithmetic operations. */\
     
    357361        return 25;
    358362       
     363    case Int52ToValue:
     364        // Loses no information. It just boxes the value, which is what OSR wants
     365        // to do anyway.
     366        return 100;
     367       
     368    case Int52ToDouble:
     369        // This is like Int32ToDouble; we can use it because it gives a semantically
     370        // equivalent value but that value may be an int32 in a double, so we'd
     371        // rather not if we can avoid it.
     372        return 75;
     373       
    359374    default:
    360375        return 0;
  • trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp

    r155995 r156019  
    4040
    4141namespace JSC { namespace DFG {
    42 
    43 static CString shortOperandsDump(const Operands<ValueRecovery>& operands)
    44 {
    45     DumpContext context;
    46     StringPrintStream out;
    47     out.print(inContext(operands, &context));
    48     return out.toCString();
    49 }
    5042
    5143extern "C" {
     
    118110                exitIndex, toCString(exit.m_codeOrigin).data(),
    119111                exitKindToString(exit.m_kind), toCString(*codeBlock).data(),
    120                 shortOperandsDump(operands).data()));
     112                toCString(ignoringContext<DumpContext>(operands)).data()));
    121113    }
    122114   
  • trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp

    r155820 r156019  
    196196        case UnboxedInt32InGPR:
    197197        case UInt32InGPR:
     198        case UnboxedInt52InGPR:
     199        case UnboxedStrictInt52InGPR:
    198200            m_jit.store64(recovery.gpr(), scratch + index);
    199201            break;
     
    236238        case Int32DisplacedInJSStack:
    237239        case DoubleDisplacedInJSStack:
     240        case Int52DisplacedInJSStack:
     241        case StrictInt52DisplacedInJSStack:
    238242            m_jit.load64(AssemblyHelpers::addressFor(recovery.virtualRegister()), GPRInfo::regT0);
    239243            m_jit.store64(GPRInfo::regT0, scratch + index);
     
    242246        case AlreadyInJSStackAsUnboxedInt32:
    243247        case AlreadyInJSStackAsUnboxedDouble:
     248        case AlreadyInJSStackAsUnboxedInt52:
    244249            m_jit.load64(AssemblyHelpers::addressFor(operand), GPRInfo::regT0);
    245250            m_jit.store64(GPRInfo::regT0, scratch + index);
     
    275280            break;
    276281           
     282        case AlreadyInJSStackAsUnboxedInt52:
     283        case UnboxedInt52InGPR:
     284        case Int52DisplacedInJSStack:
     285            m_jit.load64(scratch + index, GPRInfo::regT0);
     286            m_jit.rshift64(
     287                AssemblyHelpers::TrustedImm32(JSValue::int52ShiftAmount), GPRInfo::regT0);
     288            m_jit.boxInt52(GPRInfo::regT0, GPRInfo::regT0, GPRInfo::regT1, FPRInfo::fpRegT0);
     289            m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
     290            break;
     291           
     292        case UnboxedStrictInt52InGPR:
     293        case StrictInt52DisplacedInJSStack:
     294            m_jit.load64(scratch + index, GPRInfo::regT0);
     295            m_jit.boxInt52(GPRInfo::regT0, GPRInfo::regT0, GPRInfo::regT1, FPRInfo::fpRegT0);
     296            m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
     297            break;
     298           
     299        case UInt32InGPR:
     300            m_jit.load64(scratch + index, GPRInfo::regT0);
     301            m_jit.zeroExtend32ToPtr(GPRInfo::regT0, GPRInfo::regT0);
     302            m_jit.boxInt52(GPRInfo::regT0, GPRInfo::regT0, GPRInfo::regT1, FPRInfo::fpRegT0);
     303            m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
     304            break;
     305           
    277306        case AlreadyInJSStackAsUnboxedDouble:
    278307        case InFPR:
     
    283312            m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
    284313            break;
    285            
    286         case UInt32InGPR: {
    287             m_jit.load64(scratch + index, GPRInfo::regT0);
    288             m_jit.zeroExtend32ToPtr(GPRInfo::regT0, GPRInfo::regT0);
    289             AssemblyHelpers::Jump positive = m_jit.branch32(
    290                 AssemblyHelpers::GreaterThanOrEqual,
    291                 GPRInfo::regT0, AssemblyHelpers::TrustedImm32(0));
    292             m_jit.convertInt32ToDouble(GPRInfo::regT0, FPRInfo::fpRegT0);
    293             m_jit.addDouble(
    294                 AssemblyHelpers::AbsoluteAddress(&AssemblyHelpers::twoToThe32),
    295                 FPRInfo::fpRegT0);
    296             m_jit.boxDouble(FPRInfo::fpRegT0, GPRInfo::regT0);
    297             AssemblyHelpers::Jump done = m_jit.jump();
    298             positive.link(&m_jit);
    299             m_jit.or64(GPRInfo::tagTypeNumberRegister, GPRInfo::regT0);
    300             done.link(&m_jit);
    301             m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
    302             break;
    303         }
    304314           
    305315        case Constant:
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r155499 r156019  
    117117    SpeculatedType speculatedDoubleTypeForPrediction(SpeculatedType value)
    118118    {
    119         if (!isNumberSpeculation(value))
     119        if (!isFullNumberSpeculation(value))
    120120            return SpecDouble;
    121121        if (value & SpecDoubleNaN)
     
    143143        case WeakJSConstant: {
    144144            SpeculatedType type = speculationFromValue(m_graph.valueOfJSConstant(node));
    145             if (type == SpecInt48AsDouble)
    146                 type = SpecInt48;
     145            if (type == SpecInt52AsDouble)
     146                type = SpecInt52;
    147147            changed |= setPrediction(type);
    148148            break;
     
    150150           
    151151        case GetLocal: {
    152             VariableAccessData* variableAccessData = node->variableAccessData();
    153             SpeculatedType prediction = variableAccessData->prediction();
     152            VariableAccessData* variable = node->variableAccessData();
     153            SpeculatedType prediction = variable->prediction();
     154            if (variable->shouldNeverUnbox() && (prediction & SpecInt52))
     155                prediction = (prediction | SpecInt52AsDouble) & ~SpecInt52;
    154156            if (prediction)
    155157                changed |= mergePrediction(prediction);
     
    204206                changed |= mergePrediction(SpecInt32);
    205207            else
    206                 changed |= mergePrediction(SpecNumber);
     208                changed |= mergePrediction(SpecBytecodeNumber);
    207209            break;
    208210        }
     
    213215           
    214216            if (left && right) {
    215                 if (isNumberSpeculationExpectingDefined(left) && isNumberSpeculationExpectingDefined(right)) {
     217                if (isFullNumberSpeculationExpectingDefined(left) && isFullNumberSpeculationExpectingDefined(right)) {
    216218                    if (m_graph.addSpeculationMode(node) != DontSpeculateInt32)
    217219                        changed |= mergePrediction(SpecInt32);
    218220                    else if (m_graph.addShouldSpeculateMachineInt(node))
    219                         changed |= mergePrediction(SpecInt48);
     221                        changed |= mergePrediction(SpecInt52);
    220222                    else
    221223                        changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
    222                 } else if (!(left & SpecNumber) || !(right & SpecNumber)) {
     224                } else if (!(left & SpecFullNumber) || !(right & SpecFullNumber)) {
    223225                    // left or right is definitely something other than a number.
    224226                    changed |= mergePrediction(SpecString);
     
    237239                    changed |= mergePrediction(SpecInt32);
    238240                else if (m_graph.addShouldSpeculateMachineInt(node))
    239                     changed |= mergePrediction(SpecInt48);
     241                    changed |= mergePrediction(SpecInt52);
    240242                else
    241243                    changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
     
    252254                    changed |= mergePrediction(SpecInt32);
    253255                else if (m_graph.addShouldSpeculateMachineInt(node))
    254                     changed |= mergePrediction(SpecInt48);
     256                    changed |= mergePrediction(SpecInt52);
    255257                else
    256258                    changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
     
    264266                    changed |= mergePrediction(SpecInt32);
    265267                else if (m_graph.negateShouldSpeculateMachineInt(node))
    266                     changed |= mergePrediction(SpecInt48);
     268                    changed |= mergePrediction(SpecInt52);
    267269                else
    268270                    changed |= mergePrediction(speculatedDoubleTypeForPrediction(node->child1()->prediction()));
     
    293295                    changed |= mergePrediction(SpecInt32);
    294296                else if (m_graph.mulShouldSpeculateMachineInt(node))
    295                     changed |= mergePrediction(SpecInt48);
     297                    changed |= mergePrediction(SpecInt52);
    296298                else
    297299                    changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
     
    369371
    370372        case GetByVal: {
     373            if (!node->child1()->prediction())
     374                break;
     375            if (!node->getHeapPrediction())
     376                break;
     377           
    371378            if (node->child1()->shouldSpeculateFloat32Array()
    372379                || node->child1()->shouldSpeculateFloat64Array())
    373380                changed |= mergePrediction(SpecDouble);
    374             else
     381            else if (node->child1()->shouldSpeculateUint32Array()) {
     382                if (isInt32Speculation(node->getHeapPrediction()))
     383                    changed |= mergePrediction(SpecInt32);
     384                else
     385                    changed |= mergePrediction(SpecInt52);
     386            } else
    375387                changed |= mergePrediction(node->getHeapPrediction());
    376388            break;
     
    567579        case Unreachable:
    568580        case LoopHint:
     581        case Int52ToValue:
     582        case Int52ToDouble:
    569583            break;
    570584           
     
    641655            DoubleBallot ballot;
    642656               
    643             if (isNumberSpeculationExpectingDefined(left) && isNumberSpeculationExpectingDefined(right)
    644                 && !m_graph.addShouldSpeculateInt32(node))
     657            if (isFullNumberSpeculationExpectingDefined(left) && isFullNumberSpeculationExpectingDefined(right)
     658                && !m_graph.addShouldSpeculateInt32(node)
     659                && !m_graph.addShouldSpeculateMachineInt(node))
    645660                ballot = VoteDouble;
    646661            else
     
    658673            DoubleBallot ballot;
    659674               
    660             if (isNumberSpeculation(left) && isNumberSpeculation(right)
    661                 && !m_graph.mulShouldSpeculateInt32(node))
     675            if (isFullNumberSpeculation(left) && isFullNumberSpeculation(right)
     676                && !m_graph.mulShouldSpeculateInt32(node)
     677                && !m_graph.mulShouldSpeculateMachineInt(node))
    662678                ballot = VoteDouble;
    663679            else
     
    678694            DoubleBallot ballot;
    679695               
    680             if (isNumberSpeculation(left) && isNumberSpeculation(right)
     696            if (isFullNumberSpeculation(left) && isFullNumberSpeculation(right)
    681697                && !(Node::shouldSpeculateInt32ForArithmetic(node->child1().node(), node->child2().node()) && node->canSpeculateInt32()))
    682698                ballot = VoteDouble;
     
    707723            if (isDoubleSpeculation(prediction))
    708724                node->variableAccessData()->vote(VoteDouble);
    709             else if (!isNumberSpeculation(prediction) || isInt32Speculation(prediction))
     725            else if (
     726                !isFullNumberSpeculation(prediction)
     727                || isInt32Speculation(prediction) || isMachineIntSpeculation(prediction))
    710728                node->variableAccessData()->vote(VoteValue);
    711729            break;
  • trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h

    r155201 r156019  
    6262        case NotCellUse:
    6363        case OtherUse:
     64        case MachineIntUse:
    6465            return;
    6566           
     
    7071           
    7172        case KnownNumberUse:
    72             if (m_state.forNode(edge).m_type & ~SpecNumber)
     73            if (m_state.forNode(edge).m_type & ~SpecFullNumber)
    7374                m_result = false;
    7475            return;
     
    240241    case CheckTierUpAndOSREnter:
    241242    case LoopHint:
     243    case Int52ToDouble:
     244    case Int52ToValue:
    242245        return true;
    243246       
  • trunk/Source/JavaScriptCore/dfg/DFGSilentRegisterSavePlan.h

    r141069 r156019  
    4949    DoNothingForFill,
    5050    SetInt32Constant,
     51    SetInt52Constant,
     52    SetStrictInt52Constant,
    5153    SetBooleanConstant,
    5254    SetCellConstant,
     
    6264    Load32Payload,
    6365    Load32PayloadBoxInt,
     66    Load32PayloadConvertToInt52,
     67    Load32PayloadSignExtend,
    6468    LoadPtr,
    6569    Load64,
     70    Load64ShiftInt52Right,
     71    Load64ShiftInt52Left,
    6672    LoadDouble,
    6773    LoadDoubleBoxDouble,
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r156016 r156019  
    336336        else if (registerFormat == DataFormatCell || registerFormat == DataFormatStorage)
    337337            spillAction = StorePtr;
     338        else if (registerFormat == DataFormatInt52 || registerFormat == DataFormatStrictInt52)
     339            spillAction = Store64;
    338340        else {
    339341            ASSERT(registerFormat & DataFormatJS);
     
    387389        ASSERT(info.gpr() == source);
    388390        fillAction = LoadPtr;
     391    } else if (registerFormat == DataFormatInt52) {
     392        if (node->hasConstant())
     393            fillAction = SetInt52Constant;
     394        else if (isJSInt32(info.spillFormat()) || info.spillFormat() == DataFormatJS)
     395            fillAction = Load32PayloadConvertToInt52;
     396        else if (info.spillFormat() == DataFormatInt52)
     397            fillAction = Load64;
     398        else if (info.spillFormat() == DataFormatStrictInt52)
     399            fillAction = Load64ShiftInt52Left;
     400        else if (info.spillFormat() == DataFormatNone)
     401            fillAction = Load64;
     402        else {
     403            // Should never happen. Anything that qualifies as an int32 will never
     404            // be turned into a cell (immediate spec fail) or a double (to-double
     405            // conversions involve a separate node).
     406            RELEASE_ASSERT_NOT_REACHED();
     407            fillAction = Load64; // Make GCC happy.
     408        }
     409    } else if (registerFormat == DataFormatStrictInt52) {
     410        if (node->hasConstant())
     411            fillAction = SetStrictInt52Constant;
     412        else if (isJSInt32(info.spillFormat()) || info.spillFormat() == DataFormatJS)
     413            fillAction = Load32PayloadSignExtend;
     414        else if (info.spillFormat() == DataFormatInt52)
     415            fillAction = Load64ShiftInt52Right;
     416        else if (info.spillFormat() == DataFormatStrictInt52)
     417            fillAction = Load64;
     418        else if (info.spillFormat() == DataFormatNone)
     419            fillAction = Load64;
     420        else {
     421            // Should never happen. Anything that qualifies as an int32 will never
     422            // be turned into a cell (immediate spec fail) or a double (to-double
     423            // conversions involve a separate node).
     424            RELEASE_ASSERT_NOT_REACHED();
     425            fillAction = Load64; // Make GCC happy.
     426        }
    389427    } else {
    390428        ASSERT(registerFormat & DataFormatJS);
     
    394432            if (valueOfJSConstant(node).isCell())
    395433                fillAction = SetTrustedJSConstant;
    396             else
    397434                fillAction = SetJSConstant;
    398435        } else if (info.spillFormat() == DataFormatInt32) {
     
    513550        m_jit.move(Imm32(valueOfInt32Constant(plan.node())), plan.gpr());
    514551        break;
     552#if USE(JSVALUE64)
     553    case SetInt52Constant:
     554        m_jit.move(Imm64(valueOfJSConstant(plan.node()).asMachineInt() << JSValue::int52ShiftAmount), plan.gpr());
     555        break;
     556    case SetStrictInt52Constant:
     557        m_jit.move(Imm64(valueOfJSConstant(plan.node()).asMachineInt()), plan.gpr());
     558        break;
     559#endif // USE(JSVALUE64)
    515560    case SetBooleanConstant:
    516561        m_jit.move(TrustedImm32(valueOfBooleanConstant(plan.node())), plan.gpr());
     
    534579        m_jit.or64(GPRInfo::tagTypeNumberRegister, plan.gpr());
    535580        break;
     581    case Load32PayloadConvertToInt52:
     582        m_jit.load32(JITCompiler::payloadFor(plan.node()->virtualRegister()), plan.gpr());
     583        m_jit.signExtend32ToPtr(plan.gpr(), plan.gpr());
     584        m_jit.lshift64(TrustedImm32(JSValue::int52ShiftAmount), plan.gpr());
     585        break;
     586    case Load32PayloadSignExtend:
     587        m_jit.load32(JITCompiler::payloadFor(plan.node()->virtualRegister()), plan.gpr());
     588        m_jit.signExtend32ToPtr(plan.gpr(), plan.gpr());
     589        break;
    536590    case LoadDoubleBoxDouble:
    537591        m_jit.load64(JITCompiler::addressFor(plan.node()->virtualRegister()), plan.gpr());
     
    574628    case Load64:
    575629        m_jit.load64(JITCompiler::addressFor(plan.node()->virtualRegister()), plan.gpr());
     630        break;
     631    case Load64ShiftInt52Right:
     632        m_jit.load64(JITCompiler::addressFor(plan.node()->virtualRegister()), plan.gpr());
     633        m_jit.rshift64(TrustedImm32(JSValue::int52ShiftAmount), plan.gpr());
     634        break;
     635    case Load64ShiftInt52Left:
     636        m_jit.load64(JITCompiler::addressFor(plan.node()->virtualRegister()), plan.gpr());
     637        m_jit.lshift64(TrustedImm32(JSValue::int52ShiftAmount), plan.gpr());
    576638        break;
    577639#endif
     
    14171479        if (node->isBinaryUseKind(Int32Use))
    14181480            compilePeepHoleInt32Branch(node, branchNode, condition);
     1481#if USE(JSVALUE64)
     1482        else if (node->isBinaryUseKind(MachineIntUse))
     1483            compilePeepHoleInt52Branch(node, branchNode, condition);
     1484#endif // USE(JSVALUE64)
    14191485        else if (node->isBinaryUseKind(NumberUse))
    14201486            compilePeepHoleDoubleBranch(node, branchNode, doubleCondition);
     
    15071573            case FlushedInt32:
    15081574                valueSource = ValueSource(Int32InJSStack);
     1575                break;
     1576            case FlushedInt52:
     1577                valueSource = ValueSource(Int52InJSStack);
    15091578                break;
    15101579            case FlushedCell:
     
    18741943   
    18751944    DFG_TYPE_CHECK(
    1876         JSValueRegs(), child3, SpecRealNumber,
     1945        JSValueRegs(), child3, SpecFullRealNumber,
    18771946        m_jit.branchDouble(
    18781947            MacroAssembler::DoubleNotEqualOrUnordered, valueReg, valueReg));
     
    21502219        return;
    21512220    }
     2221       
     2222#if USE(JSVALUE64)
     2223    case MachineIntUse: {
     2224        SpeculateStrictInt52Operand op1(this, node->child1());
     2225        GPRTemporary result(this, Reuse, op1);
     2226        GPRReg op1GPR = op1.gpr();
     2227        GPRReg resultGPR = result.gpr();
     2228        m_jit.zeroExtend32ToPtr(op1GPR, resultGPR);
     2229        int32Result(resultGPR, node, DataFormatInt32);
     2230        return;
     2231    }
     2232#endif // USE(JSVALUE64)
    21522233   
    21532234    case NumberUse:
     
    21882269            if (node->child1().useKind() == NumberUse) {
    21892270                DFG_TYPE_CHECK(
    2190                     JSValueRegs(gpr), node->child1(), SpecNumber,
     2271                    JSValueRegs(gpr), node->child1(), SpecFullNumber,
    21912272                    m_jit.branchTest64(
    21922273                        MacroAssembler::Zero, gpr, GPRInfo::tagTypeNumberRegister));
     
    22442325                if (node->child1().useKind() == NumberUse) {
    22452326                    DFG_TYPE_CHECK(
    2246                         JSValueRegs(tagGPR, payloadGPR), node->child1(), SpecNumber,
     2327                        JSValueRegs(tagGPR, payloadGPR), node->child1(), SpecFullNumber,
    22472328                        m_jit.branch32(
    22482329                            MacroAssembler::AboveOrEqual, tagGPR,
     
    23902471        MacroAssembler::AboveOrEqual, op1GPR, GPRInfo::tagTypeNumberRegister);
    23912472   
    2392     if (needsTypeCheck(node->child1(), SpecNumber)) {
     2473    if (needsTypeCheck(node->child1(), SpecFullNumber)) {
    23932474        if (node->flags() & NodeExitsForward) {
    23942475            forwardTypeCheck(
    2395                 JSValueRegs(op1GPR), node->child1(), SpecNumber,
     2476                JSValueRegs(op1GPR), node->child1(), SpecFullNumber,
    23962477                m_jit.branchTest64(MacroAssembler::Zero, op1GPR, GPRInfo::tagTypeNumberRegister),
    23972478                ValueRecovery::inGPR(op1GPR, DataFormatJS));
    23982479        } else {
    23992480            backwardTypeCheck(
    2400                 JSValueRegs(op1GPR), node->child1(), SpecNumber,
     2481                JSValueRegs(op1GPR), node->child1(), SpecFullNumber,
    24012482                m_jit.branchTest64(MacroAssembler::Zero, op1GPR, GPRInfo::tagTypeNumberRegister));
    24022483        }
     
    24212502        MacroAssembler::Equal, op1TagGPR, TrustedImm32(JSValue::Int32Tag));
    24222503   
    2423     if (needsTypeCheck(node->child1(), SpecNumber)) {
     2504    if (needsTypeCheck(node->child1(), SpecFullNumber)) {
    24242505        if (node->flags() & NodeExitsForward) {
    24252506            forwardTypeCheck(
    2426                 JSValueRegs(op1TagGPR, op1PayloadGPR), node->child1(), SpecNumber,
     2507                JSValueRegs(op1TagGPR, op1PayloadGPR), node->child1(), SpecFullNumber,
    24272508                m_jit.branch32(MacroAssembler::AboveOrEqual, op1TagGPR, TrustedImm32(JSValue::LowestTag)),
    24282509                ValueRecovery::inPair(op1TagGPR, op1PayloadGPR));
    24292510        } else {
    24302511            backwardTypeCheck(
    2431                 JSValueRegs(op1TagGPR, op1PayloadGPR), node->child1(), SpecNumber,
     2512                JSValueRegs(op1TagGPR, op1PayloadGPR), node->child1(), SpecFullNumber,
    24322513                m_jit.branch32(MacroAssembler::AboveOrEqual, op1TagGPR, TrustedImm32(JSValue::LowestTag)));
    24332514        }
     
    25492630        return;
    25502631    }
     2632   
     2633#if USE(JSVALUE64)
     2634    if (node->shouldSpeculateMachineInt()) {
     2635        m_jit.zeroExtend32ToPtr(resultReg, resultReg);
     2636        strictInt52Result(resultReg, node);
     2637        return;
     2638    }
     2639#endif
    25512640   
    25522641    FPRTemporary fresult(this);
     
    26022691            break;
    26032692        }
     2693           
     2694#if USE(JSVALUE64)
     2695        case MachineIntUse: {
     2696            SpeculateStrictInt52Operand valueOp(this, valueUse);
     2697            GPRTemporary scratch(this);
     2698            GPRReg scratchReg = scratch.gpr();
     2699            m_jit.move(valueOp.gpr(), scratchReg);
     2700            if (isClamped(type)) {
     2701                ASSERT(elementSize(type) == 1);
     2702                MacroAssembler::Jump inBounds = m_jit.branch64(
     2703                    MacroAssembler::BelowOrEqual, scratchReg, JITCompiler::TrustedImm64(0xff));
     2704                MacroAssembler::Jump tooBig = m_jit.branch64(
     2705                    MacroAssembler::GreaterThan, scratchReg, JITCompiler::TrustedImm64(0xff));
     2706                m_jit.move(TrustedImm32(0), scratchReg);
     2707                MacroAssembler::Jump clamped = m_jit.jump();
     2708                tooBig.link(&m_jit);
     2709                m_jit.move(JITCompiler::TrustedImm32(255), scratchReg);
     2710                clamped.link(&m_jit);
     2711                inBounds.link(&m_jit);
     2712            }
     2713            value.adopt(scratch);
     2714            valueGPR = scratchReg;
     2715            break;
     2716        }
     2717#endif // USE(JSVALUE64)
    26042718           
    26052719        case NumberUse: {
     
    28712985            return;
    28722986        }
    2873                
     2987       
    28742988        if (isNumberConstant(node->child2().node())) {
    28752989            SpeculateInt32Operand op1(this, node->child1());
     
    29163030        return;
    29173031    }
     3032       
     3033#if USE(JSVALUE64)
     3034    case MachineIntUse: {
     3035        // Will we need an overflow check? If we can prove that neither input can be
     3036        // Int52 then the overflow check will not be necessary.
     3037        if (!m_state.forNode(node->child1()).couldBeType(SpecInt52)
     3038            && !m_state.forNode(node->child2()).couldBeType(SpecInt52)) {
     3039            SpeculateWhicheverInt52Operand op1(this, node->child1());
     3040            SpeculateWhicheverInt52Operand op2(this, node->child2(), op1);
     3041            GPRTemporary result(this, Reuse, op1);
     3042            m_jit.move(op1.gpr(), result.gpr());
     3043            m_jit.add64(op2.gpr(), result.gpr());
     3044            int52Result(result.gpr(), node, op1.format());
     3045            return;
     3046        }
     3047       
     3048        SpeculateInt52Operand op1(this, node->child1());
     3049        SpeculateInt52Operand op2(this, node->child2());
     3050        GPRTemporary result(this, Reuse, op1, op2);
     3051        m_jit.move(op1.gpr(), result.gpr());
     3052        speculationCheck(
     3053            Int52Overflow, JSValueRegs(), 0,
     3054            m_jit.branchAdd64(MacroAssembler::Overflow, op2.gpr(), result.gpr()));
     3055        int52Result(result.gpr(), node);
     3056        return;
     3057    }
     3058#endif // USE(JSVALUE64)
    29183059   
    29193060    case NumberUse: {
     
    30613202    }
    30623203       
     3204#if USE(JSVALUE64)
     3205    case MachineIntUse: {
     3206        // Will we need an overflow check? If we can prove that neither input can be
     3207        // Int52 then the overflow check will not be necessary.
     3208        if (!m_state.forNode(node->child1()).couldBeType(SpecInt52)
     3209            && !m_state.forNode(node->child2()).couldBeType(SpecInt52)) {
     3210            SpeculateWhicheverInt52Operand op1(this, node->child1());
     3211            SpeculateWhicheverInt52Operand op2(this, node->child2(), op1);
     3212            GPRTemporary result(this, Reuse, op1);
     3213            m_jit.move(op1.gpr(), result.gpr());
     3214            m_jit.sub64(op2.gpr(), result.gpr());
     3215            int52Result(result.gpr(), node, op1.format());
     3216            return;
     3217        }
     3218       
     3219        SpeculateInt52Operand op1(this, node->child1());
     3220        SpeculateInt52Operand op2(this, node->child2());
     3221        GPRTemporary result(this, Reuse, op1, op2);
     3222        m_jit.move(op1.gpr(), result.gpr());
     3223        speculationCheck(
     3224            Int52Overflow, JSValueRegs(), 0,
     3225            m_jit.branchSub64(MacroAssembler::Overflow, op2.gpr(), result.gpr()));
     3226        int52Result(result.gpr(), node);
     3227        return;
     3228    }
     3229#endif // USE(JSVALUE64)
     3230
    30633231    case NumberUse: {
    30643232        SpeculateDoubleOperand op1(this, node->child1());
     
    30893257        m_jit.move(op1.gpr(), result.gpr());
    30903258
     3259        // Note: there is no notion of being not used as a number, but someone
     3260        // caring about negative zero.
     3261       
    30913262        if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
    30923263            m_jit.neg32(result.gpr());
     
    31013272        return;
    31023273    }
     3274
     3275#if USE(JSVALUE64)
     3276    case MachineIntUse: {
     3277        if (!m_state.forNode(node->child1()).couldBeType(SpecInt52)) {
     3278            SpeculateWhicheverInt52Operand op1(this, node->child1());
     3279            GPRTemporary result(this);
     3280            GPRReg op1GPR = op1.gpr();
     3281            GPRReg resultGPR = result.gpr();
     3282            m_jit.move(op1GPR, resultGPR);
     3283            m_jit.neg64(resultGPR);
     3284            if (!bytecodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
     3285                speculationCheck(
     3286                    NegativeZero, JSValueRegs(), 0,
     3287                    m_jit.branchTest64(MacroAssembler::Zero, resultGPR));
     3288            }
     3289            int52Result(resultGPR, node, op1.format());
     3290            return;
     3291        }
     3292       
     3293        SpeculateInt52Operand op1(this, node->child1());
     3294        GPRTemporary result(this);
     3295        GPRReg op1GPR = op1.gpr();
     3296        GPRReg resultGPR = result.gpr();
     3297        m_jit.move(op1GPR, resultGPR);
     3298        speculationCheck(
     3299            Int52Overflow, JSValueRegs(), 0,
     3300            m_jit.branchNeg64(MacroAssembler::Overflow, resultGPR));
     3301        if (!bytecodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
     3302            speculationCheck(
     3303                NegativeZero, JSValueRegs(), 0,
     3304                m_jit.branchTest64(MacroAssembler::Zero, resultGPR));
     3305        }
     3306        int52Result(resultGPR, node);
     3307        return;
     3308    }
     3309#endif // USE(JSVALUE64)
    31033310       
    31043311    case NumberUse: {
     
    31663373        return;
    31673374    }
     3375   
     3376#if USE(JSVALUE64)   
     3377    case MachineIntUse: {
     3378        // This is super clever. We want to do an int52 multiplication and check the
     3379        // int52 overflow bit. There is no direct hardware support for this, but we do
     3380        // have the ability to do an int64 multiplication and check the int64 overflow
     3381        // bit. We leverage that. Consider that a, b are int52 numbers inside int64
     3382        // registers, with the high 12 bits being sign-extended. We can do:
     3383        //
     3384        //     (a * (b << 12))
     3385        //
     3386        // This will give us a left-shifted int52 (value is in high 52 bits, low 16
     3387        // bits are zero) plus the int52 overflow bit. I.e. whether this 64-bit
     3388        // multiplication overflows is identical to whether the 'a * b' 52-bit
     3389        // multiplication overflows.
     3390        //
     3391        // In our nomenclature, this is:
     3392        //
     3393        //     strictInt52(a) * int52(b) => int52
     3394        //
     3395        // That is "strictInt52" means unshifted and "int52" means left-shifted by 16
     3396        // bits.
     3397        //
     3398        // We don't care which of op1 or op2 serves as the left-shifted operand, so
     3399        // we just do whatever is more convenient for op1 and have op2 do the
     3400        // opposite. This ensures that we do at most one shift.
     3401
     3402        SpeculateWhicheverInt52Operand op1(this, node->child1());
     3403        SpeculateWhicheverInt52Operand op2(this, node->child2(), OppositeShift, op1);
     3404        GPRTemporary result(this);
     3405       
     3406        GPRReg op1GPR = op1.gpr();
     3407        GPRReg op2GPR = op2.gpr();
     3408        GPRReg resultGPR = result.gpr();
     3409       
     3410        m_jit.move(op1GPR, resultGPR);
     3411        speculationCheck(
     3412            Int52Overflow, JSValueRegs(), 0,
     3413            m_jit.branchMul64(MacroAssembler::Overflow, op2GPR, resultGPR));
     3414       
     3415        if (!bytecodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
     3416            MacroAssembler::Jump resultNonZero = m_jit.branchTest64(
     3417                MacroAssembler::NonZero, resultGPR);
     3418            speculationCheck(
     3419                NegativeZero, JSValueRegs(), 0,
     3420                m_jit.branch64(MacroAssembler::LessThan, op1GPR, TrustedImm64(0)));
     3421            speculationCheck(
     3422                NegativeZero, JSValueRegs(), 0,
     3423                m_jit.branch64(MacroAssembler::LessThan, op2GPR, TrustedImm64(0)));
     3424            resultNonZero.link(&m_jit);
     3425        }
     3426       
     3427        int52Result(resultGPR, node);
     3428        return;
     3429    }
     3430#endif // USE(JSVALUE64)
    31683431       
    31693432    case NumberUse: {
     
    35893852        return false;
    35903853    }
    3591 
     3854   
     3855#if USE(JSVALUE64)
     3856    if (node->isBinaryUseKind(MachineIntUse)) {
     3857        compileInt52Compare(node, condition);
     3858        return false;
     3859    }
     3860#endif // USE(JSVALUE64)
     3861   
    35923862    if (node->isBinaryUseKind(NumberUse)) {
    35933863        compileDoubleCompare(node, doubleCondition);
     
    37394009        return false;
    37404010    }
     4011   
     4012#if USE(JSVALUE64)   
     4013    case MachineIntUse: {
     4014        unsigned branchIndexInBlock = detectPeepHoleBranch();
     4015        if (branchIndexInBlock != UINT_MAX) {
     4016            Node* branchNode = m_block->at(branchIndexInBlock);
     4017            compilePeepHoleInt52Branch(node, branchNode, MacroAssembler::Equal);
     4018            use(node->child1());
     4019            use(node->child2());
     4020            m_indexInBlock = branchIndexInBlock;
     4021            m_currentNode = branchNode;
     4022            return true;
     4023        }
     4024        compileInt52Compare(node, MacroAssembler::Equal);
     4025        return false;
     4026    }
     4027#endif // USE(JSVALUE64)
    37414028       
    37424029    case NumberUse: {
     
    44944781}
    44954782
     4783void SpeculativeJIT::speculateMachineInt(Edge edge)
     4784{
     4785#if USE(JSVALUE64)
     4786    if (!needsTypeCheck(edge, SpecMachineInt))
     4787        return;
     4788   
     4789    (SpeculateWhicheverInt52Operand(this, edge)).gpr();
     4790#else // USE(JSVALUE64)
     4791    UNUSED_PARAM(edge);
     4792    UNREACHABLE_FOR_PLATFORM();
     4793#endif // USE(JSVALUE64)
     4794}
     4795
    44964796void SpeculativeJIT::speculateNumber(Edge edge)
    44974797{
    4498     if (!needsTypeCheck(edge, SpecNumber))
     4798    if (!needsTypeCheck(edge, SpecFullNumber))
    44994799        return;
    45004800   
     
    45044804void SpeculativeJIT::speculateRealNumber(Edge edge)
    45054805{
    4506     if (!needsTypeCheck(edge, SpecRealNumber))
     4806    if (!needsTypeCheck(edge, SpecFullRealNumber))
    45074807        return;
    45084808   
     
    45104810    FPRReg fpr = operand.fpr();
    45114811    DFG_TYPE_CHECK(
    4512         JSValueRegs(), edge, SpecRealNumber,
     4812        JSValueRegs(), edge, SpecFullRealNumber,
    45134813        m_jit.branchDouble(
    45144814            MacroAssembler::DoubleNotEqualOrUnordered, fpr, fpr));
     
    47725072        break;
    47735073    case KnownNumberUse:
    4774         ASSERT(!needsTypeCheck(edge, SpecNumber));
     5074        ASSERT(!needsTypeCheck(edge, SpecFullNumber));
    47755075        break;
    47765076    case KnownCellUse:
     
    47825082    case Int32Use:
    47835083        speculateInt32(edge);
     5084        break;
     5085    case MachineIntUse:
     5086        speculateMachineInt(edge);
    47845087        break;
    47855088    case RealNumberUse:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r155783 r156019  
    160160    bool canReuse(Node* node)
    161161    {
    162         VirtualRegister virtualRegister = node->virtualRegister();
    163         GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
    164         return info.canReuse();
     162        return generationInfo(node).canReuse();
    165163    }
    166164    bool canReuse(Edge nodeUse)
     
    238236    bool isFilled(Node* node)
    239237    {
    240         VirtualRegister virtualRegister = node->virtualRegister();
    241         GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
    242         return info.registerFormat() != DataFormatNone;
     238        return generationInfo(node).registerFormat() != DataFormatNone;
    243239    }
    244240    bool isFilledDouble(Node* node)
    245241    {
    246         VirtualRegister virtualRegister = node->virtualRegister();
    247         GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
    248         return info.registerFormat() == DataFormatDouble;
     242        return generationInfo(node).registerFormat() == DataFormatDouble;
    249243    }
    250244
     
    254248        if (!node->hasResult())
    255249            return;
    256         VirtualRegister virtualRegister = node->virtualRegister();
    257         GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
     250        GenerationInfo& info = generationInfo(node);
    258251
    259252        // use() returns true when the value becomes dead, and any
     
    334327    GPRReg fillSpeculateInt32(Edge, DataFormat& returnFormat);
    335328    GPRReg fillSpeculateInt32Strict(Edge);
     329    GPRReg fillSpeculateInt52(Edge, DataFormat desiredFormat);
    336330    FPRReg fillSpeculateDouble(Edge);
    337331    GPRReg fillSpeculateCell(Edge);
     
    469463        return boxDouble(fpr, allocate());
    470464    }
     465   
     466    void boxInt52(GPRReg sourceGPR, GPRReg targetGPR, DataFormat);
    471467#elif USE(JSVALUE32_64)
    472468    void boxDouble(FPRReg fpr, GPRReg tagGPR, GPRReg payloadGPR)
     
    560556    }
    561557   
    562     bool isKnownInteger(Node* node) { return !(m_state.forNode(node).m_type & ~SpecInt32); }
    563     bool isKnownCell(Node* node) { return !(m_state.forNode(node).m_type & ~SpecCell); }
     558    bool isKnownInteger(Node* node) { return m_state.forNode(node).isType(SpecInt32); }
     559    bool isKnownCell(Node* node) { return m_state.forNode(node).isType(SpecCell); }
    564560   
    565561    bool isKnownNotInteger(Node* node) { return !(m_state.forNode(node).m_type & SpecInt32); }
    566     bool isKnownNotNumber(Node* node) { return !(m_state.forNode(node).m_type & SpecNumber); }
     562    bool isKnownNotNumber(Node* node) { return !(m_state.forNode(node).m_type & SpecFullNumber); }
    567563    bool isKnownNotCell(Node* node) { return !(m_state.forNode(node).m_type & SpecCell); }
    568564   
     
    817813        int32Result(reg, node, DataFormatInt32, mode);
    818814    }
     815    void int52Result(GPRReg reg, Node* node, DataFormat format, UseChildrenMode mode = CallUseChildren)
     816    {
     817        if (mode == CallUseChildren)
     818            useChildren(node);
     819
     820        VirtualRegister virtualRegister = node->virtualRegister();
     821        GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
     822
     823        m_gprs.retain(reg, virtualRegister, SpillOrderJS);
     824        info.initInt52(node, node->refCount(), reg, format);
     825    }
     826    void int52Result(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
     827    {
     828        int52Result(reg, node, DataFormatInt52, mode);
     829    }
     830    void strictInt52Result(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
     831    {
     832        int52Result(reg, node, DataFormatStrictInt52, mode);
     833    }
    819834    void noResult(Node* node, UseChildrenMode mode = CallUseChildren)
    820835    {
     
    901916    {
    902917        ASSERT(isInt32Constant(node) || isNumberConstant(node) || isJSConstant(node));
    903         generationInfoFromVirtualRegister(node->virtualRegister()).initConstant(node, node->refCount());
     918        generationInfo(node).initConstant(node, node->refCount());
    904919    }
    905920   
     
    18901905            return true;
    18911906
    1892         VirtualRegister virtualRegister = node->virtualRegister();
    1893         GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
    1894        
    1895         return info.isJSInt32();
     1907        return generationInfo(node).isJSInt32();
     1908    }
     1909   
     1910    bool betterUseStrictInt52(Node* node)
     1911    {
     1912        return !generationInfo(node).isInt52();
     1913    }
     1914    bool betterUseStrictInt52(Edge edge)
     1915    {
     1916        return betterUseStrictInt52(edge.node());
    18961917    }
    18971918   
     
    18991920    bool compilePeepHoleBranch(Node*, MacroAssembler::RelationalCondition, MacroAssembler::DoubleCondition, S_DFGOperation_EJJ);
    19001921    void compilePeepHoleInt32Branch(Node*, Node* branchNode, JITCompiler::RelationalCondition);
     1922    void compilePeepHoleInt52Branch(Node*, Node* branchNode, JITCompiler::RelationalCondition);
    19011923    void compilePeepHoleBooleanBranch(Node*, Node* branchNode, JITCompiler::RelationalCondition);
    19021924    void compilePeepHoleDoubleBranch(Node*, Node* branchNode, JITCompiler::DoubleCondition);
     
    19461968   
    19471969    void compileInt32Compare(Node*, MacroAssembler::RelationalCondition);
     1970    void compileInt52Compare(Node*, MacroAssembler::RelationalCondition);
    19481971    void compileBooleanCompare(Node*, MacroAssembler::RelationalCondition);
    19491972    void compileDoubleCompare(Node*, MacroAssembler::DoubleCondition);
     
    21192142
    21202143    void speculateInt32(Edge);
     2144    void speculateMachineInt(Edge);
    21212145    void speculateNumber(Edge);
    21222146    void speculateRealNumber(Edge);
     
    21962220        return m_generationInfo[operandToLocal(virtualRegister)];
    21972221    }
     2222   
     2223    GenerationInfo& generationInfo(Node* node)
     2224    {
     2225        return generationInfoFromVirtualRegister(node->virtualRegister());
     2226    }
     2227   
     2228    GenerationInfo& generationInfo(Edge edge)
     2229    {
     2230        return generationInfo(edge.node());
     2231    }
    21982232
    21992233    // The JIT, while also provides MacroAssembler functionality.
     
    26772711};
    26782712
     2713// Gives you a canonical Int52 (i.e. it's left-shifted by 16, low bits zero).
     2714class SpeculateInt52Operand {
     2715public:
     2716    explicit SpeculateInt52Operand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
     2717        : m_jit(jit)
     2718        , m_edge(edge)
     2719        , m_gprOrInvalid(InvalidGPRReg)
     2720    {
     2721        ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == MachineIntUse);
     2722        if (jit->isFilled(node()))
     2723            gpr();
     2724    }
     2725   
     2726    ~SpeculateInt52Operand()
     2727    {
     2728        ASSERT(m_gprOrInvalid != InvalidGPRReg);
     2729        m_jit->unlock(m_gprOrInvalid);
     2730    }
     2731   
     2732    Edge edge() const
     2733    {
     2734        return m_edge;
     2735    }
     2736   
     2737    Node* node() const
     2738    {
     2739        return edge().node();
     2740    }
     2741   
     2742    GPRReg gpr()
     2743    {
     2744        if (m_gprOrInvalid == InvalidGPRReg)
     2745            m_gprOrInvalid = m_jit->fillSpeculateInt52(edge(), DataFormatInt52);
     2746        return m_gprOrInvalid;
     2747    }
     2748   
     2749    void use()
     2750    {
     2751        m_jit->use(node());
     2752    }
     2753   
     2754private:
     2755    SpeculativeJIT* m_jit;
     2756    Edge m_edge;
     2757    GPRReg m_gprOrInvalid;
     2758};
     2759
     2760// Gives you a strict Int52 (i.e. the payload is in the low 48 bits, high 16 bits are sign-extended).
     2761class SpeculateStrictInt52Operand {
     2762public:
     2763    explicit SpeculateStrictInt52Operand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
     2764        : m_jit(jit)
     2765        , m_edge(edge)
     2766        , m_gprOrInvalid(InvalidGPRReg)
     2767    {
     2768        ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == MachineIntUse);
     2769        if (jit->isFilled(node()))
     2770            gpr();
     2771    }
     2772   
     2773    ~SpeculateStrictInt52Operand()
     2774    {
     2775        ASSERT(m_gprOrInvalid != InvalidGPRReg);
     2776        m_jit->unlock(m_gprOrInvalid);
     2777    }
     2778   
     2779    Edge edge() const
     2780    {
     2781        return m_edge;
     2782    }
     2783   
     2784    Node* node() const
     2785    {
     2786        return edge().node();
     2787    }
     2788   
     2789    GPRReg gpr()
     2790    {
     2791        if (m_gprOrInvalid == InvalidGPRReg)
     2792            m_gprOrInvalid = m_jit->fillSpeculateInt52(edge(), DataFormatStrictInt52);
     2793        return m_gprOrInvalid;
     2794    }
     2795   
     2796    void use()
     2797    {
     2798        m_jit->use(node());
     2799    }
     2800   
     2801private:
     2802    SpeculativeJIT* m_jit;
     2803    Edge m_edge;
     2804    GPRReg m_gprOrInvalid;
     2805};
     2806
     2807enum OppositeShiftTag { OppositeShift };
     2808
     2809class SpeculateWhicheverInt52Operand {
     2810public:
     2811    explicit SpeculateWhicheverInt52Operand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
     2812        : m_jit(jit)
     2813        , m_edge(edge)
     2814        , m_gprOrInvalid(InvalidGPRReg)
     2815        , m_strict(jit->betterUseStrictInt52(edge))
     2816    {
     2817        ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == MachineIntUse);
     2818        if (jit->isFilled(node()))
     2819            gpr();
     2820    }
     2821   
     2822    explicit SpeculateWhicheverInt52Operand(SpeculativeJIT* jit, Edge edge, const SpeculateWhicheverInt52Operand& other, OperandSpeculationMode mode = AutomaticOperandSpeculation)
     2823        : m_jit(jit)
     2824        , m_edge(edge)
     2825        , m_gprOrInvalid(InvalidGPRReg)
     2826        , m_strict(other.m_strict)
     2827    {
     2828        ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == MachineIntUse);
     2829        if (jit->isFilled(node()))
     2830            gpr();
     2831    }
     2832   
     2833    explicit SpeculateWhicheverInt52Operand(SpeculativeJIT* jit, Edge edge, OppositeShiftTag, const SpeculateWhicheverInt52Operand& other, OperandSpeculationMode mode = AutomaticOperandSpeculation)
     2834        : m_jit(jit)
     2835        , m_edge(edge)
     2836        , m_gprOrInvalid(InvalidGPRReg)
     2837        , m_strict(!other.m_strict)
     2838    {
     2839        ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == MachineIntUse);
     2840        if (jit->isFilled(node()))
     2841            gpr();
     2842    }
     2843   
     2844    ~SpeculateWhicheverInt52Operand()
     2845    {
     2846        ASSERT(m_gprOrInvalid != InvalidGPRReg);
     2847        m_jit->unlock(m_gprOrInvalid);
     2848    }
     2849   
     2850    Edge edge() const
     2851    {
     2852        return m_edge;
     2853    }
     2854   
     2855    Node* node() const
     2856    {
     2857        return edge().node();
     2858    }
     2859   
     2860    GPRReg gpr()
     2861    {
     2862        if (m_gprOrInvalid == InvalidGPRReg) {
     2863            m_gprOrInvalid = m_jit->fillSpeculateInt52(
     2864                edge(), m_strict ? DataFormatStrictInt52 : DataFormatInt52);
     2865        }
     2866        return m_gprOrInvalid;
     2867    }
     2868   
     2869    void use()
     2870    {
     2871        m_jit->use(node());
     2872    }
     2873   
     2874    DataFormat format() const
     2875    {
     2876        return m_strict ? DataFormatStrictInt52 : DataFormatInt52;
     2877    }
     2878
     2879private:
     2880    SpeculativeJIT* m_jit;
     2881    Edge m_edge;
     2882    GPRReg m_gprOrInvalid;
     2883    bool m_strict;
     2884};
     2885
    26792886class SpeculateDoubleOperand {
    26802887public:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r155783 r156019  
    889889    AbstractValue& value = m_state.forNode(edge);
    890890    SpeculatedType type = value.m_type;
    891     ASSERT(edge.useKind() != KnownNumberUse || !(value.m_type & ~SpecNumber));
    892     m_interpreter.filter(value, SpecNumber);
     891    ASSERT(edge.useKind() != KnownNumberUse || !(value.m_type & ~SpecFullNumber));
     892    m_interpreter.filter(value, SpecFullNumber);
    893893    VirtualRegister virtualRegister = edge->virtualRegister();
    894894    GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
     
    929929            if (spillFormat != DataFormatJSInt32 && spillFormat != DataFormatInt32) {
    930930                JITCompiler::Jump isInteger = m_jit.branch32(MacroAssembler::Equal, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::Int32Tag));
    931                 if (type & ~SpecNumber)
     931                if (type & ~SpecFullNumber)
    932932                    speculationCheck(BadType, JSValueSource(JITCompiler::addressFor(virtualRegister)), edge, m_jit.branch32(MacroAssembler::AboveOrEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::LowestTag)));
    933933                m_jit.loadDouble(JITCompiler::addressFor(virtualRegister), fpr);
     
    964964            FPRTemporary scratch(this);
    965965            JITCompiler::Jump isInteger = m_jit.branch32(MacroAssembler::Equal, tagGPR, TrustedImm32(JSValue::Int32Tag));
    966             if (type & ~SpecNumber)
     966            if (type & ~SpecFullNumber)
    967967                speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), edge, m_jit.branch32(MacroAssembler::AboveOrEqual, tagGPR, TrustedImm32(JSValue::LowestTag)));
    968968            unboxDouble(tagGPR, payloadGPR, fpr, scratch.fpr());
     
    29242924
    29252925            DFG_TYPE_CHECK(
    2926                 JSValueRegs(), node->child2(), SpecRealNumber,
     2926                JSValueRegs(), node->child2(), SpecFullRealNumber,
    29272927                m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, valueFPR, valueFPR));
    29282928           
     
    31883188        op1.use();
    31893189       
    3190         if (!(m_state.forNode(node->child1()).m_type & ~(SpecNumber | SpecBoolean))) {
     3190        if (!(m_state.forNode(node->child1()).m_type & ~(SpecFullNumber | SpecBoolean))) {
    31913191            m_jit.move(op1TagGPR, resultTagGPR);
    31923192            m_jit.move(op1PayloadGPR, resultPayloadGPR);
     
    32903290                    FPRReg opFPR = operand.fpr();
    32913291                    DFG_TYPE_CHECK(
    3292                         JSValueRegs(), use, SpecRealNumber,
     3292                        JSValueRegs(), use, SpecFullRealNumber,
    32933293                        m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR));
    32943294       
     
    33553355                FPRReg opFPR = operand.fpr();
    33563356                DFG_TYPE_CHECK(
    3357                     JSValueRegs(), use, SpecRealNumber,
     3357                    JSValueRegs(), use, SpecFullRealNumber,
    33583358                    m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR));
    33593359               
     
    47984798    case CheckTierUpAtReturn:
    47994799    case CheckTierUpAndOSREnter:
     4800    case Int52ToDouble:
     4801    case Int52ToValue:
    48004802        RELEASE_ASSERT_NOT_REACHED();
    48014803        break;
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r155783 r156019  
    4141#if USE(JSVALUE64)
    4242
     43void SpeculativeJIT::boxInt52(GPRReg sourceGPR, GPRReg targetGPR, DataFormat format)
     44{
     45    GPRReg tempGPR;
     46    if (sourceGPR == targetGPR)
     47        tempGPR = allocate();
     48    else
     49        tempGPR = targetGPR;
     50   
     51    FPRReg fpr = fprAllocate();
     52
     53    if (format == DataFormatInt52)
     54        m_jit.rshift64(TrustedImm32(JSValue::int52ShiftAmount), sourceGPR);
     55    else
     56        ASSERT(format == DataFormatStrictInt52);
     57   
     58    m_jit.boxInt52(sourceGPR, targetGPR, tempGPR, fpr);
     59   
     60    if (tempGPR != targetGPR)
     61        unlock(tempGPR);
     62   
     63    unlock(fpr);
     64}
     65
    4366GPRReg SpeculativeJIT::fillJSValue(Edge edge)
    4467{
     
    7093            DataFormat spillFormat = info.spillFormat();
    7194            m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
    72             if (spillFormat == DataFormatInt32) {
     95            switch (spillFormat) {
     96            case DataFormatInt32: {
    7397                m_jit.load32(JITCompiler::addressFor(virtualRegister), gpr);
    7498                m_jit.or64(GPRInfo::tagTypeNumberRegister, gpr);
    7599                spillFormat = DataFormatJSInt32;
    76             } else {
     100                break;
     101            }
     102               
     103            case DataFormatInt52:
     104            case DataFormatStrictInt52: {
     105                m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
     106                boxInt52(gpr, gpr, spillFormat);
     107                return gpr;
     108            }
     109               
     110            default:
    77111                m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
    78112                if (spillFormat == DataFormatDouble) {
     
    82116                } else
    83117                    RELEASE_ASSERT(spillFormat & DataFormatJS);
     118                break;
    84119            }
    85120            info.fillJSValue(*m_stream, gpr, spillFormat);
     
    113148
    114149        return gpr;
     150    }
     151       
     152    case DataFormatInt52:
     153    case DataFormatStrictInt52: {
     154        GPRReg gpr = info.gpr();
     155        lock(gpr);
     156        GPRReg resultGPR = allocate();
     157        boxInt52(gpr, resultGPR, info.registerFormat());
     158        unlock(gpr);
     159        return resultGPR;
    115160    }
    116161
     
    769814        DataFormat spillFormat = info.spillFormat();
    770815       
    771         RELEASE_ASSERT((spillFormat & DataFormatJS) || spillFormat == DataFormatInt32);
     816        RELEASE_ASSERT((spillFormat & DataFormatJS) || spillFormat == DataFormatInt32 || spillFormat == DataFormatInt52 || spillFormat == DataFormatStrictInt52);
    772817       
    773818        m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
     
    790835            return gpr;
    791836        }
     837        if (spillFormat == DataFormatInt52 || spillFormat == DataFormatStrictInt52) {
     838            // Generally, this can only happen if we've already proved that the
     839            // value is an int32. That's because if a value originated as a JSValue
     840            // then we would speculate that it's an int32 before representing it as
     841            // an int52. Otherwise, if we knowingly produced an int52, then we would
     842            // be boxing it into a value using Int52ToValue. This assertion is valid
     843            // only because Int52 is something that we introduce at prediction time.
     844            // However: we may have an int32-producing node replaced by an
     845            // int52-producing node due to CSE. So we must do a check.
     846            RELEASE_ASSERT(!(type & ~SpecMachineInt));
     847            if (type & SpecInt52) {
     848                GPRReg temp = allocate();
     849                m_jit.signExtend32ToPtr(gpr, temp);
     850                // Currently, we can't supply value profiling information here. :-/
     851                speculationCheck(
     852                    BadType, JSValueRegs(), 0,
     853                    m_jit.branch64(MacroAssembler::NotEqual, gpr, temp));
     854                unlock(temp);
     855            }
     856            if (spillFormat == DataFormatStrictInt52)
     857                m_jit.load32(JITCompiler::addressFor(virtualRegister), gpr);
     858            else {
     859                m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
     860                m_jit.rshift64(TrustedImm32(JSValue::int52ShiftAmount), gpr);
     861                m_jit.zeroExtend32ToPtr(gpr, gpr);
     862            }
     863            info.fillInt32(*m_stream, gpr);
     864            returnFormat = DataFormatInt32;
     865            return gpr;
     866        }
    792867        m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
    793868
     
    798873
    799874    case DataFormatJS: {
     875        RELEASE_ASSERT(!(type & SpecInt52));
    800876        // Check the value is an integer.
    801877        GPRReg gpr = info.gpr();
     
    844920        return gpr;
    845921    }
     922       
     923    case DataFormatStrictInt52:
     924    case DataFormatInt52: {
     925        GPRReg gpr = info.gpr();
     926        GPRReg result;
     927        if (m_gprs.isLocked(gpr)) {
     928            result = allocate();
     929            m_jit.move(gpr, result);
     930        } else {
     931            lock(gpr);
     932            info.fillInt32(*m_stream, gpr);
     933            result = gpr;
     934        }
     935        RELEASE_ASSERT(!(type & ~SpecMachineInt));
     936        if (info.registerFormat() == DataFormatInt52)
     937            m_jit.rshift64(TrustedImm32(JSValue::int52ShiftAmount), result);
     938        if (type & SpecInt52) {
     939            GPRReg temp = allocate();
     940            m_jit.signExtend32ToPtr(result, temp);
     941            // Currently, we can't supply value profiling information here. :-/
     942            speculationCheck(
     943                BadType, JSValueRegs(), 0,
     944                m_jit.branch64(MacroAssembler::NotEqual, result, temp));
     945            unlock(temp);
     946        }
     947        m_jit.zeroExtend32ToPtr(result, result);
     948        returnFormat = DataFormatInt32;
     949        return gpr;
     950    }
    846951
    847952    case DataFormatDouble:
     
    886991}
    887992
     993GPRReg SpeculativeJIT::fillSpeculateInt52(Edge edge, DataFormat desiredFormat)
     994{
     995    ASSERT(desiredFormat == DataFormatInt52 || desiredFormat == DataFormatStrictInt52);
     996    AbstractValue& value = m_state.forNode(edge);
     997    SpeculatedType type = value.m_type;
     998    m_interpreter.filter(value, SpecMachineInt);
     999    VirtualRegister virtualRegister = edge->virtualRegister();
     1000    GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
     1001
     1002    switch (info.registerFormat()) {
     1003    case DataFormatNone: {
     1004        if ((edge->hasConstant() && !valueOfJSConstant(edge.node()).isMachineInt()) || info.spillFormat() == DataFormatDouble) {
     1005            terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
     1006            return allocate();
     1007        }
     1008       
     1009        GPRReg gpr = allocate();
     1010
     1011        if (edge->hasConstant()) {
     1012            JSValue jsValue = valueOfJSConstant(edge.node());
     1013            ASSERT(jsValue.isMachineInt());
     1014            m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
     1015            int64_t value = jsValue.asMachineInt();
     1016            if (desiredFormat == DataFormatInt52)
     1017                value = value << JSValue::int52ShiftAmount;
     1018            m_jit.move(MacroAssembler::Imm64(value), gpr);
     1019            info.fillGPR(*m_stream, gpr, desiredFormat);
     1020            return gpr;
     1021        }
     1022       
     1023        DataFormat spillFormat = info.spillFormat();
     1024       
     1025        RELEASE_ASSERT((spillFormat & DataFormatJS) || spillFormat == DataFormatInt32 || spillFormat == DataFormatInt52 || spillFormat == DataFormatStrictInt52);
     1026       
     1027        m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
     1028       
     1029        if (spillFormat == DataFormatJSInt32 || spillFormat == DataFormatInt32) {
     1030            // If we know this was spilled as an integer we can fill without checking.
     1031            m_jit.load32(JITCompiler::addressFor(virtualRegister), gpr);
     1032            m_jit.signExtend32ToPtr(gpr, gpr);
     1033            if (desiredFormat == DataFormatStrictInt52) {
     1034                info.fillStrictInt52(*m_stream, gpr);
     1035                return gpr;
     1036            }
     1037            m_jit.lshift64(TrustedImm32(JSValue::int52ShiftAmount), gpr);
     1038            info.fillInt52(*m_stream, gpr);
     1039            return gpr;
     1040        }
     1041        if (spillFormat == DataFormatInt52 || spillFormat == DataFormatStrictInt52) {
     1042            m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
     1043            if (desiredFormat == DataFormatStrictInt52) {
     1044                if (spillFormat == DataFormatInt52)
     1045                    m_jit.rshift64(TrustedImm32(JSValue::int52ShiftAmount), gpr);
     1046                info.fillStrictInt52(*m_stream, gpr);
     1047                return gpr;
     1048            }
     1049            if (spillFormat == DataFormatStrictInt52)
     1050                m_jit.lshift64(TrustedImm32(JSValue::int52ShiftAmount), gpr);
     1051            info.fillInt52(*m_stream, gpr);
     1052            return gpr;
     1053        }
     1054        m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
     1055
     1056        // Fill as JSValue, and fall through.
     1057        info.fillJSValue(*m_stream, gpr, DataFormatJSInt32);
     1058        m_gprs.unlock(gpr);
     1059    }
     1060
     1061    case DataFormatJS: {
     1062        // Check the value is an integer. Note that we would *like* to unbox an Int52
     1063        // at this point but this is too costly. We only *prove* that this is an Int52
     1064        // even though we check if it's an int32.
     1065        GPRReg gpr = info.gpr();
     1066        GPRReg result;
     1067        if (m_gprs.isLocked(gpr)) {
     1068            result = allocate();
     1069            m_jit.move(gpr, result);
     1070        } else {
     1071            m_gprs.lock(gpr);
     1072            result = gpr;
     1073        }
     1074        if (type & ~SpecInt32)
     1075            speculationCheck(BadType, JSValueRegs(result), edge, m_jit.branch64(MacroAssembler::Below, result, GPRInfo::tagTypeNumberRegister));
     1076        if (result == gpr) // The not-already-locked, so fill in-place, case.
     1077            info.fillInt52(*m_stream, gpr, desiredFormat);
     1078        m_jit.signExtend32ToPtr(result, result);
     1079        if (desiredFormat == DataFormatInt52)
     1080            m_jit.lshift64(TrustedImm32(JSValue::int52ShiftAmount), result);
     1081        return result;
     1082    }
     1083
     1084    case DataFormatInt32:
     1085    case DataFormatJSInt32: {
     1086        GPRReg gpr = info.gpr();
     1087        GPRReg result;
     1088        if (m_gprs.isLocked(gpr)) {
     1089            result = allocate();
     1090            m_jit.move(gpr, result);
     1091        } else {
     1092            m_gprs.lock(gpr);
     1093            info.fillInt52(*m_stream, gpr, desiredFormat);
     1094            result = gpr;
     1095        }
     1096        m_jit.signExtend32ToPtr(result, result);
     1097        if (desiredFormat == DataFormatInt52)
     1098            m_jit.lshift64(TrustedImm32(JSValue::int52ShiftAmount), result);
     1099        return result;
     1100    }
     1101
     1102    case DataFormatStrictInt52: {
     1103        GPRReg gpr = info.gpr();
     1104        bool wasLocked = m_gprs.isLocked(gpr);
     1105        lock(gpr);
     1106        if (desiredFormat == DataFormatStrictInt52)
     1107            return gpr;
     1108        if (wasLocked) {
     1109            GPRReg result = allocate();
     1110            m_jit.move(gpr, result);
     1111            unlock(gpr);
     1112            gpr = result;
     1113        } else
     1114            info.fillStrictInt52(*m_stream, gpr);
     1115        m_jit.lshift64(TrustedImm32(JSValue::int52ShiftAmount), gpr);
     1116        return gpr;
     1117    }
     1118       
     1119    case DataFormatInt52: {
     1120        GPRReg gpr = info.gpr();
     1121        bool wasLocked = m_gprs.isLocked(gpr);
     1122        lock(gpr);
     1123        if (desiredFormat == DataFormatInt52)
     1124            return gpr;
     1125        if (wasLocked) {
     1126            GPRReg result = allocate();
     1127            m_jit.move(gpr, result);
     1128            unlock(gpr);
     1129            gpr = result;
     1130        } else
     1131            info.fillInt52(*m_stream, gpr);
     1132        m_jit.rshift64(TrustedImm32(JSValue::int52ShiftAmount), gpr);
     1133        return gpr;
     1134    }
     1135
     1136    case DataFormatDouble:
     1137    case DataFormatJSDouble:
     1138        if (edge->hasConstant()) {
     1139            JSValue jsValue = valueOfJSConstant(edge.node());
     1140            if (jsValue.isMachineInt()) {
     1141                int64_t value = jsValue.asMachineInt();
     1142                if (desiredFormat == DataFormatInt52)
     1143                    value = value << JSValue::int52ShiftAmount;
     1144                GPRReg gpr = allocate();
     1145                m_jit.move(MacroAssembler::Imm64(value), gpr);
     1146                return gpr;
     1147            }
     1148        }
     1149       
     1150    case DataFormatCell:
     1151    case DataFormatBoolean:
     1152    case DataFormatJSCell:
     1153    case DataFormatJSBoolean: {
     1154        terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
     1155        return allocate();
     1156    }
     1157
     1158    case DataFormatStorage:
     1159        RELEASE_ASSERT_NOT_REACHED();
     1160       
     1161    default:
     1162        RELEASE_ASSERT_NOT_REACHED();
     1163        return InvalidGPRReg;
     1164    }
     1165}
     1166
    8881167FPRReg SpeculativeJIT::fillSpeculateDouble(Edge edge)
    8891168{
     
    8931172    AbstractValue& value = m_state.forNode(edge);
    8941173    SpeculatedType type = value.m_type;
    895     ASSERT(edge.useKind() != KnownNumberUse || !(value.m_type & ~SpecNumber));
    896     m_interpreter.filter(value, SpecNumber);
     1174    ASSERT(edge.useKind() != KnownNumberUse || !(value.m_type & ~SpecFullNumber));
     1175    m_interpreter.filter(value, SpecFullNumber);
    8971176    VirtualRegister virtualRegister = edge->virtualRegister();
    8981177    GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
     
    9461225            break;
    9471226        }
     1227           
     1228        case DataFormatInt52: {
     1229            GPRReg gpr = allocate();
     1230            m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
     1231            m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
     1232            info.fillInt52(*m_stream, gpr);
     1233            unlock(gpr);
     1234            break;
     1235        }
     1236           
     1237        case DataFormatStrictInt52: {
     1238            GPRReg gpr = allocate();
     1239            m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
     1240            m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
     1241            info.fillStrictInt52(*m_stream, gpr);
     1242            unlock(gpr);
     1243            break;
     1244        }
    9481245
    9491246        default:
     
    9791276        JITCompiler::Jump isInteger = m_jit.branch64(MacroAssembler::AboveOrEqual, jsValueGpr, GPRInfo::tagTypeNumberRegister);
    9801277
    981         if (type & ~SpecNumber)
     1278        if (type & ~SpecFullNumber)
    9821279            speculationCheck(BadType, JSValueRegs(jsValueGpr), edge, m_jit.branchTest64(MacroAssembler::Zero, jsValueGpr, GPRInfo::tagTypeNumberRegister));
    9831280
     
    10071304        m_gprs.lock(gpr);
    10081305        m_jit.convertInt32ToDouble(gpr, fpr);
     1306        m_gprs.unlock(gpr);
     1307        return fpr;
     1308    }
     1309       
     1310    case DataFormatInt52: {
     1311        FPRReg fpr = fprAllocate();
     1312        GPRReg gpr = info.gpr();
     1313        m_gprs.lock(gpr);
     1314        GPRReg temp = allocate();
     1315        m_jit.move(gpr, temp);
     1316        m_jit.rshift64(TrustedImm32(JSValue::int52ShiftAmount), temp);
     1317        m_jit.convertInt64ToDouble(temp, fpr);
     1318        unlock(temp);
     1319        m_gprs.unlock(gpr);
     1320        return fpr;
     1321    }
     1322       
     1323    case DataFormatStrictInt52: {
     1324        FPRReg fpr = fprAllocate();
     1325        GPRReg gpr = info.gpr();
     1326        m_gprs.lock(gpr);
     1327        m_jit.convertInt64ToDouble(gpr, fpr);
    10091328        m_gprs.unlock(gpr);
    10101329        return fpr;
     
    11121431    case DataFormatDouble:
    11131432    case DataFormatJSBoolean:
    1114     case DataFormatBoolean: {
     1433    case DataFormatBoolean:
     1434    case DataFormatInt52:
     1435    case DataFormatStrictInt52: {
    11151436        terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
    11161437        return allocate();
     
    11951516    case DataFormatDouble:
    11961517    case DataFormatJSCell:
    1197     case DataFormatCell: {
     1518    case DataFormatCell:
     1519    case DataFormatInt52:
     1520    case DataFormatStrictInt52: {
    11981521        terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
    11991522        return allocate();
     
    15021825    m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
    15031826    jsValueResult(result.gpr(), m_currentNode, DataFormatJSBoolean);
     1827}
     1828
     1829void SpeculativeJIT::compileInt52Compare(Node* node, MacroAssembler::RelationalCondition condition)
     1830{
     1831    SpeculateWhicheverInt52Operand op1(this, node->child1());
     1832    SpeculateWhicheverInt52Operand op2(this, node->child2(), op1);
     1833    GPRTemporary result(this, Reuse, op1, op2);
     1834   
     1835    m_jit.compare64(condition, op1.gpr(), op2.gpr(), result.gpr());
     1836   
     1837    // If we add a DataFormatBool, we should use it here.
     1838    m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
     1839    jsValueResult(result.gpr(), m_currentNode, DataFormatJSBoolean);
     1840}
     1841
     1842void SpeculativeJIT::compilePeepHoleInt52Branch(Node* node, Node* branchNode, JITCompiler::RelationalCondition condition)
     1843{
     1844    BasicBlock* taken = branchNode->takenBlock();
     1845    BasicBlock* notTaken = branchNode->notTakenBlock();
     1846
     1847    // The branch instruction will branch to the taken block.
     1848    // If taken is next, switch taken with notTaken & invert the branch condition so we can fall through.
     1849    if (taken == nextBlock()) {
     1850        condition = JITCompiler::invert(condition);
     1851        BasicBlock* tmp = taken;
     1852        taken = notTaken;
     1853        notTaken = tmp;
     1854    }
     1855   
     1856    SpeculateWhicheverInt52Operand op1(this, node->child1());
     1857    SpeculateWhicheverInt52Operand op2(this, node->child2(), op1);
     1858   
     1859    branch64(condition, op1.gpr(), op2.gpr(), taken);
     1860    jump(notTaken);
    15041861}
    15051862
     
    19072264        }
    19082265           
     2266        case FlushedInt52: {
     2267            GPRTemporary result(this);
     2268            m_jit.load64(JITCompiler::addressFor(node->local()), result.gpr());
     2269           
     2270            VirtualRegister virtualRegister = node->virtualRegister();
     2271            m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS);
     2272            generationInfoFromVirtualRegister(virtualRegister).initInt52(node, node->refCount(), result.gpr());
     2273            break;
     2274        }
     2275           
    19092276        default:
    19102277            GPRTemporary result(this);
     
    19822349        }
    19832350           
     2351        case FlushedInt52: {
     2352            SpeculateInt52Operand value(this, node->child1());
     2353            m_jit.store64(value.gpr(), JITCompiler::addressFor(node->local()));
     2354            noResult(node);
     2355            recordSetLocal(node->local(), ValueSource(Int52InJSStack));
     2356            break;
     2357        }
     2358           
    19842359        case FlushedCell: {
    19852360            SpeculateCellOperand cell(this, node->child1());
     
    21022477    case Int32ToDouble: {
    21032478        compileInt32ToDouble(node);
     2479        break;
     2480    }
     2481       
     2482    case Int52ToValue: {
     2483        JSValueOperand operand(this, node->child1());
     2484        GPRTemporary result(this, Reuse, operand);
     2485        m_jit.move(operand.gpr(), result.gpr());
     2486        jsValueResult(result.gpr(), node);
     2487        break;
     2488    }
     2489       
     2490    case Int52ToDouble: {
     2491        SpeculateDoubleOperand operand(this, node->child1());
     2492        FPRTemporary result(this, operand);
     2493        m_jit.moveDouble(operand.fpr(), result.fpr());
     2494        doubleResult(result.fpr(), node);
    21042495        break;
    21052496    }
     
    28903281
    28913282            DFG_TYPE_CHECK(
    2892                 JSValueRegs(), node->child2(), SpecRealNumber,
     3283                JSValueRegs(), node->child2(), SpecFullRealNumber,
    28933284                m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, valueFPR, valueFPR));
    28943285           
     
    31063497        op1.use();
    31073498       
    3108         if (!(m_state.forNode(node->child1()).m_type & ~(SpecNumber | SpecBoolean)))
     3499        if (!(m_state.forNode(node->child1()).m_type & ~(SpecFullNumber | SpecBoolean)))
    31093500            m_jit.move(op1GPR, resultGPR);
    31103501        else {
     
    32033594                    FPRReg opFPR = operand.fpr();
    32043595                    DFG_TYPE_CHECK(
    3205                         JSValueRegs(), use, SpecRealNumber,
     3596                        JSValueRegs(), use, SpecFullRealNumber,
    32063597                        m_jit.branchDouble(
    32073598                            MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR));
     
    32683659                GPRReg scratchGPR = scratch.gpr();
    32693660                DFG_TYPE_CHECK(
    3270                     JSValueRegs(), use, SpecRealNumber,
     3661                    JSValueRegs(), use, SpecFullRealNumber,
    32713662                    m_jit.branchDouble(
    32723663                        MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR));
  • trunk/Source/JavaScriptCore/dfg/DFGUseKind.cpp

    r155201 r156019  
    4444    case KnownInt32Use:
    4545        out.print("KnownInt32");
     46        break;
     47    case MachineIntUse:
     48        out.print("MachineInt");
    4649        break;
    4750    case RealNumberUse:
  • trunk/Source/JavaScriptCore/dfg/DFGUseKind.h

    r155590 r156019  
    4040    Int32Use,
    4141    KnownInt32Use,
     42    MachineIntUse,
    4243    RealNumberUse,
    4344    NumberUse,
     
    6768    case KnownInt32Use:
    6869        return SpecInt32;
     70    case MachineIntUse:
     71        return SpecMachineInt;
    6972    case RealNumberUse:
    70         return SpecRealNumber;
     73        return SpecFullRealNumber;
    7174    case NumberUse:
    7275    case KnownNumberUse:
    73         return SpecNumber;
     76        return SpecFullNumber;
    7477    case BooleanUse:
    7578        return SpecBoolean;
     
    126129    case Int32Use:
    127130    case KnownInt32Use:
     131    case MachineIntUse:
    128132    case RealNumberUse:
    129133    case NumberUse:
  • trunk/Source/JavaScriptCore/dfg/DFGValueSource.cpp

    r141069 r156019  
    4646        out.print("Int32");
    4747        break;
     48    case Int52InJSStack:
     49        out.print("Int52");
     50        break;
    4851    case CellInJSStack:
    4952        out.print("Cell");
  • trunk/Source/JavaScriptCore/dfg/DFGValueSource.h

    r155575 r156019  
    4444    ValueInJSStack,
    4545    Int32InJSStack,
     46    Int52InJSStack,
    4647    CellInJSStack,
    4748    BooleanInJSStack,
     
    5758    case DataFormatInt32:
    5859        return Int32InJSStack;
     60    case DataFormatInt52:
     61        return Int52InJSStack;
    5962    case DataFormatDouble:
    6063        return DoubleInJSStack;
     
    8083    case Int32InJSStack:
    8184        return DataFormatInt32;
     85    case Int52InJSStack:
     86        return DataFormatInt52;
    8287    case CellInJSStack:
    8388        return DataFormatCell;
     
    140145        case FlushedInt32:
    141146            return ValueSource(Int32InJSStack);
     147        case FlushedInt52:
     148            return ValueSource(Int52InJSStack);
    142149        case FlushedCell:
    143150            return ValueSource(CellInJSStack);
     
    182189            return ValueRecovery::alreadyInJSStackAsUnboxedInt32();
    183190           
     191        case Int52InJSStack:
     192            return ValueRecovery::alreadyInJSStackAsUnboxedInt52();
     193           
    184194        case CellInJSStack:
    185195            return ValueRecovery::alreadyInJSStackAsUnboxedCell();
  • trunk/Source/JavaScriptCore/dfg/DFGVariableAccessData.h

    r155497 r156019  
    236236        // If the variable is not a number prediction, then this doesn't
    237237        // make any sense.
    238         if (!isNumberSpeculation(prediction())) {
     238        if (!isFullNumberSpeculation(prediction())) {
    239239            // FIXME: we may end up forcing a local in inlined argument position to be a double even
    240240            // if it is sometimes not even numeric, since this never signals the fact that it doesn't
     
    333333        if (isInt32Speculation(prediction))
    334334            return FlushedInt32;
     335       
     336        if (enableInt52() && !operandIsArgument(m_local) && isMachineIntSpeculation(prediction))
     337            return FlushedInt52;
    335338       
    336339        if (isCellSpeculation(prediction))
  • trunk/Source/JavaScriptCore/ftl/FTLCArgumentGetter.cpp

    r153121 r156019  
    3333using namespace DFG;
    3434
    35 void CArgumentGetter::loadNextAndBox(ValueFormat format, GPRReg destination, GPRReg scratch)
     35void CArgumentGetter::loadNextAndBox(
     36    ValueFormat format, GPRReg destination, GPRReg scratch1, GPRReg scratch2)
    3637{
    37     if (scratch == InvalidGPRReg) {
     38    if (scratch1 == InvalidGPRReg) {
     39        ASSERT(scratch2 == InvalidGPRReg);
    3840        if (destination == GPRInfo::nonArgGPR0)
    39             scratch = GPRInfo::nonArgGPR1;
     41            scratch1 = GPRInfo::nonArgGPR1;
    4042        else
    41             scratch = GPRInfo::nonArgGPR0;
     43            scratch1 = GPRInfo::nonArgGPR0;
     44    }
     45    if (scratch2 == InvalidGPRReg) {
     46        if (destination != GPRInfo::nonArgGPR0 && scratch1 != GPRInfo::nonArgGPR0)
     47            scratch2 = GPRInfo::nonArgGPR0;
     48        else if (destination != GPRInfo::nonArgGPR1 && scratch1 != GPRInfo::nonArgGPR1)
     49            scratch2 = GPRInfo::nonArgGPR1;
     50        else
     51            scratch2 = GPRInfo::nonArgGPR2;
    4252    }
    4353   
     
    5161    case ValueFormatUInt32: {
    5262        loadNext32(destination);
    53         MacroAssembler::Jump isInt = m_jit.branch32(
    54             MacroAssembler::GreaterThanOrEqual,
    55             destination, MacroAssembler::TrustedImm32(0));
     63        m_jit.moveDoubleTo64(FPRInfo::fpRegT0, scratch2);
     64        m_jit.boxInt52(destination, destination, scratch1, FPRInfo::fpRegT0);
     65        m_jit.move64ToDouble(scratch2, FPRInfo::fpRegT0);
     66        break;
     67    }
     68       
     69    case ValueFormatInt52: {
     70        loadNext64(destination);
     71        m_jit.rshift64(AssemblyHelpers::TrustedImm32(JSValue::int52ShiftAmount), destination);
     72        m_jit.moveDoubleTo64(FPRInfo::fpRegT0, scratch2);
     73        m_jit.boxInt52(destination, destination, scratch1, FPRInfo::fpRegT0);
     74        m_jit.move64ToDouble(scratch2, FPRInfo::fpRegT0);
     75        break;
     76    }
    5677           
    57         m_jit.moveDoubleTo64(FPRInfo::fpRegT0, scratch);
    58         m_jit.convertInt32ToDouble(destination, FPRInfo::fpRegT0);
    59         m_jit.boxDouble(FPRInfo::fpRegT0, destination);
    60         m_jit.move64ToDouble(scratch, FPRInfo::fpRegT0);
    61            
    62         MacroAssembler::Jump done = m_jit.jump();
    63            
    64         isInt.link(&m_jit);
    65         m_jit.or64(GPRInfo::tagTypeNumberRegister, destination);
    66            
    67         done.link(&m_jit);
     78    case ValueFormatStrictInt52: {
     79        loadNext64(destination);
     80        m_jit.moveDoubleTo64(FPRInfo::fpRegT0, scratch2);
     81        m_jit.boxInt52(destination, destination, scratch1, FPRInfo::fpRegT0);
     82        m_jit.move64ToDouble(scratch2, FPRInfo::fpRegT0);
    6883        break;
    6984    }
     
    8196           
    8297    case ValueFormatDouble: {
    83         m_jit.moveDoubleTo64(FPRInfo::fpRegT0, scratch);
     98        m_jit.moveDoubleTo64(FPRInfo::fpRegT0, scratch1);
    8499        loadNextDouble(FPRInfo::fpRegT0);
    85100        m_jit.boxDouble(FPRInfo::fpRegT0, destination);
    86         m_jit.move64ToDouble(scratch, FPRInfo::fpRegT0);
     101        m_jit.move64ToDouble(scratch1, FPRInfo::fpRegT0);
    87102        break;
    88103    }
  • trunk/Source/JavaScriptCore/ftl/FTLCArgumentGetter.h

    r153121 r156019  
    116116   
    117117    void loadNextAndBox(
    118         ValueFormat format, DFG::GPRReg destination, DFG::GPRReg scratch = InvalidGPRReg);
     118        ValueFormat, DFG::GPRReg destination,
     119        DFG::GPRReg scratch1 = InvalidGPRReg, DFG::GPRReg scratch2 = InvalidGPRReg);
    119120
    120121private:
  • trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp

    r155281 r156019  
    165165        if (node->isBinaryUseKind(Int32Use))
    166166            break;
     167        if (node->isBinaryUseKind(MachineIntUse))
     168            break;
    167169        if (node->isBinaryUseKind(NumberUse))
    168170            break;
     
    175177    case CompareGreaterEq:
    176178        if (node->isBinaryUseKind(Int32Use))
     179            break;
     180        if (node->isBinaryUseKind(MachineIntUse))
    177181            break;
    178182        if (node->isBinaryUseKind(NumberUse))
     
    237241                case Int32Use:
    238242                case KnownInt32Use:
     243                case MachineIntUse:
    239244                case NumberUse:
    240245                case KnownNumberUse:
  • trunk/Source/JavaScriptCore/ftl/FTLExitValue.cpp

    r153296 r156019  
    5454        out.print("InJSStackAsInt32");
    5555        return;
     56    case ExitValueInJSStackAsInt52:
     57        out.print("InJSStackAsInt52");
     58        return;
    5659    case ExitValueInJSStackAsDouble:
    5760        out.print("InJSStackAsDouble");
  • trunk/Source/JavaScriptCore/ftl/FTLExitValue.h

    r153296 r156019  
    5050    ExitValueInJSStack,
    5151    ExitValueInJSStackAsInt32,
     52    ExitValueInJSStackAsInt52,
    5253    ExitValueInJSStackAsDouble
    5354};
     
    8081        ExitValue result;
    8182        result.m_kind = ExitValueInJSStackAsInt32;
     83        return result;
     84    }
     85   
     86    static ExitValue inJSStackAsInt52()
     87    {
     88        ExitValue result;
     89        result.m_kind = ExitValueInJSStackAsInt52;
    8290        return result;
    8391    }
  • trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h

    r155281 r156019  
    3939#define FOR_EACH_FTL_INTRINSIC(macro) \
    4040    macro(addWithOverflow32, "llvm.sadd.with.overflow.i32", functionType(structType(m_context, int32, boolean), int32, int32)) \
     41    macro(addWithOverflow64, "llvm.sadd.with.overflow.i64", functionType(structType(m_context, int64, boolean), int64, int64)) \
    4142    macro(doubleAbs, "llvm.fabs.f64", functionType(doubleType, doubleType)) \
    4243    macro(mulWithOverflow32, "llvm.smul.with.overflow.i32", functionType(structType(m_context, int32, boolean), int32, int32)) \
     44    macro(mulWithOverflow64, "llvm.smul.with.overflow.i64", functionType(structType(m_context, int64, boolean), int64, int64)) \
    4345    macro(subWithOverflow32, "llvm.ssub.with.overflow.i32", functionType(structType(m_context, int32, boolean), int32, int32)) \
     46    macro(subWithOverflow64, "llvm.ssub.with.overflow.i64", functionType(structType(m_context, int64, boolean), int64, int64)) \
    4447    macro(trap, "llvm.trap", functionType(voidType)) \
    4548    macro(osrExit, "webkit_osr_exit", functionType(voidType, boolean, int32, Variadic))
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp

    r156016 r156019  
    152152                    type = m_out.int32;
    153153                    break;
     154                case NodeResultInt52:
     155                    type = m_out.int64;
     156                    break;
    154157                case NodeResultBoolean:
    155158                    type = m_out.boolean;
     
    240243            break;
    241244        case JSConstant:
    242             compileJSConstant();
    243245            break;
    244246        case WeakJSConstant:
     
    462464            m_out.set(lowInt32(m_node->child1()), destination);
    463465            break;
     466        case MachineIntUse:
     467            m_out.set(lowInt52(m_node->child1()), destination);
     468            break;
    464469        case BooleanUse:
    465470            m_out.set(lowBoolean(m_node->child1()), destination);
     
    487492        case NodeResultInt32:
    488493            setInt32(m_out.get(source));
     494            break;
     495        case NodeResultInt52:
     496            setInt52(m_out.get(source));
    489497            break;
    490498        case NodeResultBoolean:
     
    592600        }
    593601           
     602        case FlushedInt52: {
     603            LValue value = lowInt52(m_node->child1());
     604            m_out.store64(value, addressFor(variable->local()));
     605            m_valueSources.operand(variable->local()) = ValueSource(Int52InJSStack);
     606            return;
     607        }
     608           
    594609        case FlushedCell: {
    595610            LValue value = lowCell(m_node->child1());
     
    656671        }
    657672           
     673        case MachineIntUse: {
     674            if (!m_state.forNode(m_node->child1()).couldBeType(SpecInt52)
     675                && !m_state.forNode(m_node->child2()).couldBeType(SpecInt52)) {
     676                Int52Kind kind;
     677                LValue left = lowWhicheverInt52(m_node->child1(), kind);
     678                LValue right = lowInt52(m_node->child2(), kind);
     679                setInt52(m_out.add(left, right), kind);
     680                break;
     681            }
     682           
     683            LValue left = lowInt52(m_node->child1());
     684            LValue right = lowInt52(m_node->child2());
     685            LValue result = m_out.addWithOverflow64(left, right);
     686            speculate(Int52Overflow, noValue(), 0, m_out.extractValue(result, 1));
     687            setInt52(m_out.extractValue(result, 0));
     688            break;
     689        }
     690           
    658691        case NumberUse: {
    659692            setDouble(
     
    683716            speculate(Overflow, noValue(), 0, m_out.extractValue(result, 1));
    684717            setInt32(m_out.extractValue(result, 0));
     718            break;
     719        }
     720           
     721        case MachineIntUse: {
     722            if (!m_state.forNode(m_node->child1()).couldBeType(SpecInt52)
     723                && !m_state.forNode(m_node->child2()).couldBeType(SpecInt52)) {
     724                Int52Kind kind;
     725                LValue left = lowWhicheverInt52(m_node->child1(), kind);
     726                LValue right = lowInt52(m_node->child2(), kind);
     727                setInt52(m_out.sub(left, right), kind);
     728                break;
     729            }
     730           
     731            LValue left = lowInt52(m_node->child1());
     732            LValue right = lowInt52(m_node->child2());
     733            LValue result = m_out.subWithOverflow64(left, right);
     734            speculate(Int52Overflow, noValue(), 0, m_out.extractValue(result, 1));
     735            setInt52(m_out.extractValue(result, 0));
    685736            break;
    686737        }
     
    728779           
    729780            setInt32(result);
     781            break;
     782        }
     783           
     784        case MachineIntUse: {
     785            Int52Kind kind;
     786            LValue left = lowWhicheverInt52(m_node->child1(), kind);
     787            LValue right = lowInt52(m_node->child2(), opposite(kind));
     788           
     789            LValue overflowResult = m_out.mulWithOverflow64(left, right);
     790            speculate(Int52Overflow, noValue(), 0, m_out.extractValue(overflowResult, 1));
     791            LValue result = m_out.extractValue(overflowResult, 0);
     792           
     793            if (!bytecodeCanIgnoreNegativeZero(m_node->arithNodeFlags())) {
     794                LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("ArithMul slow case"));
     795                LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithMul continuation"));
     796               
     797                m_out.branch(m_out.notZero64(result), continuation, slowCase);
     798               
     799                LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
     800                speculate(NegativeZero, noValue(), 0, m_out.lessThan(left, m_out.int64Zero));
     801                speculate(NegativeZero, noValue(), 0, m_out.lessThan(right, m_out.int64Zero));
     802                m_out.jump(continuation);
     803                m_out.appendTo(continuation, lastNext);
     804            }
     805           
     806            setInt52(result);
    730807            break;
    731808        }
     
    10301107           
    10311108            setInt32(result);
     1109            break;
     1110        }
     1111           
     1112        case MachineIntUse: {
     1113            if (!m_state.forNode(m_node->child1()).couldBeType(SpecInt52)) {
     1114                Int52Kind kind;
     1115                LValue value = lowWhicheverInt52(m_node->child1(), kind);
     1116                LValue result = m_out.neg(value);
     1117                if (!bytecodeCanIgnoreNegativeZero(m_node->arithNodeFlags()))
     1118                    speculate(NegativeZero, noValue(), 0, m_out.isZero64(result));
     1119                setInt52(result, kind);
     1120                break;
     1121            }
     1122           
     1123            LValue value = lowInt52(m_node->child1());
     1124            LValue overflowResult = m_out.subWithOverflow64(m_out.int64Zero, value);
     1125            speculate(Int52Overflow, noValue(), 0, m_out.extractValue(overflowResult, 1));
     1126            LValue result = m_out.extractValue(overflowResult, 0);
     1127            speculate(NegativeZero, noValue(), 0, m_out.isZero64(result));
     1128            setInt52(result);
    10321129            break;
    10331130        }
     
    14741571               
    14751572                FTL_TYPE_CHECK(
    1476                     doubleValue(value), child3, SpecRealNumber,
     1573                    doubleValue(value), child3, SpecFullRealNumber,
    14771574                    m_out.doubleNotEqualOrUnordered(value, value));
    14781575               
     
    17091806    {
    17101807        if (m_node->isBinaryUseKind(Int32Use)
     1808            || m_node->isBinaryUseKind(MachineIntUse)
    17111809            || m_node->isBinaryUseKind(NumberUse)
    17121810            || m_node->isBinaryUseKind(ObjectUse)) {
     
    17321830            setBoolean(
    17331831                m_out.equal(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
     1832            return;
     1833        }
     1834       
     1835        if (m_node->isBinaryUseKind(MachineIntUse)) {
     1836            Int52Kind kind;
     1837            LValue left = lowWhicheverInt52(m_node->child1(), kind);
     1838            LValue right = lowInt52(m_node->child2(), kind);
     1839            setBoolean(m_out.equal(left, right));
    17341840            return;
    17351841        }
     
    17831889        }
    17841890       
     1891        if (m_node->isBinaryUseKind(MachineIntUse)) {
     1892            Int52Kind kind;
     1893            LValue left = lowWhicheverInt52(m_node->child1(), kind);
     1894            LValue right = lowInt52(m_node->child2(), kind);
     1895            setBoolean(m_out.lessThan(left, right));
     1896            return;
     1897        }
     1898       
    17851899        if (m_node->isBinaryUseKind(NumberUse)) {
    17861900            setBoolean(
     
    17971911            setBoolean(
    17981912                m_out.lessThanOrEqual(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
     1913            return;
     1914        }
     1915       
     1916        if (m_node->isBinaryUseKind(MachineIntUse)) {
     1917            Int52Kind kind;
     1918            LValue left = lowWhicheverInt52(m_node->child1(), kind);
     1919            LValue right = lowInt52(m_node->child2(), kind);
     1920            setBoolean(m_out.lessThanOrEqual(left, right));
    17991921            return;
    18001922        }
     
    18181940        }
    18191941       
     1942        if (m_node->isBinaryUseKind(MachineIntUse)) {
     1943            Int52Kind kind;
     1944            LValue left = lowWhicheverInt52(m_node->child1(), kind);
     1945            LValue right = lowInt52(m_node->child2(), kind);
     1946            setBoolean(m_out.greaterThan(left, right));
     1947            return;
     1948        }
     1949       
    18201950        if (m_node->isBinaryUseKind(NumberUse)) {
    18211951            setBoolean(
     
    18341964                m_out.greaterThanOrEqual(
    18351965                    lowInt32(m_node->child1()), lowInt32(m_node->child2())));
     1966            return;
     1967        }
     1968       
     1969        if (m_node->isBinaryUseKind(MachineIntUse)) {
     1970            Int52Kind kind;
     1971            LValue left = lowWhicheverInt52(m_node->child1(), kind);
     1972            LValue right = lowInt52(m_node->child2(), kind);
     1973            setBoolean(m_out.greaterThanOrEqual(left, right));
    18361974            return;
    18371975        }
     
    23532491        ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || (edge.useKind() == Int32Use || edge.useKind() == KnownInt32Use));
    23542492       
     2493        if (edge->hasConstant()) {
     2494            JSValue value = m_graph.valueOfJSConstant(edge.node());
     2495            if (!value.isInt32()) {
     2496                terminate(Uncountable);
     2497                return m_out.int32Zero;
     2498            }
     2499            return m_out.constInt32(value.asInt32());
     2500        }
     2501       
    23552502        LoweredNodeValue value = m_int32Values.get(edge.node());
    23562503        if (isValid(value))
    23572504            return value.value();
     2505       
     2506        value = m_strictInt52Values.get(edge.node());
     2507        if (isValid(value))
     2508            return strictInt52ToInt32(edge, value.value());
     2509       
     2510        value = m_int52Values.get(edge.node());
     2511        if (isValid(value))
     2512            return strictInt52ToInt32(edge, int52ToStrictInt52(value.value()));
    23582513       
    23592514        value = m_jsValueValues.get(edge.node());
     
    23722527    }
    23732528   
     2529    enum Int52Kind { StrictInt52, Int52 };
     2530    LValue lowInt52(Edge edge, Int52Kind kind, OperandSpeculationMode mode = AutomaticOperandSpeculation)
     2531    {
     2532        ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == MachineIntUse);
     2533       
     2534        if (edge->hasConstant()) {
     2535            JSValue value = m_graph.valueOfJSConstant(edge.node());
     2536            if (!value.isMachineInt()) {
     2537                terminate(Uncountable);
     2538                return m_out.int64Zero;
     2539            }
     2540            int64_t result = value.asMachineInt();
     2541            if (kind == Int52)
     2542                result <<= JSValue::int52ShiftAmount;
     2543            return m_out.constInt64(result);
     2544        }
     2545       
     2546        LoweredNodeValue value;
     2547       
     2548        switch (kind) {
     2549        case Int52:
     2550            value = m_int52Values.get(edge.node());
     2551            if (isValid(value))
     2552                return value.value();
     2553           
     2554            value = m_strictInt52Values.get(edge.node());
     2555            if (isValid(value))
     2556                return strictInt52ToInt52(value.value());
     2557            break;
     2558           
     2559        case StrictInt52:
     2560            value = m_strictInt52Values.get(edge.node());
     2561            if (isValid(value))
     2562                return value.value();
     2563           
     2564            value = m_int52Values.get(edge.node());
     2565            if (isValid(value))
     2566                return int52ToStrictInt52(value.value());
     2567            break;
     2568        }
     2569       
     2570        value = m_int32Values.get(edge.node());
     2571        if (isValid(value)) {
     2572            return setInt52WithStrictValue(
     2573                edge.node(), m_out.signExt(value.value(), m_out.int64), kind);
     2574        }
     2575       
     2576        RELEASE_ASSERT(!(m_state.forNode(edge).m_type & SpecInt52));
     2577       
     2578        value = m_jsValueValues.get(edge.node());
     2579        if (isValid(value)) {
     2580            LValue boxedResult = value.value();
     2581            FTL_TYPE_CHECK(
     2582                jsValueValue(boxedResult), edge, SpecMachineInt, isNotInt32(boxedResult));
     2583            return setInt52WithStrictValue(
     2584                edge.node(), m_out.signExt(unboxInt32(boxedResult), m_out.int64), kind);
     2585        }
     2586       
     2587        RELEASE_ASSERT(!(m_state.forNode(edge).m_type & SpecMachineInt));
     2588        terminate(Uncountable);
     2589        return m_out.int64Zero;
     2590    }
     2591   
     2592    LValue lowInt52(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
     2593    {
     2594        return lowInt52(edge, Int52, mode);
     2595    }
     2596   
     2597    LValue lowStrictInt52(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
     2598    {
     2599        return lowInt52(edge, StrictInt52, mode);
     2600    }
     2601   
     2602    bool betterUseStrictInt52(Node* node)
     2603    {
     2604        return !isValid(m_int52Values.get(node));
     2605    }
     2606    bool betterUseStrictInt52(Edge edge)
     2607    {
     2608        return betterUseStrictInt52(edge.node());
     2609    }
     2610    template<typename T>
     2611    Int52Kind bestInt52Kind(T node)
     2612    {
     2613        return betterUseStrictInt52(node) ? StrictInt52 : Int52;
     2614    }
     2615    Int52Kind opposite(Int52Kind kind)
     2616    {
     2617        switch (kind) {
     2618        case Int52:
     2619            return StrictInt52;
     2620        case StrictInt52:
     2621            return Int52;
     2622        }
     2623        RELEASE_ASSERT_NOT_REACHED();
     2624    }
     2625   
     2626    LValue lowWhicheverInt52(Edge edge, Int52Kind& kind, OperandSpeculationMode mode = AutomaticOperandSpeculation)
     2627    {
     2628        kind = bestInt52Kind(edge);
     2629        return lowInt52(edge, kind, mode);
     2630    }
     2631   
    23742632    LValue lowCell(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
    23752633    {
    23762634        ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || isCell(edge.useKind()));
     2635       
     2636        if (edge->op() == JSConstant) {
     2637            JSValue value = m_graph.valueOfJSConstant(edge.node());
     2638            if (!value.isCell()) {
     2639                terminate(Uncountable);
     2640                return m_out.intPtrZero;
     2641            }
     2642            return m_out.constIntPtr(value.asCell());
     2643        }
    23772644       
    23782645        LoweredNodeValue value = m_jsValueValues.get(edge.node());
     
    24192686    {
    24202687        ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == BooleanUse);
     2688       
     2689        if (edge->hasConstant()) {
     2690            JSValue value = m_graph.valueOfJSConstant(edge.node());
     2691            if (!value.isBoolean()) {
     2692                terminate(Uncountable);
     2693                return m_out.booleanFalse;
     2694            }
     2695            return m_out.constBool(value.asBoolean());
     2696        }
    24212697       
    24222698        LoweredNodeValue value = m_booleanValues.get(edge.node());
     
    24432719        ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || isDouble(edge.useKind()));
    24442720       
     2721        if (edge->hasConstant()) {
     2722            JSValue value = m_graph.valueOfJSConstant(edge.node());
     2723            if (!value.isNumber()) {
     2724                terminate(Uncountable);
     2725                return m_out.doubleZero;
     2726            }
     2727            return m_out.constDouble(value.asNumber());
     2728        }
     2729       
    24452730        LoweredNodeValue value = m_doubleValues.get(edge.node());
    24462731        if (isValid(value))
     
    24542739        }
    24552740       
     2741        value = m_strictInt52Values.get(edge.node());
     2742        if (isValid(value))
     2743            return strictInt52ToDouble(edge, value.value());
     2744       
     2745        value = m_int52Values.get(edge.node());
     2746        if (isValid(value))
     2747            return strictInt52ToDouble(edge, int52ToStrictInt52(value.value()));
     2748       
    24562749        value = m_jsValueValues.get(edge.node());
    24572750        if (isValid(value)) {
     
    24732766           
    24742767            FTL_TYPE_CHECK(
    2475                 jsValueValue(boxedResult), edge, SpecNumber, isCellOrMisc(boxedResult));
     2768                jsValueValue(boxedResult), edge, SpecFullNumber, isCellOrMisc(boxedResult));
    24762769           
    24772770            ValueFromBlock unboxedDouble = m_out.anchor(unboxDouble(boxedResult));
     
    24862779        }
    24872780       
    2488         RELEASE_ASSERT(!(m_state.forNode(edge).m_type & SpecNumber));
     2781        RELEASE_ASSERT(!(m_state.forNode(edge).m_type & SpecFullNumber));
    24892782        terminate(Uncountable);
    24902783        return m_out.doubleZero;
     
    24942787    {
    24952788        ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == UntypedUse);
     2789       
     2790        if (edge->hasConstant())
     2791            return m_out.constInt64(JSValue::encode(m_graph.valueOfJSConstant(edge.node())));
    24962792       
    24972793        LoweredNodeValue value = m_jsValueValues.get(edge.node());
     
    25062802        }
    25072803       
     2804        value = m_strictInt52Values.get(edge.node());
     2805        if (isValid(value))
     2806            return strictInt52ToJSValue(value.value());
     2807       
     2808        value = m_int52Values.get(edge.node());
     2809        if (isValid(value))
     2810            return strictInt52ToJSValue(int52ToStrictInt52(value.value()));
     2811       
    25082812        value = m_booleanValues.get(edge.node());
    25092813        if (isValid(value)) {
     
    25332837        setStorage(edge.node(), result);
    25342838        return result;
     2839    }
     2840   
     2841    LValue strictInt52ToInt32(Edge edge, LValue value)
     2842    {
     2843        LValue result = m_out.castToInt32(value);
     2844        FTL_TYPE_CHECK(
     2845            noValue(), edge, SpecInt32,
     2846            m_out.notEqual(m_out.signExt(result, m_out.int64), value));
     2847        setInt32(edge.node(), result);
     2848        return result;
     2849    }
     2850   
     2851    LValue strictInt52ToDouble(Edge edge, LValue value)
     2852    {
     2853        LValue result = m_out.intToDouble(value);
     2854        setDouble(edge.node(), result);
     2855        return result;
     2856    }
     2857   
     2858    LValue strictInt52ToJSValue(LValue value)
     2859    {
     2860        LBasicBlock isInt32 = FTL_NEW_BLOCK(m_out, ("strictInt52ToJSValue isInt32 case"));
     2861        LBasicBlock isDouble = FTL_NEW_BLOCK(m_out, ("strictInt52ToJSValue isDouble case"));
     2862        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("strictInt52ToJSValue continuation"));
     2863       
     2864        Vector<ValueFromBlock, 2> results;
     2865           
     2866        LValue int32Value = m_out.castToInt32(value);
     2867        m_out.branch(
     2868            m_out.equal(m_out.signExt(int32Value, m_out.int64), value),
     2869            isInt32, isDouble);
     2870       
     2871        LBasicBlock lastNext = m_out.appendTo(isInt32, isDouble);
     2872       
     2873        results.append(m_out.anchor(boxInt32(int32Value)));
     2874        m_out.jump(continuation);
     2875       
     2876        m_out.appendTo(isDouble, continuation);
     2877       
     2878        results.append(m_out.anchor(boxDouble(m_out.intToDouble(value))));
     2879        m_out.jump(continuation);
     2880       
     2881        m_out.appendTo(continuation, lastNext);
     2882        return m_out.phi(m_out.int64, results);
     2883    }
     2884   
     2885    LValue setInt52WithStrictValue(Node* node, LValue value, Int52Kind kind)
     2886    {
     2887        switch (kind) {
     2888        case StrictInt52:
     2889            setStrictInt52(node, value);
     2890            return value;
     2891           
     2892        case Int52:
     2893            value = strictInt52ToInt52(value);
     2894            setInt52(node, value);
     2895            return value;
     2896        }
     2897       
     2898        RELEASE_ASSERT_NOT_REACHED();
     2899        return 0;
     2900    }
     2901
     2902    LValue strictInt52ToInt52(LValue value)
     2903    {
     2904        return m_out.shl(value, m_out.constInt64(JSValue::int52ShiftAmount));
     2905    }
     2906   
     2907    LValue int52ToStrictInt52(LValue value)
     2908    {
     2909        return m_out.aShr(value, m_out.constInt64(JSValue::int52ShiftAmount));
    25352910    }
    25362911   
     
    27953170        LValue value = lowDouble(edge);
    27963171        FTL_TYPE_CHECK(
    2797             doubleValue(value), edge, SpecRealNumber,
     3172            doubleValue(value), edge, SpecFullRealNumber,
    27983173            m_out.doubleNotEqualOrUnordered(value, value));
    27993174    }
     
    28033178        lowBoolean(edge);
    28043179    }
    2805 
     3180   
    28063181    bool masqueradesAsUndefinedWatchpointIsStillValid()
    28073182    {
     
    29343309                break;
    29353310               
     3311            case FlushedInt52:
     3312                m_valueSources[i] = ValueSource(Int52InJSStack);
     3313                break;
     3314               
    29363315            case FlushedDouble:
    29373316                m_valueSources[i] = ValueSource(DoubleInJSStack);
     
    30363415            case Int32InJSStack:
    30373416                exit.m_values[i] = ExitValue::inJSStackAsInt32();
     3417                break;
     3418            case Int52InJSStack:
     3419                exit.m_values[i] = ExitValue::inJSStackAsInt52();
    30383420                break;
    30393421            case DoubleInJSStack:
     
    31403522        }
    31413523       
     3524        value = m_int52Values.get(node);
     3525        if (isValid(value)) {
     3526            addExitArgument(exit, arguments, index, ValueFormatInt52, value.value());
     3527            return;
     3528        }
     3529       
     3530        value = m_strictInt52Values.get(node);
     3531        if (isValid(value)) {
     3532            addExitArgument(exit, arguments, index, ValueFormatStrictInt52, value.value());
     3533            return;
     3534        }
     3535       
    31423536        value = m_booleanValues.get(node);
    31433537        if (isValid(value)) {
     
    32433637        m_int32Values.set(node, LoweredNodeValue(value, m_highBlock));
    32443638    }
     3639    void setInt52(Node* node, LValue value)
     3640    {
     3641        m_int52Values.set(node, LoweredNodeValue(value, m_highBlock));
     3642    }
     3643    void setStrictInt52(Node* node, LValue value)
     3644    {
     3645        m_strictInt52Values.set(node, LoweredNodeValue(value, m_highBlock));
     3646    }
     3647    void setInt52(Node* node, LValue value, Int52Kind kind)
     3648    {
     3649        switch (kind) {
     3650        case Int52:
     3651            setInt52(node, value);
     3652            return;
     3653           
     3654        case StrictInt52:
     3655            setStrictInt52(node, value);
     3656            return;
     3657        }
     3658       
     3659        RELEASE_ASSERT_NOT_REACHED();
     3660    }
    32453661    void setJSValue(Node* node, LValue value)
    32463662    {
     
    32633679    {
    32643680        setInt32(m_node, value);
     3681    }
     3682    void setInt52(LValue value)
     3683    {
     3684        setInt52(m_node, value);
     3685    }
     3686    void setStrictInt52(LValue value)
     3687    {
     3688        setStrictInt52(m_node, value);
     3689    }
     3690    void setInt52(LValue value, Int52Kind kind)
     3691    {
     3692        setInt52(m_node, value, kind);
    32653693    }
    32663694    void setJSValue(LValue value)
     
    33433771   
    33443772    HashMap<Node*, LoweredNodeValue> m_int32Values;
     3773    HashMap<Node*, LoweredNodeValue> m_strictInt52Values;
     3774    HashMap<Node*, LoweredNodeValue> m_int52Values;
    33453775    HashMap<Node*, LoweredNodeValue> m_jsValueValues;
    33463776    HashMap<Node*, LoweredNodeValue> m_booleanValues;
  • trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp

    r155995 r156019  
    105105    }
    106106   
     107    // All temp registers are free at this point.
     108   
    107109    // Box anything that is already on the stack, or that is a constant.
    108110   
     
    129131            jit.store64(GPRInfo::regT0, address);
    130132            break;
     133        case ExitValueInJSStackAsInt52:
     134            jit.load64(address, GPRInfo::regT0);
     135            jit.rshift64(
     136                AssemblyHelpers::TrustedImm32(JSValue::int52ShiftAmount), GPRInfo::regT0);
     137            jit.boxInt52(GPRInfo::regT0, GPRInfo::regT0, GPRInfo::regT1, FPRInfo::fpRegT0);
     138            jit.store64(GPRInfo::regT0, address);
     139            break;
    131140        case ExitValueInJSStackAsDouble:
    132141            jit.loadDouble(address, FPRInfo::fpRegT0);
     
    161170        shouldShowDisassembly(),
    162171        patchBuffer,
    163         ("FTL OSR exit #%u (bc#%u, %s) from %s",
     172        ("FTL OSR exit #%u (bc#%u, %s) from %s, with operands = %s",
    164173            exitID, exit.m_codeOrigin.bytecodeIndex,
    165             exitKindToString(exit.m_kind), toCString(*codeBlock).data()));
     174            exitKindToString(exit.m_kind), toCString(*codeBlock).data(),
     175            toCString(ignoringContext<DumpContext>(exit.m_values)).data()));
    166176}
    167177
  • trunk/Source/JavaScriptCore/ftl/FTLOutput.h

    r155281 r156019  
    167167        return call(mulWithOverflow32Intrinsic(), left, right);
    168168    }
     169    LValue addWithOverflow64(LValue left, LValue right)
     170    {
     171        return call(addWithOverflow64Intrinsic(), left, right);
     172    }
     173    LValue subWithOverflow64(LValue left, LValue right)
     174    {
     175        return call(subWithOverflow64Intrinsic(), left, right);
     176    }
     177    LValue mulWithOverflow64(LValue left, LValue right)
     178    {
     179        return call(mulWithOverflow64Intrinsic(), left, right);
     180    }
    169181    LValue doubleAbs(LValue value)
    170182    {
  • trunk/Source/JavaScriptCore/ftl/FTLValueFormat.cpp

    r153121 r156019  
    4545        out.print("UInt32");
    4646        return;
     47    case ValueFormatInt52:
     48        out.print("Int52");
     49        return;
     50    case ValueFormatStrictInt52:
     51        out.print("StrictInt52");
     52        return;
    4753    case ValueFormatBoolean:
    4854        out.print("Boolean");
  • trunk/Source/JavaScriptCore/ftl/FTLValueFormat.h

    r153121 r156019  
    4242    ValueFormatInt32,
    4343    ValueFormatUInt32,
     44    ValueFormatInt52,
     45    ValueFormatStrictInt52,
    4446    ValueFormatBoolean,
    4547    ValueFormatJSValue,
  • trunk/Source/JavaScriptCore/ftl/FTLValueSource.cpp

    r153296 r156019  
    4343        out.print("Int32InJSStack");
    4444        return;
     45    case Int52InJSStack:
     46        out.print("Int52InJSStack");
     47        return;
    4548    case DoubleInJSStack:
    4649        out.print("DoubleInJSStack");
  • trunk/Source/JavaScriptCore/ftl/FTLValueSource.h

    r153296 r156019  
    4141    ValueInJSStack,
    4242    Int32InJSStack,
     43    Int52InJSStack,
    4344    DoubleInJSStack,
    4445    SourceIsDead,
  • trunk/Source/JavaScriptCore/interpreter/Register.h

    r155023 r156019  
    7474        InlineCallFrame* asInlineCallFrame() const;
    7575        int32_t unboxedInt32() const;
     76        int64_t unboxedInt52() const;
    7677        bool unboxedBoolean() const;
    7778        double unboxedDouble() const;
     
    99100            EncodedValueDescriptor encodedValue;
    100101            double number;
     102            int64_t integer;
    101103        } u;
    102104    };
     
    184186    {
    185187        return payload();
     188    }
     189
     190    ALWAYS_INLINE int64_t Register::unboxedInt52() const
     191    {
     192        return u.integer >> JSValue::int52ShiftAmount;
    186193    }
    187194
  • trunk/Source/JavaScriptCore/runtime/Arguments.cpp

    r155711 r156019  
    384384            value = jsNumber(location->unboxedInt32());
    385385            break;
     386        case AlreadyInJSStackAsUnboxedInt52:
     387            value = jsNumber(location->unboxedInt52());
     388            break;
    386389        case AlreadyInJSStackAsUnboxedCell:
    387390            value = location->unboxedCell();
  • trunk/Source/JavaScriptCore/runtime/IndexingType.cpp

    r138073 r156019  
    5151        if (isInt32Speculation(type))
    5252            return (indexingType & ~IndexingShapeMask) | Int32Shape;
    53         if (isNumberSpeculation(type))
     53        if (isFullNumberSpeculation(type))
    5454            return (indexingType & ~IndexingShapeMask) | DoubleShape;
    5555        return (indexingType & ~IndexingShapeMask) | ContiguousShape;
    5656    case ALL_DOUBLE_INDEXING_TYPES:
    57         if (isNumberSpeculation(type))
     57        if (isFullNumberSpeculation(type))
    5858            return indexingType;
    5959        return (indexingType & ~IndexingShapeMask) | ContiguousShape;
  • trunk/Source/JavaScriptCore/runtime/JSCJSValue.h

    r155643 r156019  
    192192    int32_t asInt32() const;
    193193    uint32_t asUInt32() const;
     194    int64_t asMachineInt() const;
    194195    double asDouble() const;
    195196    bool asBoolean() const;
     
    203204    bool isUndefinedOrNull() const;
    204205    bool isBoolean() const;
     206    bool isMachineInt() const;
    205207    bool isNumber() const;
    206208    bool isString() const;
     
    274276
    275277    JS_EXPORT_PRIVATE JSObject* synthesizePrototype(ExecState*) const;
     278
     279#if USE(JSVALUE64)
     280    // Constants used for Int52. Int52 isn't part of JSValue right now, but JSValues may be
     281    // converted to Int52s and back again.
     282    static const unsigned numberOfInt52Bits = 52;
     283    static const unsigned int52ShiftAmount = 12;
     284#endif
    276285
    277286private:
  • trunk/Source/JavaScriptCore/runtime/JSCJSValueInlines.h

    r154902 r156019  
    495495#endif // USE(JSVALUE64)
    496496
     497inline bool JSValue::isMachineInt() const
     498{
     499    if (isInt32())
     500        return true;
     501    if (!isNumber())
     502        return false;
     503    double number = asDouble();
     504    if (number != number)
     505        return false;
     506    int64_t asInt64 = static_cast<int64_t>(number);
     507    if (asInt64 != number)
     508        return false;
     509    if (!asInt64 && std::signbit(number))
     510        return false;
     511    if (asInt64 >= (static_cast<int64_t>(1) << (numberOfInt52Bits - 1)))
     512        return false;
     513    if (asInt64 < -(static_cast<int64_t>(1) << (numberOfInt52Bits - 1)))
     514        return false;
     515    return true;
     516}
     517
     518inline int64_t JSValue::asMachineInt() const
     519{
     520    ASSERT(isMachineInt());
     521    if (isInt32())
     522        return asInt32();
     523    return static_cast<int64_t>(asDouble());
     524}
     525
    497526inline bool JSValue::isString() const
    498527{
  • trunk/Source/WTF/ChangeLog

    r156004 r156019  
     12013-09-16  Filip Pizlo  <fpizlo@apple.com>
     2
     3        DFG should support Int52 for local variables
     4        https://bugs.webkit.org/show_bug.cgi?id=121064
     5
     6        Reviewed by Oliver Hunt.
     7
     8        * wtf/PrintStream.h:
     9        (WTF::ValueIgnoringContext::ValueIgnoringContext):
     10        (WTF::ValueIgnoringContext::dump):
     11        (WTF::ignoringContext):
     12
    1132013-09-17  Anders Carlsson  <andersca@apple.com>
    214
  • trunk/Source/WTF/wtf/PrintStream.h

    r155251 r156019  
    361361}
    362362
     363template<typename T, typename U>
     364class ValueIgnoringContext {
     365public:
     366    ValueIgnoringContext(const U& value)
     367        : m_value(&value)
     368    {
     369    }
     370   
     371    void dump(PrintStream& out) const
     372    {
     373        T context;
     374        m_value->dumpInContext(out, &context);
     375    }
     376
     377private:
     378    const U* m_value;
     379};
     380
     381template<typename T, typename U>
     382ValueIgnoringContext<T, U> ignoringContext(const U& value)
     383{
     384    return ValueIgnoringContext<T, U>(value);
     385}
     386
    363387} // namespace WTF
    364388
     
    366390using WTF::PointerDump;
    367391using WTF::PrintStream;
     392using WTF::ignoringContext;
    368393using WTF::inContext;
    369394using WTF::pointerDump;
  • trunk/Tools/ChangeLog

    r156018 r156019  
     12013-09-17  Filip Pizlo  <fpizlo@apple.com>
     2
     3        DFG should support Int52 for local variables
     4        https://bugs.webkit.org/show_bug.cgi?id=121064
     5
     6        Reviewed by Oliver Hunt.
     7
     8        * Scripts/run-jsc-stress-tests:
     9
    1102013-09-17  Alex Christensen  <alex.christensen@flexsim.com>
    211
  • trunk/Tools/Scripts/run-jsc-stress-tests

    r155489 r156019  
    215215    runAlwaysTriggerCopyPhase
    216216    runNoCJIT
     217    runDFGEager
    217218    if $enableFTL
    218219        runDefaultFTL
    219220        runFTLNoCJIT
    220221        runFTLEager
    221     else
    222         runDFGEager
    223222    end
    224223end
Note: See TracChangeset for help on using the changeset viewer.