Commit 6921b29b authored by fpizlo@apple.com's avatar fpizlo@apple.com

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/ExitKind.cpp:
(JSC::exitKindToString):
* bytecode/ExitKind.h:
* bytecode/OperandsInlines.h:
(JSC::::dumpInContext):
* bytecode/SpeculatedType.cpp:
(JSC::dumpSpeculation):
(JSC::speculationToAbbreviatedString):
(JSC::speculationFromValue):
* bytecode/SpeculatedType.h:
(JSC::isInt32SpeculationForArithmetic):
(JSC::isInt52Speculation):
(JSC::isMachineIntSpeculationForArithmetic):
(JSC::isInt52AsDoubleSpeculation):
(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/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::makeSafe):
* 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/DFGDCEPhase.cpp:
(JSC::DFG::DCEPhase::fixupBlock):
* 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/DFGJITCompiler.h:
(JSC::DFG::JITCompiler::noticeOSREntry):
* dfg/DFGMinifiedNode.h:
(JSC::DFG::belongsInMinifiedGraph):
(JSC::DFG::MinifiedNode::hasChild):
* dfg/DFGNode.h:
(JSC::DFG::Node::shouldSpeculateNumber):
(JSC::DFG::Node::shouldSpeculateNumberExpectingDefined):
(JSC::DFG::Node::canSpeculateInt52):
* dfg/DFGNodeFlags.h:
(JSC::DFG::nodeCanSpeculateInt52):
* dfg/DFGNodeType.h:
(JSC::DFG::permitsOSRBackwardRewiring):
(JSC::DFG::forwardRewiringSelectionScore):
* dfg/DFGOSREntry.cpp:
(JSC::DFG::prepareOSREntry):
* dfg/DFGOSREntry.h:
* 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::lowWhicheverInt52):
(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/dfg-int-overflow-large-constants-in-a-line-expected.txt:
* 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):
* js/script-tests/dfg-int-overflow-large-constants-in-a-line.js:



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@156047 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 98791905
2013-09-18 Filip Pizlo <fpizlo@apple.com>
DFG should support Int52 for local variables
https://bugs.webkit.org/show_bug.cgi?id=121064
Reviewed by Oliver Hunt.
* js/dfg-int-overflow-large-constants-in-a-line-expected.txt:
* 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):
* js/script-tests/dfg-int-overflow-large-constants-in-a-line.js:
2013-09-18 Andreas Kling <akling@apple.com>
Missed one rebaseline for the RenderMenuList change.
......@@ -3,206 +3,7 @@ Tests that our optimization to elide overflow checks understands that if we keep
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552
PASS foo(2147483647) is 2147483552 on all iterations including after DFG tier-up.
PASS successfullyParsed is true
TEST COMPLETE
......
JSRegress/large-int-captured
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS no exception thrown
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<script src="../../resources/js-test-pre.js"></script>
</head>
<body>
<script src="resources/regress-pre.js"></script>
<script src="script-tests/large-int-captured.js"></script>
<script src="resources/regress-post.js"></script>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>
JSRegress/large-int
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS no exception thrown
PASS successfullyParsed is true
TEST COMPLETE
JSRegress/large-int-neg
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS no exception thrown
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<script src="../../resources/js-test-pre.js"></script>
</head>
<body>
<script src="resources/regress-pre.js"></script>
<script src="script-tests/large-int-neg.js"></script>
<script src="resources/regress-post.js"></script>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<script src="../../resources/js-test-pre.js"></script>
</head>
<body>
<script src="resources/regress-pre.js"></script>
<script src="script-tests/large-int.js"></script>
<script src="resources/regress-post.js"></script>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>
JSRegress/marsaglia-larger-ints
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS no exception thrown
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<script src="../../resources/js-test-pre.js"></script>
</head>
<body>
<script src="resources/regress-pre.js"></script>
<script src="script-tests/marsaglia-larger-ints.js"></script>
<script src="resources/regress-post.js"></script>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>
function foo(x, y) {
var z = x;
function bar() {
return z;
}
for (var i = 0; i < 3; ++i)
z += y;
return bar();
}
eval("// Don't compile me");
var result = 0;
for (var i = 0; i < 100000; ++i)
result += foo(1000000000, 1000000000);
if (result != 400000000000000)
throw "Error: bad result: " + result;
function foo(x, y) {
var z = x;
var w = 0;
for (var i = 0; i < 3; ++i) {
z += y;
w = -z;
}
return w + 1;
}
eval("// Don't compile me");
var result = 0;
for (var i = 0; i < 1000000; ++i)
result += foo(1000000000, 1000000000);
if (result != -3999999999000000)
throw "Error: bad result: " + result;
function foo(x, y) {
var z = x;
for (var i = 0; i < 3; ++i)
z += y;
return z;
}
eval("// Don't compile me");
var result = 0;
for (var i = 0; i < 1000000; ++i)
result += foo(1000000000, 1000000000);
if (result != 4000000000000000)
throw "Error: bad result: " + result;
function uint(x) {
if (x < 0)
return x + 4294967296;
return x;
}
function marsaglia(m_z, m_w, n) {
var result;
for (var i = 0; i < n; ++i) {
m_z = (36969 * uint(m_z & 65535) + (m_z >> 16)) | 0;
m_w = (18000 * uint(m_w & 65535) + (m_w >> 16)) | 0;
result = ((m_z << 16) + m_w) | 0;
}
return result;
}
var result = marsaglia(5, 7, 10000000);
if (result != -1047364056)
throw "Error: bad result: " + result;
......@@ -47,7 +47,4 @@ function foo(a) {
return x | 0
}
for (var i = 0; i < 200; ++i)
shouldBe("foo(2147483647)", "2147483552");
dfgShouldBe(foo, "foo(2147483647)", "2147483552");
This diff is collapsed.
......@@ -230,6 +230,16 @@ public:
m_assembler.shlq_i8r(imm.m_value, dest);
}
void rshift64(TrustedImm32 imm, RegisterID dest)
{
m_assembler.sarq_i8r(imm.m_value, dest);
}
void mul64(RegisterID src, RegisterID dest)
{
m_assembler.imulq_rr(src, dest);
}
void neg64(RegisterID dest)
{
m_assembler.negq_r(dest);
......@@ -530,6 +540,14 @@ public:
return Jump(m_assembler.jCC(x86Condition(cond)));
}
Jump branchMul64(ResultCondition cond, RegisterID src, RegisterID dest)
{
mul64(src, dest);
if (cond != Overflow)
m_assembler.testq_rr(dest, dest);
return Jump(m_assembler.jCC(x86Condition(cond)));
}
Jump branchSub64(ResultCondition cond, TrustedImm32 imm, RegisterID dest)
{
sub64(imm, dest);
......@@ -548,6 +566,12 @@ public:
return branchSub64(cond, src2, dest);
}
Jump branchNeg64(ResultCondition cond, RegisterID srcDest)
{
neg64(srcDest);
return Jump(m_assembler.jCC(x86Condition(cond)));
}
ConvertibleLoadLabel convertibleLoadPtr(Address address, RegisterID dest)
{
ConvertibleLoadLabel result = ConvertibleLoadLabel(this);
......@@ -595,6 +619,11 @@ public:
return MacroAssemblerX86Common::branchTest8(cond, Address(scratchRegister), mask);
}
void convertInt64ToDouble(RegisterID src, FPRegisterID dest)
{
m_assembler.cvtsi2sdq_rr(src, dest);
}
static bool supportsFloatingPoint() { return true; }
// See comment on MacroAssemblerARMv7::supportsFloatingPointTruncate()
static bool supportsFloatingPointTruncate() { return true; }
......
......@@ -829,13 +829,20 @@ public:
m_formatter.immediate8(imm);
}
}
#endif
#endif // CPU(X86_64)
void imull_rr(RegisterID src, RegisterID dst)
{
m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, src);
}
#if CPU(X86_64)
void imulq_rr(RegisterID src, RegisterID dst)
{
m_formatter.twoByteOp64(OP2_IMUL_GvEv, dst, src);
}
#endif // CPU(X86_64)
void imull_mr(int offset, RegisterID base, RegisterID dst)
{
m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, base, offset);
......@@ -1611,6 +1618,14 @@ public:
m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src);
}
#if CPU(X86_64)
void cvtsi2sdq_rr(RegisterID src, XMMRegisterID dst)
{
m_formatter.prefix(PRE_SSE_F2);
m_formatter.twoByteOp64(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src);
}
#endif
void cvtsi2sd_mr(int offset, RegisterID base, XMMRegisterID dst)
{
m_formatter.prefix(PRE_SSE_F2);
......
......@@ -39,10 +39,12 @@ namespace JSC {
enum DataFormat {
DataFormatNone = 0,
DataFormatInt32 = 1,
DataFormatDouble = 2,
DataFormatBoolean = 3,
DataFormatCell = 4,
DataFormatStorage = 5,
DataFormatInt52 = 2, // Int52's are left-shifted by 16 by default.
DataFormatStrictInt52 = 3, // "Strict" Int52 means it's not shifted.
DataFormatDouble = 4,
DataFormatBoolean = 5,
DataFormatCell = 6,
DataFormatStorage = 7,
DataFormatJS = 8,
DataFormatJSInt32 = DataFormatJS | DataFormatInt32,
DataFormatJSDouble = DataFormatJS | DataFormatDouble,
......@@ -64,6 +66,10 @@ inline const char* dataFormatToString(DataFormat dataFormat)
return "None";
case DataFormatInt32:
return "Int32";
case DataFormatInt52:
return "Int52";
case DataFormatStrictInt52:
return "StrictInt52";
case DataFormatDouble:
return "Double";
case DataFormatCell:
......
......@@ -52,8 +52,8 @@ const char* exitKindToString(ExitKind kind)
return "Overflow";
case NegativeZero:
return "NegativeZero";
case Int48Overflow:
return "Int48Overflow";
case Int52Overflow:
return "Int52Overflow";
case StoreToHole:
return "StoreToHole";
case LoadFromHole:
......
......@@ -38,7 +38,7 @@ enum ExitKind {
BadIndexingType, // We exited because an indexing type was wrong.
Overflow, // We exited because of overflow.
NegativeZero, // We exited because we encountered negative zero.
Int48Overflow, // We exited because of an Int48 overflow.
Int52Overflow, // We exited because of an Int52 overflow.
StoreToHole, // We had a store to a hole.
LoadFromHole, // We had a load from a hole.
OutOfBounds, // We had an out-of-bounds access to an array.
......
......@@ -43,7 +43,7 @@ void Operands<T, Traits>::dumpInContext(PrintStream& out, DumpContext* context)
for (size_t localIndex = 0; localIndex < numberOfLocals(); ++localIndex) {
if (Traits::isEmptyForDump(local(localIndex)))
continue;
out.print(comma, "r", localIndex, ":", inContext(local(localIndex), context));
out.print(comma, "loc", localIndex, ":", inContext(local(localIndex), context));
}
}
......
......@@ -154,20 +154,18 @@ void dumpSpeculation(PrintStream& out, SpeculatedType value)
}
if (value & SpecInt32)
myOut.print("Int");
myOut.print("Int32");
else
isTop = false;
if (value & SpecInt52)
myOut.print("Int52");
if ((value & SpecDouble) == SpecDouble)
myOut.print("Double");
else {
if (value & SpecInt48AsDouble)
myOut.print("Int48asdouble");
else
isTop = false;
if (value & SpecInt48)
myOut.print("Int48");
if (value & SpecInt52AsDouble)
myOut.print("Int52asdouble");
else
isTop = false;
......@@ -243,13 +241,15 @@ static const char* speculationToAbbreviatedString(SpeculatedType prediction)
return "<Cell>";
if (isInt32Speculation(prediction))
return "<Int32>";
if (isInt48AsDoubleSpeculation(prediction))
return "<Int48AsDouble>";
if (isInt48Speculation(prediction))
return "<Int48>";
if (isInt52AsDoubleSpeculation(prediction))
return "<Int52AsDouble>";
if (isInt52Speculation(prediction))
return "<Int52>";
if (isMachineIntSpeculation(prediction))
return "<MachineInt>";
if (isDoubleSpeculation(prediction))
return "<Double>";
if (isNumberSpeculation(prediction))
if (isFullNumberSpeculation(prediction))
return "<Number>";
if (isBooleanSpeculation(prediction))
return "<Boolean>";
......@@ -345,16 +345,11 @@ SpeculatedType speculationFromValue(JSValue value)
return SpecInt32;
if (value.isDouble()) {
double number = value.asNumber();
if (number == number) {
int64_t asInt64 = static_cast<int64_t>(number);
if (asInt64 == number && (asInt64 || !std::signbit(number))
&& asInt64 < (static_cast<int64_t>(1) << 47)
&& asInt64 >= -(static_cast<int64_t>(1) << 47)) {
return SpecInt48AsDouble;
}
return SpecNonIntAsDouble;
}
return SpecDoubleNaN;
if (number != number)
return SpecDoubleNaN;
if (value.isMachineInt())
return SpecInt52AsDouble;
return SpecNonIntAsDouble;
}
if (value.isCell())
return speculationFromCell(value.asCell());
......
......@@ -44,12 +44,15 @@ enum ValueRecoveryTechnique {
AlreadyInJSStack,