Changeset 156029 in webkit
- Timestamp:
- Sep 18, 2013 12:25:52 AM (11 years ago)
- Location:
- trunk
- Files:
-
- 12 deleted
- 69 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r156022 r156029 1 2013-09-18 Commit Queue <commit-queue@webkit.org> 2 3 Unreviewed, rolling out r156019 and r156020. 4 http://trac.webkit.org/changeset/156019 5 http://trac.webkit.org/changeset/156020 6 https://bugs.webkit.org/show_bug.cgi?id=121540 7 8 Broke tests (Requested by ap on #webkit). 9 10 * js/regress/large-int-captured-expected.txt: Removed. 11 * js/regress/large-int-captured.html: Removed. 12 * js/regress/large-int-expected.txt: Removed. 13 * js/regress/large-int-neg-expected.txt: Removed. 14 * js/regress/large-int-neg.html: Removed. 15 * js/regress/large-int.html: Removed. 16 * js/regress/marsaglia-larger-ints-expected.txt: Removed. 17 * js/regress/marsaglia-larger-ints.html: Removed. 18 * js/regress/script-tests/large-int-captured.js: Removed. 19 * js/regress/script-tests/large-int-neg.js: Removed. 20 * js/regress/script-tests/large-int.js: Removed. 21 * js/regress/script-tests/marsaglia-larger-ints.js: Removed. 22 1 23 2013-09-17 Zoltan Horvath <zoltan@webkit.org> 2 24 -
trunk/Source/JavaScriptCore/ChangeLog
r156020 r156029 1 2013-09-18 Commit Queue <commit-queue@webkit.org> 2 3 Unreviewed, rolling out r156019 and r156020. 4 http://trac.webkit.org/changeset/156019 5 http://trac.webkit.org/changeset/156020 6 https://bugs.webkit.org/show_bug.cgi?id=121540 7 8 Broke tests (Requested by ap on #webkit). 9 10 * assembler/MacroAssemblerX86_64.h: 11 * assembler/X86Assembler.h: 12 * bytecode/DataFormat.h: 13 (JSC::dataFormatToString): 14 * bytecode/ExitKind.cpp: 15 (JSC::exitKindToString): 16 * bytecode/ExitKind.h: 17 * bytecode/OperandsInlines.h: 18 (JSC::::dumpInContext): 19 * bytecode/SpeculatedType.cpp: 20 (JSC::dumpSpeculation): 21 (JSC::speculationToAbbreviatedString): 22 (JSC::speculationFromValue): 23 * bytecode/SpeculatedType.h: 24 (JSC::isInt32SpeculationForArithmetic): 25 (JSC::isInt48Speculation): 26 (JSC::isMachineIntSpeculationForArithmetic): 27 (JSC::isInt48AsDoubleSpeculation): 28 (JSC::isRealNumberSpeculation): 29 (JSC::isNumberSpeculation): 30 (JSC::isNumberSpeculationExpectingDefined): 31 * bytecode/ValueRecovery.h: 32 (JSC::ValueRecovery::inGPR): 33 (JSC::ValueRecovery::displacedInJSStack): 34 (JSC::ValueRecovery::isAlreadyInJSStack): 35 (JSC::ValueRecovery::gpr): 36 (JSC::ValueRecovery::virtualRegister): 37 (JSC::ValueRecovery::dumpInContext): 38 * dfg/DFGAbstractInterpreter.h: 39 (JSC::DFG::AbstractInterpreter::needsTypeCheck): 40 (JSC::DFG::AbstractInterpreter::filterByType): 41 * dfg/DFGAbstractInterpreterInlines.h: 42 (JSC::DFG::::executeEffects): 43 * dfg/DFGAbstractValue.cpp: 44 (JSC::DFG::AbstractValue::set): 45 (JSC::DFG::AbstractValue::checkConsistency): 46 * dfg/DFGAbstractValue.h: 47 (JSC::DFG::AbstractValue::validateType): 48 * dfg/DFGArrayMode.cpp: 49 (JSC::DFG::ArrayMode::refine): 50 * dfg/DFGAssemblyHelpers.h: 51 (JSC::DFG::AssemblyHelpers::unboxDouble): 52 * dfg/DFGByteCodeParser.cpp: 53 (JSC::DFG::ByteCodeParser::makeSafe): 54 * dfg/DFGCSEPhase.cpp: 55 (JSC::DFG::CSEPhase::canonicalize): 56 (JSC::DFG::CSEPhase::pureCSE): 57 (JSC::DFG::CSEPhase::getByValLoadElimination): 58 (JSC::DFG::CSEPhase::performNodeCSE): 59 * dfg/DFGClobberize.h: 60 (JSC::DFG::clobberize): 61 * dfg/DFGCommon.h: 62 * dfg/DFGFixupPhase.cpp: 63 (JSC::DFG::FixupPhase::run): 64 (JSC::DFG::FixupPhase::fixupNode): 65 (JSC::DFG::FixupPhase::fixupSetLocalsInBlock): 66 (JSC::DFG::FixupPhase::observeUseKindOnNode): 67 (JSC::DFG::FixupPhase::fixEdge): 68 (JSC::DFG::FixupPhase::injectInt32ToDoubleNode): 69 (JSC::DFG::FixupPhase::attemptToMakeIntegerAdd): 70 * dfg/DFGFlushFormat.cpp: 71 (WTF::printInternal): 72 * dfg/DFGFlushFormat.h: 73 (JSC::DFG::resultFor): 74 (JSC::DFG::useKindFor): 75 * dfg/DFGGenerationInfo.h: 76 (JSC::DFG::GenerationInfo::initInt32): 77 (JSC::DFG::GenerationInfo::fillInt32): 78 * dfg/DFGGraph.cpp: 79 (JSC::DFG::Graph::dump): 80 * dfg/DFGGraph.h: 81 (JSC::DFG::Graph::addShouldSpeculateMachineInt): 82 (JSC::DFG::Graph::mulShouldSpeculateMachineInt): 83 (JSC::DFG::Graph::negateShouldSpeculateMachineInt): 84 * dfg/DFGInPlaceAbstractState.cpp: 85 (JSC::DFG::InPlaceAbstractState::mergeStateAtTail): 86 * dfg/DFGJITCode.cpp: 87 (JSC::DFG::JITCode::reconstruct): 88 * dfg/DFGMinifiedNode.h: 89 (JSC::DFG::belongsInMinifiedGraph): 90 (JSC::DFG::MinifiedNode::hasChild): 91 * dfg/DFGNode.h: 92 (JSC::DFG::Node::shouldSpeculateNumber): 93 (JSC::DFG::Node::shouldSpeculateNumberExpectingDefined): 94 (JSC::DFG::Node::canSpeculateInt48): 95 * dfg/DFGNodeFlags.h: 96 (JSC::DFG::nodeCanSpeculateInt48): 97 * dfg/DFGNodeType.h: 98 (JSC::DFG::forwardRewiringSelectionScore): 99 * dfg/DFGOSRExitCompiler.cpp: 100 (JSC::DFG::shortOperandsDump): 101 * dfg/DFGOSRExitCompiler64.cpp: 102 (JSC::DFG::OSRExitCompiler::compileExit): 103 * dfg/DFGPredictionPropagationPhase.cpp: 104 (JSC::DFG::PredictionPropagationPhase::speculatedDoubleTypeForPrediction): 105 (JSC::DFG::PredictionPropagationPhase::propagate): 106 (JSC::DFG::PredictionPropagationPhase::doDoubleVoting): 107 * dfg/DFGSafeToExecute.h: 108 (JSC::DFG::SafeToExecuteEdge::operator()): 109 (JSC::DFG::safeToExecute): 110 * dfg/DFGSilentRegisterSavePlan.h: 111 * dfg/DFGSpeculativeJIT.cpp: 112 (JSC::DFG::SpeculativeJIT::silentSavePlanForGPR): 113 (JSC::DFG::SpeculativeJIT::silentFill): 114 (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch): 115 (JSC::DFG::SpeculativeJIT::compileInlineStart): 116 (JSC::DFG::SpeculativeJIT::compileDoublePutByVal): 117 (JSC::DFG::SpeculativeJIT::compileValueToInt32): 118 (JSC::DFG::SpeculativeJIT::compileInt32ToDouble): 119 (JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray): 120 (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray): 121 (JSC::DFG::SpeculativeJIT::compileAdd): 122 (JSC::DFG::SpeculativeJIT::compileArithSub): 123 (JSC::DFG::SpeculativeJIT::compileArithNegate): 124 (JSC::DFG::SpeculativeJIT::compileArithMul): 125 (JSC::DFG::SpeculativeJIT::compare): 126 (JSC::DFG::SpeculativeJIT::compileStrictEq): 127 (JSC::DFG::SpeculativeJIT::speculateNumber): 128 (JSC::DFG::SpeculativeJIT::speculateRealNumber): 129 (JSC::DFG::SpeculativeJIT::speculate): 130 * dfg/DFGSpeculativeJIT.h: 131 (JSC::DFG::SpeculativeJIT::canReuse): 132 (JSC::DFG::SpeculativeJIT::isFilled): 133 (JSC::DFG::SpeculativeJIT::isFilledDouble): 134 (JSC::DFG::SpeculativeJIT::use): 135 (JSC::DFG::SpeculativeJIT::boxDouble): 136 (JSC::DFG::SpeculativeJIT::isKnownInteger): 137 (JSC::DFG::SpeculativeJIT::isKnownCell): 138 (JSC::DFG::SpeculativeJIT::isKnownNotNumber): 139 (JSC::DFG::SpeculativeJIT::int32Result): 140 (JSC::DFG::SpeculativeJIT::initConstantInfo): 141 (JSC::DFG::SpeculativeJIT::isInteger): 142 (JSC::DFG::SpeculativeJIT::generationInfoFromVirtualRegister): 143 * dfg/DFGSpeculativeJIT32_64.cpp: 144 (JSC::DFG::SpeculativeJIT::fillSpeculateDouble): 145 (JSC::DFG::SpeculativeJIT::compile): 146 * dfg/DFGSpeculativeJIT64.cpp: 147 (JSC::DFG::SpeculativeJIT::fillJSValue): 148 (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal): 149 (JSC::DFG::SpeculativeJIT::fillSpeculateDouble): 150 (JSC::DFG::SpeculativeJIT::fillSpeculateCell): 151 (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean): 152 (JSC::DFG::SpeculativeJIT::compile): 153 * dfg/DFGUseKind.cpp: 154 (WTF::printInternal): 155 * dfg/DFGUseKind.h: 156 (JSC::DFG::typeFilterFor): 157 (JSC::DFG::isNumerical): 158 * dfg/DFGValueSource.cpp: 159 (JSC::DFG::ValueSource::dump): 160 * dfg/DFGValueSource.h: 161 (JSC::DFG::dataFormatToValueSourceKind): 162 (JSC::DFG::valueSourceKindToDataFormat): 163 (JSC::DFG::ValueSource::forFlushFormat): 164 (JSC::DFG::ValueSource::valueRecovery): 165 * dfg/DFGVariableAccessData.h: 166 (JSC::DFG::VariableAccessData::shouldUseDoubleFormatAccordingToVote): 167 (JSC::DFG::VariableAccessData::flushFormat): 168 * ftl/FTLCArgumentGetter.cpp: 169 (JSC::FTL::CArgumentGetter::loadNextAndBox): 170 * ftl/FTLCArgumentGetter.h: 171 * ftl/FTLCapabilities.cpp: 172 (JSC::FTL::canCompile): 173 * ftl/FTLExitValue.cpp: 174 (JSC::FTL::ExitValue::dumpInContext): 175 * ftl/FTLExitValue.h: 176 * ftl/FTLIntrinsicRepository.h: 177 * ftl/FTLLowerDFGToLLVM.cpp: 178 (JSC::FTL::LowerDFGToLLVM::createPhiVariables): 179 (JSC::FTL::LowerDFGToLLVM::compileNode): 180 (JSC::FTL::LowerDFGToLLVM::compileUpsilon): 181 (JSC::FTL::LowerDFGToLLVM::compilePhi): 182 (JSC::FTL::LowerDFGToLLVM::compileSetLocal): 183 (JSC::FTL::LowerDFGToLLVM::compileAdd): 184 (JSC::FTL::LowerDFGToLLVM::compileArithSub): 185 (JSC::FTL::LowerDFGToLLVM::compileArithMul): 186 (JSC::FTL::LowerDFGToLLVM::compileArithNegate): 187 (JSC::FTL::LowerDFGToLLVM::compilePutByVal): 188 (JSC::FTL::LowerDFGToLLVM::compileCompareEq): 189 (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq): 190 (JSC::FTL::LowerDFGToLLVM::compileCompareLess): 191 (JSC::FTL::LowerDFGToLLVM::compileCompareLessEq): 192 (JSC::FTL::LowerDFGToLLVM::compileCompareGreater): 193 (JSC::FTL::LowerDFGToLLVM::compileCompareGreaterEq): 194 (JSC::FTL::LowerDFGToLLVM::lowInt32): 195 (JSC::FTL::LowerDFGToLLVM::lowCell): 196 (JSC::FTL::LowerDFGToLLVM::lowBoolean): 197 (JSC::FTL::LowerDFGToLLVM::lowDouble): 198 (JSC::FTL::LowerDFGToLLVM::lowJSValue): 199 (JSC::FTL::LowerDFGToLLVM::speculateRealNumber): 200 (JSC::FTL::LowerDFGToLLVM::initializeOSRExitStateForBlock): 201 (JSC::FTL::LowerDFGToLLVM::emitOSRExitCall): 202 (JSC::FTL::LowerDFGToLLVM::addExitArgumentForNode): 203 (JSC::FTL::LowerDFGToLLVM::setInt32): 204 * ftl/FTLOSRExitCompiler.cpp: 205 (JSC::FTL::compileStub): 206 * ftl/FTLOutput.h: 207 (JSC::FTL::Output::mulWithOverflow32): 208 * ftl/FTLValueFormat.cpp: 209 (WTF::printInternal): 210 * ftl/FTLValueFormat.h: 211 * ftl/FTLValueSource.cpp: 212 (JSC::FTL::ValueSource::dump): 213 * ftl/FTLValueSource.h: 214 * interpreter/Register.h: 215 * runtime/Arguments.cpp: 216 (JSC::Arguments::tearOffForInlineCallFrame): 217 * runtime/IndexingType.cpp: 218 (JSC::leastUpperBoundOfIndexingTypeAndType): 219 * runtime/JSCJSValue.h: 220 * runtime/JSCJSValueInlines.h: 221 1 222 2013-09-17 Filip Pizlo <fpizlo@apple.com> 2 223 -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h
r156019 r156029 231 231 } 232 232 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 243 233 void neg64(RegisterID dest) 244 234 { … … 541 531 } 542 532 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 551 533 Jump branchSub64(ResultCondition cond, TrustedImm32 imm, RegisterID dest) 552 534 { … … 565 547 move(src1, dest); 566 548 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)));573 549 } 574 550 … … 618 594 MacroAssemblerX86Common::move(TrustedImmPtr(address.m_ptr), scratchRegister); 619 595 return MacroAssemblerX86Common::branchTest8(cond, Address(scratchRegister), mask); 620 }621 622 void convertInt64ToDouble(RegisterID src, FPRegisterID dest)623 {624 m_assembler.cvtsi2sdq_rr(src, dest);625 596 } 626 597 -
trunk/Source/JavaScriptCore/assembler/X86Assembler.h
r156019 r156029 830 830 } 831 831 } 832 #endif // CPU(X86_64)832 #endif 833 833 834 834 void imull_rr(RegisterID src, RegisterID dst) … … 836 836 m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, src); 837 837 } 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)845 838 846 839 void imull_mr(int offset, RegisterID base, RegisterID dst) … … 1618 1611 m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src); 1619 1612 } 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 #endif1628 1613 1629 1614 void cvtsi2sd_mr(int offset, RegisterID base, XMMRegisterID dst) -
trunk/Source/JavaScriptCore/bytecode/DataFormat.h
r156019 r156029 40 40 DataFormatNone = 0, 41 41 DataFormatInt32 = 1, 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, 42 DataFormatDouble = 2, 43 DataFormatBoolean = 3, 44 DataFormatCell = 4, 45 DataFormatStorage = 5, 48 46 DataFormatJS = 8, 49 47 DataFormatJSInt32 = DataFormatJS | DataFormatInt32, … … 67 65 case DataFormatInt32: 68 66 return "Int32"; 69 case DataFormatInt52:70 return "Int52";71 case DataFormatStrictInt52:72 return "StrictInt52";73 67 case DataFormatDouble: 74 68 return "Double"; -
trunk/Source/JavaScriptCore/bytecode/ExitKind.cpp
r156019 r156029 53 53 case NegativeZero: 54 54 return "NegativeZero"; 55 case Int 52Overflow:56 return "Int 52Overflow";55 case Int48Overflow: 56 return "Int48Overflow"; 57 57 case StoreToHole: 58 58 return "StoreToHole"; -
trunk/Source/JavaScriptCore/bytecode/ExitKind.h
r156019 r156029 39 39 Overflow, // We exited because of overflow. 40 40 NegativeZero, // We exited because we encountered negative zero. 41 Int 52Overflow, // We exited because of an Int52overflow.41 Int48Overflow, // We exited because of an Int48 overflow. 42 42 StoreToHole, // We had a store to a hole. 43 43 LoadFromHole, // We had a load from a hole. -
trunk/Source/JavaScriptCore/bytecode/OperandsInlines.h
r156019 r156029 44 44 if (Traits::isEmptyForDump(local(localIndex))) 45 45 continue; 46 out.print(comma, " loc", localIndex, ":", inContext(local(localIndex), context));46 out.print(comma, "r", localIndex, ":", inContext(local(localIndex), context)); 47 47 } 48 48 } -
trunk/Source/JavaScriptCore/bytecode/SpeculatedType.cpp
r156019 r156029 155 155 156 156 if (value & SpecInt32) 157 myOut.print("Int 32");157 myOut.print("Int"); 158 158 else 159 159 isTop = false; 160 160 161 if (value & SpecInt52)162 myOut.print("Int52");163 164 161 if ((value & SpecDouble) == SpecDouble) 165 162 myOut.print("Double"); 166 163 else { 167 if (value & SpecInt52AsDouble) 168 myOut.print("Int52asdouble"); 164 if (value & SpecInt48AsDouble) 165 myOut.print("Int48asdouble"); 166 else 167 isTop = false; 168 169 if (value & SpecInt48) 170 myOut.print("Int48"); 169 171 else 170 172 isTop = false; … … 242 244 if (isInt32Speculation(prediction)) 243 245 return "<Int32>"; 244 if (isInt52AsDoubleSpeculation(prediction)) 245 return "<Int52AsDouble>"; 246 if (isInt52Speculation(prediction)) 247 return "<Int52>"; 248 if (isMachineIntSpeculation(prediction)) 249 return "<MachineInt>"; 246 if (isInt48AsDoubleSpeculation(prediction)) 247 return "<Int48AsDouble>"; 248 if (isInt48Speculation(prediction)) 249 return "<Int48>"; 250 250 if (isDoubleSpeculation(prediction)) 251 251 return "<Double>"; 252 if (is FullNumberSpeculation(prediction))252 if (isNumberSpeculation(prediction)) 253 253 return "<Number>"; 254 254 if (isBooleanSpeculation(prediction)) … … 346 346 if (value.isDouble()) { 347 347 double number = value.asNumber(); 348 if (number != number) 349 return SpecDoubleNaN; 350 if (value.isMachineInt()) 351 return SpecInt52AsDouble; 352 return SpecNonIntAsDouble; 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; 353 358 } 354 359 if (value.isCell()) -
trunk/Source/JavaScriptCore/bytecode/SpeculatedType.h
r156019 r156029 39 39 40 40 typedef 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 SpecInt52 = 0x01000000; // It's definitely an Int52 and we intend it to unbox it. 66 static const SpeculatedType SpecMachineInt = 0x01800000; // It's something that we can do machine int arithmetic on. 67 static const SpeculatedType SpecInt52AsDouble = 0x02000000; // It's definitely an Int52 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 Int52 but it's a real number and it's a double. 70 static const SpeculatedType SpecDoubleReal = 0x06000000; // It's definitely a non-NaN double. 71 static const SpeculatedType SpecDoubleNaN = 0x08000000; // It's definitely a NaN. 72 static const SpeculatedType SpecDouble = 0x0e000000; // It's either a non-NaN or a NaN double. 73 static const SpeculatedType SpecBytecodeRealNumber = 0x06800000; // It's either an Int32 or a DoubleReal. 74 static const SpeculatedType SpecFullRealNumber = 0x07800000; // It's either an Int32 or a DoubleReal, or a Int52. 75 static const SpeculatedType SpecBytecodeNumber = 0x0e800000; // It's either an Int32 or a Double. 76 static const SpeculatedType SpecFullNumber = 0x0f800000; // It's either an Int32, Int52, or a Double. 77 static const SpeculatedType SpecBoolean = 0x10000000; // It's definitely a Boolean. 78 static const SpeculatedType SpecOther = 0x20000000; // It's definitely none of the above. 79 static const SpeculatedType SpecHeapTop = 0x3effffff; // It can be any of the above, except for SpecInt52. 80 static const SpeculatedType SpecEmpty = 0x40000000; // It's definitely an empty value marker. 81 static const SpeculatedType SpecBytecodeTop = 0x7effffff; // It can be any of the above, except for SpecInt52. 82 static const SpeculatedType SpecFullTop = 0x7fffffff; // It can be any of the above plus anything the DFG chooses. 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. 83 81 84 82 typedef bool (*SpeculatedTypeChecker)(SpeculatedType); … … 243 241 inline bool isInt32SpeculationForArithmetic(SpeculatedType value) 244 242 { 245 return !(value & (SpecDouble | SpecInt52));243 return !(value & SpecDouble); 246 244 } 247 245 … … 251 249 } 252 250 253 inline bool isInt 52Speculation(SpeculatedType value)254 { 255 return value == SpecInt 52;251 inline bool isInt48Speculation(SpeculatedType value) 252 { 253 return value == SpecInt48; 256 254 } 257 255 … … 268 266 inline bool isMachineIntSpeculationForArithmetic(SpeculatedType value) 269 267 { 270 return !(value & SpecDouble);271 } 272 273 inline bool isInt 52AsDoubleSpeculation(SpeculatedType value)274 { 275 return value == SpecInt 52AsDouble;268 return !(value & (SpecDouble & ~SpecMachineInt)); 269 } 270 271 inline bool isInt48AsDoubleSpeculation(SpeculatedType value) 272 { 273 return value == SpecInt48AsDouble; 276 274 } 277 275 … … 296 294 } 297 295 298 inline bool isBytecodeRealNumberSpeculation(SpeculatedType value) 299 { 300 return !!(value & SpecBytecodeRealNumber) && !(value & ~SpecBytecodeRealNumber); 301 } 302 303 inline bool isFullRealNumberSpeculation(SpeculatedType value) 304 { 305 return !!(value & SpecFullRealNumber) && !(value & ~SpecFullRealNumber); 306 } 307 308 inline bool isBytecodeNumberSpeculation(SpeculatedType value) 309 { 310 return !!(value & SpecBytecodeNumber) && !(value & ~SpecBytecodeNumber); 311 } 312 313 inline bool isFullNumberSpeculation(SpeculatedType value) 314 { 315 return !!(value & SpecFullNumber) && !(value & ~SpecFullNumber); 316 } 317 318 inline bool isBytecodeNumberSpeculationExpectingDefined(SpeculatedType value) 319 { 320 return isBytecodeNumberSpeculation(value & ~SpecOther); 321 } 322 323 inline bool isFullNumberSpeculationExpectingDefined(SpeculatedType value) 324 { 325 return isFullNumberSpeculation(value & ~SpecOther); 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); 326 309 } 327 310 -
trunk/Source/JavaScriptCore/bytecode/ValueRecovery.h
r156019 r156029 45 45 // It's already in the stack but unboxed. 46 46 AlreadyInJSStackAsUnboxedInt32, 47 AlreadyInJSStackAsUnboxedInt52,48 47 AlreadyInJSStackAsUnboxedCell, 49 48 AlreadyInJSStackAsUnboxedBoolean, … … 52 51 InGPR, 53 52 UnboxedInt32InGPR, 54 UnboxedInt52InGPR,55 UnboxedStrictInt52InGPR,56 53 UnboxedBooleanInGPR, 57 54 #if USE(JSVALUE32_64) … … 64 61 // It's in the stack, at a different location, and it's unboxed. 65 62 Int32DisplacedInJSStack, 66 Int52DisplacedInJSStack,67 StrictInt52DisplacedInJSStack,68 63 DoubleDisplacedInJSStack, 69 64 CellDisplacedInJSStack, … … 101 96 } 102 97 103 static ValueRecovery alreadyInJSStackAsUnboxedInt52()104 {105 ValueRecovery result;106 result.m_technique = AlreadyInJSStackAsUnboxedInt52;107 return result;108 }109 110 98 static ValueRecovery alreadyInJSStackAsUnboxedCell() 111 99 { … … 138 126 if (dataFormat == DataFormatInt32) 139 127 result.m_technique = UnboxedInt32InGPR; 140 else if (dataFormat == DataFormatInt52)141 result.m_technique = UnboxedInt52InGPR;142 else if (dataFormat == DataFormatStrictInt52)143 result.m_technique = UnboxedStrictInt52InGPR;144 128 else if (dataFormat == DataFormatBoolean) 145 129 result.m_technique = UnboxedBooleanInGPR; … … 185 169 break; 186 170 187 case DataFormatInt52:188 result.m_technique = Int52DisplacedInJSStack;189 break;190 191 case DataFormatStrictInt52:192 result.m_technique = StrictInt52DisplacedInJSStack;193 break;194 195 171 case DataFormatDouble: 196 172 result.m_technique = DoubleDisplacedInJSStack; … … 254 230 case AlreadyInJSStack: 255 231 case AlreadyInJSStackAsUnboxedInt32: 256 case AlreadyInJSStackAsUnboxedInt52:257 232 case AlreadyInJSStackAsUnboxedCell: 258 233 case AlreadyInJSStackAsUnboxedBoolean: … … 266 241 MacroAssembler::RegisterID gpr() const 267 242 { 268 ASSERT(m_technique == InGPR || m_technique == UnboxedInt32InGPR || m_technique == UnboxedBooleanInGPR || m_technique == UInt32InGPR || m_technique == UnboxedInt52InGPR || m_technique == UnboxedStrictInt52InGPR);243 ASSERT(m_technique == InGPR || m_technique == UnboxedInt32InGPR || m_technique == UnboxedBooleanInGPR || m_technique == UInt32InGPR); 269 244 return m_source.gpr; 270 245 } … … 292 267 VirtualRegister virtualRegister() const 293 268 { 294 ASSERT(m_technique == DisplacedInJSStack || m_technique == Int32DisplacedInJSStack || m_technique == DoubleDisplacedInJSStack || m_technique == CellDisplacedInJSStack || m_technique == BooleanDisplacedInJSStack || m_technique == Int52DisplacedInJSStack || m_technique == StrictInt52DisplacedInJSStack);269 ASSERT(m_technique == DisplacedInJSStack || m_technique == Int32DisplacedInJSStack || m_technique == DoubleDisplacedInJSStack || m_technique == CellDisplacedInJSStack || m_technique == BooleanDisplacedInJSStack); 295 270 return m_source.virtualReg; 296 271 } … … 311 286 out.printf("(int32)"); 312 287 return; 313 case AlreadyInJSStackAsUnboxedInt52:314 out.printf("(int52)");315 return;316 288 case AlreadyInJSStackAsUnboxedCell: 317 289 out.printf("(cell)"); … … 329 301 out.printf("int32(%%r%d)", gpr()); 330 302 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;337 303 case UnboxedBooleanInGPR: 338 304 out.printf("bool(%%r%d)", gpr()); … … 354 320 case Int32DisplacedInJSStack: 355 321 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());362 322 return; 363 323 case DoubleDisplacedInJSStack: -
trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h
r156019 r156029 61 61 bool needsTypeCheck(Node* node, SpeculatedType typesPassedThrough) 62 62 { 63 return !forNode(node).isType(typesPassedThrough);63 return forNode(node).m_type & ~typesPassedThrough; 64 64 } 65 65 … … 169 169 { 170 170 AbstractValue& value = forNode(edge); 171 if ( !value.isType(type)) {171 if (value.m_type & ~type) { 172 172 node->setCanExit(true); 173 173 edge.setProofStatus(NeedsCheck); -
trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
r156019 r156029 311 311 } 312 312 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 336 313 case ValueAdd: 337 314 case ArithAdd: { … … 348 325 node->setCanExit(true); 349 326 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;356 327 case NumberUse: 357 if (is FullRealNumberSpeculation(forNode(node->child1()).m_type)358 && is FullRealNumberSpeculation(forNode(node->child2()).m_type))328 if (isRealNumberSpeculation(forNode(node->child1()).m_type) 329 && isRealNumberSpeculation(forNode(node->child2()).m_type)) 359 330 forNode(node).setType(SpecDoubleReal); 360 331 else … … 364 335 RELEASE_ASSERT(node->op() == ValueAdd); 365 336 clobberWorld(node->codeOrigin, clobberLimit); 366 forNode(node).setType(SpecString | Spec BytecodeNumber);337 forNode(node).setType(SpecString | SpecInt32 | SpecNumber); 367 338 break; 368 339 } … … 388 359 node->setCanExit(true); 389 360 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;396 361 case NumberUse: 397 362 forNode(node).setType(SpecDouble); … … 414 379 forNode(node).setType(SpecInt32); 415 380 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()))423 381 node->setCanExit(true); 424 382 break; … … 447 405 node->setCanExit(true); 448 406 break; 449 case MachineIntUse:450 forNode(node).setType(SpecInt52);451 node->setCanExit(true);452 break;453 407 case NumberUse: 454 if (is FullRealNumberSpeculation(forNode(node->child1()).m_type)455 || is FullRealNumberSpeculation(forNode(node->child2()).m_type))408 if (isRealNumberSpeculation(forNode(node->child1()).m_type) 409 || isRealNumberSpeculation(forNode(node->child2()).m_type)) 456 410 forNode(node).setType(SpecDoubleReal); 457 411 else … … 633 587 } 634 588 635 if (is FullNumberSpeculation(abstractChild.m_type)) {589 if (isNumberSpeculation(abstractChild.m_type)) { 636 590 setConstant(node, vm->smallStrings.numberString()); 637 591 break; … … 858 812 if (node->shouldSpeculateInt32()) 859 813 forNode(node).setType(SpecInt32); 860 else if (enableInt52() && node->shouldSpeculateMachineInt())861 forNode(node).setType(SpecInt52);862 814 else 863 815 forNode(node).setType(SpecDouble); … … 912 864 node->setCanExit(true); 913 865 clobberWorld(node->codeOrigin, clobberLimit); 914 forNode(node).setType(Spec BytecodeNumber);866 forNode(node).setType(SpecNumber); 915 867 break; 916 868 … … 983 935 // 984 936 // destination = source; 985 // if (destination.m_type & !(Spec FullNumber | SpecString | SpecBoolean)) {986 // destination.filter(Spec FullNumber | SpecString | SpecBoolean);937 // if (destination.m_type & !(SpecNumber | SpecString | SpecBoolean)) { 938 // destination.filter(SpecNumber | SpecString | SpecBoolean); 987 939 // AbstractValue string; 988 940 // string.set(vm->stringStructure); … … 1004 956 1005 957 SpeculatedType type = source.m_type; 1006 if (type & ~(Spec FullNumber | SpecString | SpecBoolean))958 if (type & ~(SpecNumber | SpecString | SpecBoolean)) 1007 959 type = (SpecHeapTop & ~SpecCell) | SpecString; 1008 960 -
trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp
r156019 r156029 68 68 69 69 m_type = speculationFromValue(value); 70 if (m_type == SpecInt52AsDouble)71 m_type = SpecInt52;72 70 m_value = value; 73 71 … … 230 228 } 231 229 232 #if !ASSERT_DISABLED233 230 void AbstractValue::checkConsistency() const 234 231 { … … 242 239 ASSERT(!m_value); 243 240 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 } 241 if (!!m_value) 242 ASSERT(mergeSpeculations(m_type, speculationFromValue(m_value)) == m_type); 250 243 251 244 // Note that it's possible for a prediction like (Final, []). This really means that … … 254 247 // complexity of the code. 255 248 } 256 #endif257 249 258 250 void AbstractValue::dump(PrintStream& out) const -
trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.h
r156019 r156029 186 186 } 187 187 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 198 188 FiltrationResult filter(Graph&, const StructureSet&); 199 189 … … 203 193 204 194 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 } 205 211 206 212 bool validate(JSValue value) const … … 246 252 } 247 253 248 #if ASSERT_DISABLED249 void checkConsistency() const { }250 #else251 254 void checkConsistency() const; 252 #endif253 255 254 256 void dumpInContext(PrintStream&, DumpContext*) const; … … 362 364 } 363 365 364 bool validateType(JSValue value) const365 {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 387 366 void makeTop(SpeculatedType top) 388 367 { -
trunk/Source/JavaScriptCore/dfg/DFGArrayMode.cpp
r156019 r156029 164 164 if (isInt32Speculation(value)) 165 165 return withTypeAndConversion(Array::Int32, Array::Convert); 166 if (is FullNumberSpeculation(value))166 if (isNumberSpeculation(value)) 167 167 return withTypeAndConversion(Array::Double, Array::Convert); 168 168 return withTypeAndConversion(Array::Contiguous, Array::Convert); … … 171 171 if (!value || isInt32Speculation(value)) 172 172 return *this; 173 if (is FullNumberSpeculation(value))173 if (isNumberSpeculation(value)) 174 174 return withTypeAndConversion(Array::Double, Array::Convert); 175 175 return withTypeAndConversion(Array::Contiguous, Array::Convert); … … 178 178 if (flags & NodeBytecodeUsesAsInt) 179 179 return withTypeAndConversion(Array::Contiguous, Array::RageConvert); 180 if (!value || is FullNumberSpeculation(value))180 if (!value || isNumberSpeculation(value)) 181 181 return *this; 182 182 return withTypeAndConversion(Array::Contiguous, Array::Convert); -
trunk/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h
r156019 r156029 294 294 return fpr; 295 295 } 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 }314 296 #endif 315 297 -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r156019 r156029 875 875 case ArithAdd: 876 876 case ArithSub: 877 case ArithNegate: 877 878 case ValueAdd: 878 879 case ArithMod: // for ArithMod "MayOverflow" means we tried to divide by zero, or we saw double. … … 880 881 break; 881 882 882 case ArithNegate:883 // Currently we can't tell the difference between a negation overflowing884 // (i.e. -(1 << 31)) or generating negative zero (i.e. -0). If it took slow885 // path then we assume that it did both of those things.886 node->mergeFlags(NodeMayOverflow);887 node->mergeFlags(NodeMayNegZero);888 break;889 890 883 case ArithMul: 891 884 if (m_inlineStackTop->m_profiledBlock->likelyToTakeDeepestSlowCase(m_currentIndex) -
trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
r156019 r156029 64 64 private: 65 65 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 66 81 unsigned endIndexForPureCSE() 67 82 { … … 80 95 Node* pureCSE(Node* node) 81 96 { 82 Edge child1 = node->child1();83 Edge child2 = node->child2();84 Edge child3 = node->child3();97 Node* child1 = canonicalize(node->child1()); 98 Node* child2 = canonicalize(node->child2()); 99 Node* child3 = canonicalize(node->child3()); 85 100 86 101 for (unsigned i = endIndexForPureCSE(); i--;) { … … 95 110 continue; 96 111 97 Edge otherChild = otherNode->child1();112 Node* otherChild = canonicalize(otherNode->child1()); 98 113 if (!otherChild) 99 114 return otherNode; … … 101 116 continue; 102 117 103 otherChild = otherNode->child2();118 otherChild = canonicalize(otherNode->child2()); 104 119 if (!otherChild) 105 120 return otherNode; … … 107 122 continue; 108 123 109 otherChild = otherNode->child3();124 otherChild = canonicalize(otherNode->child3()); 110 125 if (!otherChild) 111 126 return otherNode; … … 363 378 for (unsigned i = m_indexInBlock; i--;) { 364 379 Node* node = m_currentBlock->at(i); 365 if (node == child1 || node == c hild2)380 if (node == child1 || node == canonicalize(child2)) 366 381 break; 367 382 … … 370 385 if (!m_graph.byValIsPure(node)) 371 386 return 0; 372 if (node->child1() == child1 && node->child2() == child2)387 if (node->child1() == child1 && canonicalize(node->child2()) == canonicalize(child2)) 373 388 return node; 374 389 break; … … 377 392 if (!m_graph.byValIsPure(node)) 378 393 return 0; 379 if (m_graph.varArgChild(node, 0) == child1 && m_graph.varArgChild(node, 1) == child2)394 if (m_graph.varArgChild(node, 0) == child1 && canonicalize(m_graph.varArgChild(node, 1)) == canonicalize(child2)) 380 395 return m_graph.varArgChild(node, 2).node(); 381 396 // We must assume that the PutByVal will clobber the location we're getting from. … … 1076 1091 case ValueToInt32: 1077 1092 case MakeRope: 1078 case Int52ToDouble:1079 case Int52ToValue:1080 1093 if (cseMode == StoreElimination) 1081 1094 break; -
trunk/Source/JavaScriptCore/dfg/DFGClobberize.h
r156019 r156029 113 113 case Int32ToDouble: 114 114 case ExtractOSREntryLocal: 115 case Int52ToDouble:116 case Int52ToValue:117 115 return; 118 116 … … 183 181 case Int32Use: 184 182 case NumberUse: 185 case MachineIntUse:186 183 return; 187 184 case UntypedUse: -
trunk/Source/JavaScriptCore/dfg/DFGCommon.h
r156019 r156029 139 139 #if ENABLE(CONCURRENT_JIT) 140 140 return Options::enableConcurrentJIT() && Options::numberOfCompilerThreads(); 141 #else142 return false;143 #endif144 }145 146 inline bool enableInt52()147 {148 #if USE(JSVALUE64)149 return true;150 141 #else 151 142 return false; -
trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
r156019 r156029 65 65 } 66 66 67 for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)68 fixupUntypedSetLocalsInBlock(m_graph.block(blockIndex));69 70 67 return true; 71 68 } … … 96 93 case SetLocal: { 97 94 // This gets handled by fixupSetLocalsInBlock(). 98 return;95 break; 99 96 } 100 97 … … 128 125 } 129 126 130 if (node->child1()->shouldSpeculateMachineInt()) {131 fixEdge<MachineIntUse>(node->child1());132 break;133 }134 135 127 if (node->child1()->shouldSpeculateNumber()) { 136 128 fixEdge<NumberUse>(node->child1()); … … 206 198 break; 207 199 } 208 if (m_graph.negateShouldSpeculateMachineInt(node)) {209 fixEdge<MachineIntUse>(node->child1());210 break;211 }212 200 fixEdge<NumberUse>(node->child1()); 213 201 break; … … 218 206 fixEdge<Int32Use>(node->child1()); 219 207 fixEdge<Int32Use>(node->child2()); 220 break;221 }222 if (m_graph.mulShouldSpeculateMachineInt(node)) {223 fixEdge<MachineIntUse>(node->child1());224 fixEdge<MachineIntUse>(node->child2());225 208 break; 226 209 } … … 318 301 break; 319 302 } 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 }326 303 if (Node::shouldSpeculateNumber(node->child1().node(), node->child2().node())) { 327 304 fixEdge<NumberUse>(node->child1()); … … 377 354 fixEdge<Int32Use>(node->child1()); 378 355 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());385 356 break; 386 357 } … … 506 477 fixEdge<Int32Use>(child2); 507 478 fixEdge<Int32Use>(child3); 508 if (child3->prediction() & SpecInt52)509 fixEdge<MachineIntUse>(child3);510 else511 fixEdge<Int32Use>(child3);512 479 break; 513 480 case Array::Double: … … 527 494 if (child3->shouldSpeculateInt32()) 528 495 fixEdge<Int32Use>(child3); 529 else if (child3->shouldSpeculateMachineInt())530 fixEdge<MachineIntUse>(child3);531 496 else 532 497 fixEdge<NumberUse>(child3); … … 883 848 case CheckTierUpAtReturn: 884 849 case CheckTierUpAndOSREnter: 885 case Int52ToDouble:886 case Int52ToValue:887 850 RELEASE_ASSERT_NOT_REACHED(); 888 851 break; … … 1227 1190 fixEdge<Int32Use>(node->child1()); 1228 1191 break; 1229 case FlushedInt52:1230 fixEdge<MachineIntUse>(node->child1());1231 break;1232 1192 case FlushedCell: 1233 1193 fixEdge<CellUse>(node->child1()); … … 1240 1200 break; 1241 1201 } 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());1259 1202 } 1260 1203 m_insertionSet.execute(block); … … 1362 1305 return; 1363 1306 1364 // FIXME: The way this uses alwaysUnboxSimplePrimitives() is suspicious.1365 // https://bugs.webkit.org/show_bug.cgi?id=1215181366 1367 1307 VariableAccessData* variable = node->variableAccessData(); 1368 1308 switch (useKind) { … … 1380 1320 if (alwaysUnboxSimplePrimitives() 1381 1321 || isBooleanSpeculation(variable->prediction())) 1382 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);1383 break;1384 case MachineIntUse:1385 if (isMachineIntSpeculation(variable->prediction()))1386 1322 m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true); 1387 1323 break; … … 1412 1348 void fixEdge(Edge& edge, SpeculationDirection direction = BackwardSpeculation) 1413 1349 { 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); 1350 if (isDouble(useKind) && edge->shouldSpeculateInt32ForArithmetic()) { 1351 injectInt32ToDoubleNode(edge, useKind, direction); 1483 1352 return; 1484 1353 } 1485 1354 1486 1355 observeUseKindOnNode<useKind>(edge.node()); 1487 1488 1356 edge.setUseKind(useKind); 1489 1357 } … … 1511 1379 { 1512 1380 Node* result = m_insertionSet.insertNode( 1513 m_indexInBlock, SpecInt 52AsDouble, Int32ToDouble,1381 m_indexInBlock, SpecInt48, Int32ToDouble, 1514 1382 m_currentNode->codeOrigin, Edge(edge.node(), NumberUse)); 1515 1383 if (direction == ForwardSpeculation) … … 1567 1435 { 1568 1436 AddSpeculationMode mode = m_graph.addSpeculationMode(node); 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; 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; 1583 1444 } 1584 1445 -
trunk/Source/JavaScriptCore/dfg/DFGFlushFormat.cpp
r156019 r156029 42 42 out.print("FlushedInt32"); 43 43 return; 44 case FlushedInt52:45 out.print("FlushedInt52");46 return;47 44 case FlushedDouble: 48 45 out.print("FlushedDouble"); -
trunk/Source/JavaScriptCore/dfg/DFGFlushFormat.h
r156019 r156029 41 41 DeadFlush, 42 42 FlushedInt32, 43 FlushedInt52,44 43 FlushedDouble, 45 44 FlushedCell, … … 57 56 case FlushedInt32: 58 57 return NodeResultInt32; 59 case FlushedInt52:60 return NodeResultInt52;61 58 case FlushedDouble: 62 59 return NodeResultNumber; … … 78 75 case FlushedInt32: 79 76 return Int32Use; 80 case FlushedInt52:81 return MachineIntUse;82 77 case FlushedDouble: 83 78 return NumberUse; -
trunk/Source/JavaScriptCore/dfg/DFGGenerationInfo.h
r156019 r156029 87 87 initGPR(node, useCount, gpr, DataFormatInt32); 88 88 } 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 }102 89 #if USE(JSVALUE64) 103 90 void initJSValue(Node* node, uint32_t useCount, GPRReg gpr, DataFormat format = DataFormatJS) … … 201 188 DataFormat spillFormat() { return m_spillFormat; } 202 189 203 bool isFormat(DataFormat expectedFormat)204 {205 return registerFormat() == expectedFormat || spillFormat() == expectedFormat;206 }207 208 190 bool isJSFormat(DataFormat expectedFormat) 209 191 { … … 214 196 { 215 197 return isJSFormat(DataFormatJSInt32); 216 }217 218 bool isInt52()219 {220 return isFormat(DataFormatInt52);221 }222 223 bool isStrictInt52()224 {225 return isFormat(DataFormatStrictInt52);226 198 } 227 199 … … 342 314 { 343 315 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);357 316 } 358 317 void fillBoolean(VariableEventStream& stream, GPRReg gpr) -
trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp
r156019 r156029 237 237 out.print(comma, "arg", operandToArgument(operand), "(", VariableAccessDataDump(*this, variableAccessData), ")"); 238 238 else 239 out.print(comma, " loc", operandToLocal(operand), "(", VariableAccessDataDump(*this, variableAccessData), ")");239 out.print(comma, "r", operand, "(", VariableAccessDataDump(*this, variableAccessData), ")"); 240 240 } 241 241 if (node->hasUnlinkedLocal()) { … … 244 244 out.print(comma, "arg", operandToArgument(operand)); 245 245 else 246 out.print(comma, " loc", operandToLocal(operand));246 out.print(comma, "r", operand); 247 247 } 248 248 if (node->hasConstantBuffer()) { -
trunk/Source/JavaScriptCore/dfg/DFGGraph.h
r156019 r156029 231 231 bool addShouldSpeculateMachineInt(Node* add) 232 232 { 233 if (!enableInt52())234 return false;235 236 233 Node* left = add->child1().node(); 237 234 Node* right = add->child2().node(); … … 239 236 bool speculation; 240 237 if (add->op() == ValueAdd) 241 speculation = Node::shouldSpeculateMachineInt (left, right);238 speculation = Node::shouldSpeculateMachineIntExpectingDefined(left, right); 242 239 else 243 speculation = Node::shouldSpeculateMachineInt (left, right);244 245 return speculation && !hasExitSite(add, Int 52Overflow);240 speculation = Node::shouldSpeculateMachineIntForArithmetic(left, right); 241 242 return speculation && !hasExitSite(add, Int48Overflow); 246 243 } 247 244 … … 261 258 ASSERT(mul->op() == ArithMul); 262 259 263 if (!enableInt52())264 return false;265 266 260 Node* left = mul->child1().node(); 267 261 Node* right = mul->child2().node(); 268 262 269 return Node::shouldSpeculateMachineInt (left, right)270 && mul->canSpeculateInt 52()271 && !hasExitSite(mul, Int 52Overflow);263 return Node::shouldSpeculateMachineIntForArithmetic(left, right) 264 && mul->canSpeculateInt48() 265 && !hasExitSite(mul, Int48Overflow); 272 266 } 273 267 … … 281 275 { 282 276 ASSERT(negate->op() == ArithNegate); 283 if (!enableInt52()) 284 return false; 285 return negate->child1()->shouldSpeculateMachineInt() 286 && !hasExitSite(negate, Int52Overflow) 287 && negate->canSpeculateInt52(); 277 return negate->child1()->shouldSpeculateMachineIntForArithmetic() 278 && !hasExitSite(negate, Int48Overflow) 279 && negate->canSpeculateInt48(); 288 280 } 289 281 -
trunk/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp
r156019 r156029 314 314 source = forNode(node->child1()); 315 315 if (node->variableAccessData()->flushFormat() == FlushedDouble) { 316 ASSERT(!(source.m_type & ~Spec FullNumber));317 ASSERT(!!(source.m_type & ~SpecDouble) == !!(source.m_type & Spec MachineInt));316 ASSERT(!(source.m_type & ~SpecNumber)); 317 ASSERT(!!(source.m_type & ~SpecDouble) == !!(source.m_type & SpecInt32)); 318 318 if (!(source.m_type & ~SpecDouble)) { 319 source.merge(SpecInt 52AsDouble);319 source.merge(SpecInt48AsDouble); 320 320 source.filter(SpecDouble); 321 321 } -
trunk/Source/JavaScriptCore/dfg/DFGJITCode.cpp
r156019 r156029 104 104 value = jsNumber(exec->r(operand).unboxedInt32()); 105 105 break; 106 case AlreadyInJSStackAsUnboxedInt52:107 value = jsNumber(exec->r(operand).unboxedInt52());108 break;109 106 case AlreadyInJSStackAsUnboxedDouble: 110 107 value = jsDoubleNumber(exec->r(operand).unboxedDouble()); -
trunk/Source/JavaScriptCore/dfg/DFGMinifiedNode.h
r156019 r156029 49 49 case DoubleAsInt32: 50 50 case PhantomArguments: 51 case Int52ToValue:52 case Int52ToDouble:53 51 return true; 54 52 default: … … 107 105 case UInt32ToNumber: 108 106 case DoubleAsInt32: 109 case Int52ToDouble:110 case Int52ToValue:111 107 return true; 112 108 default: -
trunk/Source/JavaScriptCore/dfg/DFGNode.h
r156019 r156029 1242 1242 bool shouldSpeculateNumber() 1243 1243 { 1244 return is FullNumberSpeculation(prediction());1244 return isNumberSpeculation(prediction()); 1245 1245 } 1246 1246 1247 1247 bool shouldSpeculateNumberExpectingDefined() 1248 1248 { 1249 return is FullNumberSpeculationExpectingDefined(prediction());1249 return isNumberSpeculationExpectingDefined(prediction()); 1250 1250 } 1251 1251 … … 1425 1425 } 1426 1426 1427 bool canSpeculateInt 52()1428 { 1429 return nodeCanSpeculateInt 52(arithNodeFlags());1427 bool canSpeculateInt48() 1428 { 1429 return nodeCanSpeculateInt48(arithNodeFlags()); 1430 1430 } 1431 1431 -
trunk/Source/JavaScriptCore/dfg/DFGNodeFlags.h
r156019 r156029 42 42 #define NodeResultNumber 0x0002 43 43 #define NodeResultInt32 0x0003 44 #define NodeResultInt52 0x0004 45 #define NodeResultBoolean 0x0005 46 #define NodeResultStorage 0x0006 44 #define NodeResultBoolean 0x0004 45 #define NodeResultStorage 0x0005 47 46 48 47 #define NodeMustGenerate 0x0008 // set on nodes that have side effects, and may not trivially be removed by DCE. … … 109 108 } 110 109 111 static inline bool nodeCanSpeculateInt 52(NodeFlags flags)110 static inline bool nodeCanSpeculateInt48(NodeFlags flags) 112 111 { 113 112 if (nodeMayNegZero(flags)) -
trunk/Source/JavaScriptCore/dfg/DFGNodeType.h
r156019 r156029 115 115 /* Used to speculate that a double value is actually an integer. */\ 116 116 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) \121 117 \ 122 118 /* Nodes for arithmetic operations. */\ … … 361 357 return 25; 362 358 363 case Int52ToValue:364 // Loses no information. It just boxes the value, which is what OSR wants365 // to do anyway.366 return 100;367 368 case Int52ToDouble:369 // This is like Int32ToDouble; we can use it because it gives a semantically370 // equivalent value but that value may be an int32 in a double, so we'd371 // rather not if we can avoid it.372 return 75;373 374 359 default: 375 360 return 0; -
trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp
r156019 r156029 40 40 41 41 namespace 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 } 42 50 43 51 extern "C" { … … 110 118 exitIndex, toCString(exit.m_codeOrigin).data(), 111 119 exitKindToString(exit.m_kind), toCString(*codeBlock).data(), 112 toCString(ignoringContext<DumpContext>(operands)).data()));120 shortOperandsDump(operands).data())); 113 121 } 114 122 -
trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp
r156019 r156029 196 196 case UnboxedInt32InGPR: 197 197 case UInt32InGPR: 198 case UnboxedInt52InGPR:199 case UnboxedStrictInt52InGPR:200 198 m_jit.store64(recovery.gpr(), scratch + index); 201 199 break; … … 238 236 case Int32DisplacedInJSStack: 239 237 case DoubleDisplacedInJSStack: 240 case Int52DisplacedInJSStack:241 case StrictInt52DisplacedInJSStack:242 238 m_jit.load64(AssemblyHelpers::addressFor(recovery.virtualRegister()), GPRInfo::regT0); 243 239 m_jit.store64(GPRInfo::regT0, scratch + index); … … 246 242 case AlreadyInJSStackAsUnboxedInt32: 247 243 case AlreadyInJSStackAsUnboxedDouble: 248 case AlreadyInJSStackAsUnboxedInt52:249 244 m_jit.load64(AssemblyHelpers::addressFor(operand), GPRInfo::regT0); 250 245 m_jit.store64(GPRInfo::regT0, scratch + index); … … 280 275 break; 281 276 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 306 277 case AlreadyInJSStackAsUnboxedDouble: 307 278 case InFPR: … … 312 283 m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand)); 313 284 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 } 314 304 315 305 case Constant: -
trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
r156019 r156029 117 117 SpeculatedType speculatedDoubleTypeForPrediction(SpeculatedType value) 118 118 { 119 if (!is FullNumberSpeculation(value))119 if (!isNumberSpeculation(value)) 120 120 return SpecDouble; 121 121 if (value & SpecDoubleNaN) … … 143 143 case WeakJSConstant: { 144 144 SpeculatedType type = speculationFromValue(m_graph.valueOfJSConstant(node)); 145 if (type == SpecInt 52AsDouble)146 type = SpecInt 52;145 if (type == SpecInt48AsDouble) 146 type = SpecInt48; 147 147 changed |= setPrediction(type); 148 148 break; … … 150 150 151 151 case GetLocal: { 152 VariableAccessData* variable = node->variableAccessData(); 153 SpeculatedType prediction = variable->prediction(); 154 if (variable->shouldNeverUnbox() && (prediction & SpecInt52)) 155 prediction = (prediction | SpecInt52AsDouble) & ~SpecInt52; 152 VariableAccessData* variableAccessData = node->variableAccessData(); 153 SpeculatedType prediction = variableAccessData->prediction(); 156 154 if (prediction) 157 155 changed |= mergePrediction(prediction); … … 206 204 changed |= mergePrediction(SpecInt32); 207 205 else 208 changed |= mergePrediction(Spec BytecodeNumber);206 changed |= mergePrediction(SpecNumber); 209 207 break; 210 208 } … … 215 213 216 214 if (left && right) { 217 if (is FullNumberSpeculationExpectingDefined(left) && isFullNumberSpeculationExpectingDefined(right)) {215 if (isNumberSpeculationExpectingDefined(left) && isNumberSpeculationExpectingDefined(right)) { 218 216 if (m_graph.addSpeculationMode(node) != DontSpeculateInt32) 219 217 changed |= mergePrediction(SpecInt32); 220 218 else if (m_graph.addShouldSpeculateMachineInt(node)) 221 changed |= mergePrediction(SpecInt 52);219 changed |= mergePrediction(SpecInt48); 222 220 else 223 221 changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right)); 224 } else if (!(left & Spec FullNumber) || !(right & SpecFullNumber)) {222 } else if (!(left & SpecNumber) || !(right & SpecNumber)) { 225 223 // left or right is definitely something other than a number. 226 224 changed |= mergePrediction(SpecString); … … 239 237 changed |= mergePrediction(SpecInt32); 240 238 else if (m_graph.addShouldSpeculateMachineInt(node)) 241 changed |= mergePrediction(SpecInt 52);239 changed |= mergePrediction(SpecInt48); 242 240 else 243 241 changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right)); … … 254 252 changed |= mergePrediction(SpecInt32); 255 253 else if (m_graph.addShouldSpeculateMachineInt(node)) 256 changed |= mergePrediction(SpecInt 52);254 changed |= mergePrediction(SpecInt48); 257 255 else 258 256 changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right)); … … 266 264 changed |= mergePrediction(SpecInt32); 267 265 else if (m_graph.negateShouldSpeculateMachineInt(node)) 268 changed |= mergePrediction(SpecInt 52);266 changed |= mergePrediction(SpecInt48); 269 267 else 270 268 changed |= mergePrediction(speculatedDoubleTypeForPrediction(node->child1()->prediction())); … … 295 293 changed |= mergePrediction(SpecInt32); 296 294 else if (m_graph.mulShouldSpeculateMachineInt(node)) 297 changed |= mergePrediction(SpecInt 52);295 changed |= mergePrediction(SpecInt48); 298 296 else 299 297 changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right)); … … 371 369 372 370 case GetByVal: { 373 if (!node->child1()->prediction())374 break;375 if (!node->getHeapPrediction())376 break;377 378 371 if (node->child1()->shouldSpeculateFloat32Array() 379 372 || node->child1()->shouldSpeculateFloat64Array()) 380 373 changed |= mergePrediction(SpecDouble); 381 else if (node->child1()->shouldSpeculateUint32Array()) { 382 if (isInt32Speculation(node->getHeapPrediction())) 383 changed |= mergePrediction(SpecInt32); 384 else 385 changed |= mergePrediction(SpecInt52); 386 } else 374 else 387 375 changed |= mergePrediction(node->getHeapPrediction()); 388 376 break; … … 579 567 case Unreachable: 580 568 case LoopHint: 581 case Int52ToValue:582 case Int52ToDouble:583 569 break; 584 570 … … 655 641 DoubleBallot ballot; 656 642 657 if (isFullNumberSpeculationExpectingDefined(left) && isFullNumberSpeculationExpectingDefined(right) 658 && !m_graph.addShouldSpeculateInt32(node) 659 && !m_graph.addShouldSpeculateMachineInt(node)) 643 if (isNumberSpeculationExpectingDefined(left) && isNumberSpeculationExpectingDefined(right) 644 && !m_graph.addShouldSpeculateInt32(node)) 660 645 ballot = VoteDouble; 661 646 else … … 673 658 DoubleBallot ballot; 674 659 675 if (isFullNumberSpeculation(left) && isFullNumberSpeculation(right) 676 && !m_graph.mulShouldSpeculateInt32(node) 677 && !m_graph.mulShouldSpeculateMachineInt(node)) 660 if (isNumberSpeculation(left) && isNumberSpeculation(right) 661 && !m_graph.mulShouldSpeculateInt32(node)) 678 662 ballot = VoteDouble; 679 663 else … … 694 678 DoubleBallot ballot; 695 679 696 if (is FullNumberSpeculation(left) && isFullNumberSpeculation(right)680 if (isNumberSpeculation(left) && isNumberSpeculation(right) 697 681 && !(Node::shouldSpeculateInt32ForArithmetic(node->child1().node(), node->child2().node()) && node->canSpeculateInt32())) 698 682 ballot = VoteDouble; … … 723 707 if (isDoubleSpeculation(prediction)) 724 708 node->variableAccessData()->vote(VoteDouble); 725 else if ( 726 !isFullNumberSpeculation(prediction) 727 || isInt32Speculation(prediction) || isMachineIntSpeculation(prediction)) 709 else if (!isNumberSpeculation(prediction) || isInt32Speculation(prediction)) 728 710 node->variableAccessData()->vote(VoteValue); 729 711 break; -
trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
r156019 r156029 62 62 case NotCellUse: 63 63 case OtherUse: 64 case MachineIntUse:65 64 return; 66 65 … … 71 70 72 71 case KnownNumberUse: 73 if (m_state.forNode(edge).m_type & ~Spec FullNumber)72 if (m_state.forNode(edge).m_type & ~SpecNumber) 74 73 m_result = false; 75 74 return; … … 241 240 case CheckTierUpAndOSREnter: 242 241 case LoopHint: 243 case Int52ToDouble:244 case Int52ToValue:245 242 return true; 246 243 -
trunk/Source/JavaScriptCore/dfg/DFGSilentRegisterSavePlan.h
r156019 r156029 49 49 DoNothingForFill, 50 50 SetInt32Constant, 51 SetInt52Constant,52 SetStrictInt52Constant,53 51 SetBooleanConstant, 54 52 SetCellConstant, … … 64 62 Load32Payload, 65 63 Load32PayloadBoxInt, 66 Load32PayloadConvertToInt52,67 Load32PayloadSignExtend,68 64 LoadPtr, 69 65 Load64, 70 Load64ShiftInt52Right,71 Load64ShiftInt52Left,72 66 LoadDouble, 73 67 LoadDoubleBoxDouble, -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r156019 r156029 336 336 else if (registerFormat == DataFormatCell || registerFormat == DataFormatStorage) 337 337 spillAction = StorePtr; 338 else if (registerFormat == DataFormatInt52 || registerFormat == DataFormatStrictInt52)339 spillAction = Store64;340 338 else { 341 339 ASSERT(registerFormat & DataFormatJS); … … 389 387 ASSERT(info.gpr() == source); 390 388 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 never404 // be turned into a cell (immediate spec fail) or a double (to-double405 // 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 never422 // be turned into a cell (immediate spec fail) or a double (to-double423 // conversions involve a separate node).424 RELEASE_ASSERT_NOT_REACHED();425 fillAction = Load64; // Make GCC happy.426 }427 389 } else { 428 390 ASSERT(registerFormat & DataFormatJS); … … 432 394 if (valueOfJSConstant(node).isCell()) 433 395 fillAction = SetTrustedJSConstant; 396 else 434 397 fillAction = SetJSConstant; 435 398 } else if (info.spillFormat() == DataFormatInt32) { … … 550 513 m_jit.move(Imm32(valueOfInt32Constant(plan.node())), plan.gpr()); 551 514 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)560 515 case SetBooleanConstant: 561 516 m_jit.move(TrustedImm32(valueOfBooleanConstant(plan.node())), plan.gpr()); … … 579 534 m_jit.or64(GPRInfo::tagTypeNumberRegister, plan.gpr()); 580 535 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;590 536 case LoadDoubleBoxDouble: 591 537 m_jit.load64(JITCompiler::addressFor(plan.node()->virtualRegister()), plan.gpr()); … … 628 574 case Load64: 629 575 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());638 576 break; 639 577 #endif … … 1479 1417 if (node->isBinaryUseKind(Int32Use)) 1480 1418 compilePeepHoleInt32Branch(node, branchNode, condition); 1481 #if USE(JSVALUE64)1482 else if (node->isBinaryUseKind(MachineIntUse))1483 compilePeepHoleInt52Branch(node, branchNode, condition);1484 #endif // USE(JSVALUE64)1485 1419 else if (node->isBinaryUseKind(NumberUse)) 1486 1420 compilePeepHoleDoubleBranch(node, branchNode, doubleCondition); … … 1573 1507 case FlushedInt32: 1574 1508 valueSource = ValueSource(Int32InJSStack); 1575 break;1576 case FlushedInt52:1577 valueSource = ValueSource(Int52InJSStack);1578 1509 break; 1579 1510 case FlushedCell: … … 1943 1874 1944 1875 DFG_TYPE_CHECK( 1945 JSValueRegs(), child3, Spec FullRealNumber,1876 JSValueRegs(), child3, SpecRealNumber, 1946 1877 m_jit.branchDouble( 1947 1878 MacroAssembler::DoubleNotEqualOrUnordered, valueReg, valueReg)); … … 2219 2150 return; 2220 2151 } 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)2233 2152 2234 2153 case NumberUse: … … 2269 2188 if (node->child1().useKind() == NumberUse) { 2270 2189 DFG_TYPE_CHECK( 2271 JSValueRegs(gpr), node->child1(), Spec FullNumber,2190 JSValueRegs(gpr), node->child1(), SpecNumber, 2272 2191 m_jit.branchTest64( 2273 2192 MacroAssembler::Zero, gpr, GPRInfo::tagTypeNumberRegister)); … … 2325 2244 if (node->child1().useKind() == NumberUse) { 2326 2245 DFG_TYPE_CHECK( 2327 JSValueRegs(tagGPR, payloadGPR), node->child1(), Spec FullNumber,2246 JSValueRegs(tagGPR, payloadGPR), node->child1(), SpecNumber, 2328 2247 m_jit.branch32( 2329 2248 MacroAssembler::AboveOrEqual, tagGPR, … … 2471 2390 MacroAssembler::AboveOrEqual, op1GPR, GPRInfo::tagTypeNumberRegister); 2472 2391 2473 if (needsTypeCheck(node->child1(), Spec FullNumber)) {2392 if (needsTypeCheck(node->child1(), SpecNumber)) { 2474 2393 if (node->flags() & NodeExitsForward) { 2475 2394 forwardTypeCheck( 2476 JSValueRegs(op1GPR), node->child1(), Spec FullNumber,2395 JSValueRegs(op1GPR), node->child1(), SpecNumber, 2477 2396 m_jit.branchTest64(MacroAssembler::Zero, op1GPR, GPRInfo::tagTypeNumberRegister), 2478 2397 ValueRecovery::inGPR(op1GPR, DataFormatJS)); 2479 2398 } else { 2480 2399 backwardTypeCheck( 2481 JSValueRegs(op1GPR), node->child1(), Spec FullNumber,2400 JSValueRegs(op1GPR), node->child1(), SpecNumber, 2482 2401 m_jit.branchTest64(MacroAssembler::Zero, op1GPR, GPRInfo::tagTypeNumberRegister)); 2483 2402 } … … 2502 2421 MacroAssembler::Equal, op1TagGPR, TrustedImm32(JSValue::Int32Tag)); 2503 2422 2504 if (needsTypeCheck(node->child1(), Spec FullNumber)) {2423 if (needsTypeCheck(node->child1(), SpecNumber)) { 2505 2424 if (node->flags() & NodeExitsForward) { 2506 2425 forwardTypeCheck( 2507 JSValueRegs(op1TagGPR, op1PayloadGPR), node->child1(), Spec FullNumber,2426 JSValueRegs(op1TagGPR, op1PayloadGPR), node->child1(), SpecNumber, 2508 2427 m_jit.branch32(MacroAssembler::AboveOrEqual, op1TagGPR, TrustedImm32(JSValue::LowestTag)), 2509 2428 ValueRecovery::inPair(op1TagGPR, op1PayloadGPR)); 2510 2429 } else { 2511 2430 backwardTypeCheck( 2512 JSValueRegs(op1TagGPR, op1PayloadGPR), node->child1(), Spec FullNumber,2431 JSValueRegs(op1TagGPR, op1PayloadGPR), node->child1(), SpecNumber, 2513 2432 m_jit.branch32(MacroAssembler::AboveOrEqual, op1TagGPR, TrustedImm32(JSValue::LowestTag))); 2514 2433 } … … 2630 2549 return; 2631 2550 } 2632 2633 #if USE(JSVALUE64)2634 if (node->shouldSpeculateMachineInt()) {2635 m_jit.zeroExtend32ToPtr(resultReg, resultReg);2636 strictInt52Result(resultReg, node);2637 return;2638 }2639 #endif2640 2551 2641 2552 FPRTemporary fresult(this); … … 2691 2602 break; 2692 2603 } 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)2718 2604 2719 2605 case NumberUse: { … … 2985 2871 return; 2986 2872 } 2987 2873 2988 2874 if (isNumberConstant(node->child2().node())) { 2989 2875 SpeculateInt32Operand op1(this, node->child1()); … … 3030 2916 return; 3031 2917 } 3032 3033 #if USE(JSVALUE64)3034 case MachineIntUse: {3035 // Will we need an overflow check? If we can prove that neither input can be3036 // 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)3059 2918 3060 2919 case NumberUse: { … … 3202 3061 } 3203 3062 3204 #if USE(JSVALUE64)3205 case MachineIntUse: {3206 // Will we need an overflow check? If we can prove that neither input can be3207 // 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 3231 3063 case NumberUse: { 3232 3064 SpeculateDoubleOperand op1(this, node->child1()); … … 3257 3089 m_jit.move(op1.gpr(), result.gpr()); 3258 3090 3259 // Note: there is no notion of being not used as a number, but someone3260 // caring about negative zero.3261 3262 3091 if (bytecodeCanTruncateInteger(node->arithNodeFlags())) 3263 3092 m_jit.neg32(result.gpr()); … … 3272 3101 return; 3273 3102 } 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)3310 3103 3311 3104 case NumberUse: { … … 3373 3166 return; 3374 3167 } 3375 3376 #if USE(JSVALUE64)3377 case MachineIntUse: {3378 // This is super clever. We want to do an int52 multiplication and check the3379 // int52 overflow bit. There is no direct hardware support for this, but we do3380 // have the ability to do an int64 multiplication and check the int64 overflow3381 // bit. We leverage that. Consider that a, b are int52 numbers inside int643382 // 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 163387 // bits are zero) plus the int52 overflow bit. I.e. whether this 64-bit3388 // multiplication overflows is identical to whether the 'a * b' 52-bit3389 // multiplication overflows.3390 //3391 // In our nomenclature, this is:3392 //3393 // strictInt52(a) * int52(b) => int523394 //3395 // That is "strictInt52" means unshifted and "int52" means left-shifted by 163396 // bits.3397 //3398 // We don't care which of op1 or op2 serves as the left-shifted operand, so3399 // we just do whatever is more convenient for op1 and have op2 do the3400 // 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)3431 3168 3432 3169 case NumberUse: { … … 3852 3589 return false; 3853 3590 } 3854 3855 #if USE(JSVALUE64) 3856 if (node->isBinaryUseKind(MachineIntUse)) { 3857 compileInt52Compare(node, condition); 3858 return false; 3859 } 3860 #endif // USE(JSVALUE64) 3861 3591 3862 3592 if (node->isBinaryUseKind(NumberUse)) { 3863 3593 compileDoubleCompare(node, doubleCondition); … … 4009 3739 return false; 4010 3740 } 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)4028 3741 4029 3742 case NumberUse: { … … 4781 4494 } 4782 4495 4783 void 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 4796 4496 void SpeculativeJIT::speculateNumber(Edge edge) 4797 4497 { 4798 if (!needsTypeCheck(edge, Spec FullNumber))4498 if (!needsTypeCheck(edge, SpecNumber)) 4799 4499 return; 4800 4500 … … 4804 4504 void SpeculativeJIT::speculateRealNumber(Edge edge) 4805 4505 { 4806 if (!needsTypeCheck(edge, Spec FullRealNumber))4506 if (!needsTypeCheck(edge, SpecRealNumber)) 4807 4507 return; 4808 4508 … … 4810 4510 FPRReg fpr = operand.fpr(); 4811 4511 DFG_TYPE_CHECK( 4812 JSValueRegs(), edge, Spec FullRealNumber,4512 JSValueRegs(), edge, SpecRealNumber, 4813 4513 m_jit.branchDouble( 4814 4514 MacroAssembler::DoubleNotEqualOrUnordered, fpr, fpr)); … … 5072 4772 break; 5073 4773 case KnownNumberUse: 5074 ASSERT(!needsTypeCheck(edge, Spec FullNumber));4774 ASSERT(!needsTypeCheck(edge, SpecNumber)); 5075 4775 break; 5076 4776 case KnownCellUse: … … 5082 4782 case Int32Use: 5083 4783 speculateInt32(edge); 5084 break;5085 case MachineIntUse:5086 speculateMachineInt(edge);5087 4784 break; 5088 4785 case RealNumberUse: -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r156019 r156029 160 160 bool canReuse(Node* node) 161 161 { 162 return generationInfo(node).canReuse(); 162 VirtualRegister virtualRegister = node->virtualRegister(); 163 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister); 164 return info.canReuse(); 163 165 } 164 166 bool canReuse(Edge nodeUse) … … 236 238 bool isFilled(Node* node) 237 239 { 238 return generationInfo(node).registerFormat() != DataFormatNone; 240 VirtualRegister virtualRegister = node->virtualRegister(); 241 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister); 242 return info.registerFormat() != DataFormatNone; 239 243 } 240 244 bool isFilledDouble(Node* node) 241 245 { 242 return generationInfo(node).registerFormat() == DataFormatDouble; 246 VirtualRegister virtualRegister = node->virtualRegister(); 247 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister); 248 return info.registerFormat() == DataFormatDouble; 243 249 } 244 250 … … 248 254 if (!node->hasResult()) 249 255 return; 250 GenerationInfo& info = generationInfo(node); 256 VirtualRegister virtualRegister = node->virtualRegister(); 257 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister); 251 258 252 259 // use() returns true when the value becomes dead, and any … … 327 334 GPRReg fillSpeculateInt32(Edge, DataFormat& returnFormat); 328 335 GPRReg fillSpeculateInt32Strict(Edge); 329 GPRReg fillSpeculateInt52(Edge, DataFormat desiredFormat);330 336 FPRReg fillSpeculateDouble(Edge); 331 337 GPRReg fillSpeculateCell(Edge); … … 463 469 return boxDouble(fpr, allocate()); 464 470 } 465 466 void boxInt52(GPRReg sourceGPR, GPRReg targetGPR, DataFormat);467 471 #elif USE(JSVALUE32_64) 468 472 void boxDouble(FPRReg fpr, GPRReg tagGPR, GPRReg payloadGPR) … … 556 560 } 557 561 558 bool isKnownInteger(Node* node) { return m_state.forNode(node).isType(SpecInt32); }559 bool isKnownCell(Node* node) { return m_state.forNode(node).isType(SpecCell); }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); } 560 564 561 565 bool isKnownNotInteger(Node* node) { return !(m_state.forNode(node).m_type & SpecInt32); } 562 bool isKnownNotNumber(Node* node) { return !(m_state.forNode(node).m_type & Spec FullNumber); }566 bool isKnownNotNumber(Node* node) { return !(m_state.forNode(node).m_type & SpecNumber); } 563 567 bool isKnownNotCell(Node* node) { return !(m_state.forNode(node).m_type & SpecCell); } 564 568 … … 813 817 int32Result(reg, node, DataFormatInt32, mode); 814 818 } 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 }834 819 void noResult(Node* node, UseChildrenMode mode = CallUseChildren) 835 820 { … … 916 901 { 917 902 ASSERT(isInt32Constant(node) || isNumberConstant(node) || isJSConstant(node)); 918 generationInfo (node).initConstant(node, node->refCount());903 generationInfoFromVirtualRegister(node->virtualRegister()).initConstant(node, node->refCount()); 919 904 } 920 905 … … 1905 1890 return true; 1906 1891 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()); 1892 VirtualRegister virtualRegister = node->virtualRegister(); 1893 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister); 1894 1895 return info.isJSInt32(); 1917 1896 } 1918 1897 … … 1920 1899 bool compilePeepHoleBranch(Node*, MacroAssembler::RelationalCondition, MacroAssembler::DoubleCondition, S_DFGOperation_EJJ); 1921 1900 void compilePeepHoleInt32Branch(Node*, Node* branchNode, JITCompiler::RelationalCondition); 1922 void compilePeepHoleInt52Branch(Node*, Node* branchNode, JITCompiler::RelationalCondition);1923 1901 void compilePeepHoleBooleanBranch(Node*, Node* branchNode, JITCompiler::RelationalCondition); 1924 1902 void compilePeepHoleDoubleBranch(Node*, Node* branchNode, JITCompiler::DoubleCondition); … … 1968 1946 1969 1947 void compileInt32Compare(Node*, MacroAssembler::RelationalCondition); 1970 void compileInt52Compare(Node*, MacroAssembler::RelationalCondition);1971 1948 void compileBooleanCompare(Node*, MacroAssembler::RelationalCondition); 1972 1949 void compileDoubleCompare(Node*, MacroAssembler::DoubleCondition); … … 2142 2119 2143 2120 void speculateInt32(Edge); 2144 void speculateMachineInt(Edge);2145 2121 void speculateNumber(Edge); 2146 2122 void speculateRealNumber(Edge); … … 2220 2196 return m_generationInfo[operandToLocal(virtualRegister)]; 2221 2197 } 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 }2232 2198 2233 2199 // The JIT, while also provides MacroAssembler functionality. … … 2711 2677 }; 2712 2678 2713 // Gives you a canonical Int52 (i.e. it's left-shifted by 16, low bits zero).2714 class SpeculateInt52Operand {2715 public: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() const2733 {2734 return m_edge;2735 }2736 2737 Node* node() const2738 {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 2754 private: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).2761 class SpeculateStrictInt52Operand {2762 public: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() const2780 {2781 return m_edge;2782 }2783 2784 Node* node() const2785 {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 2801 private:2802 SpeculativeJIT* m_jit;2803 Edge m_edge;2804 GPRReg m_gprOrInvalid;2805 };2806 2807 enum OppositeShiftTag { OppositeShift };2808 2809 class SpeculateWhicheverInt52Operand {2810 public: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() const2851 {2852 return m_edge;2853 }2854 2855 Node* node() const2856 {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() const2875 {2876 return m_strict ? DataFormatStrictInt52 : DataFormatInt52;2877 }2878 2879 private:2880 SpeculativeJIT* m_jit;2881 Edge m_edge;2882 GPRReg m_gprOrInvalid;2883 bool m_strict;2884 };2885 2886 2679 class SpeculateDoubleOperand { 2887 2680 public: -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r156019 r156029 889 889 AbstractValue& value = m_state.forNode(edge); 890 890 SpeculatedType type = value.m_type; 891 ASSERT(edge.useKind() != KnownNumberUse || !(value.m_type & ~Spec FullNumber));892 m_interpreter.filter(value, Spec FullNumber);891 ASSERT(edge.useKind() != KnownNumberUse || !(value.m_type & ~SpecNumber)); 892 m_interpreter.filter(value, SpecNumber); 893 893 VirtualRegister virtualRegister = edge->virtualRegister(); 894 894 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister); … … 929 929 if (spillFormat != DataFormatJSInt32 && spillFormat != DataFormatInt32) { 930 930 JITCompiler::Jump isInteger = m_jit.branch32(MacroAssembler::Equal, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::Int32Tag)); 931 if (type & ~Spec FullNumber)931 if (type & ~SpecNumber) 932 932 speculationCheck(BadType, JSValueSource(JITCompiler::addressFor(virtualRegister)), edge, m_jit.branch32(MacroAssembler::AboveOrEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::LowestTag))); 933 933 m_jit.loadDouble(JITCompiler::addressFor(virtualRegister), fpr); … … 964 964 FPRTemporary scratch(this); 965 965 JITCompiler::Jump isInteger = m_jit.branch32(MacroAssembler::Equal, tagGPR, TrustedImm32(JSValue::Int32Tag)); 966 if (type & ~Spec FullNumber)966 if (type & ~SpecNumber) 967 967 speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), edge, m_jit.branch32(MacroAssembler::AboveOrEqual, tagGPR, TrustedImm32(JSValue::LowestTag))); 968 968 unboxDouble(tagGPR, payloadGPR, fpr, scratch.fpr()); … … 2924 2924 2925 2925 DFG_TYPE_CHECK( 2926 JSValueRegs(), node->child2(), Spec FullRealNumber,2926 JSValueRegs(), node->child2(), SpecRealNumber, 2927 2927 m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, valueFPR, valueFPR)); 2928 2928 … … 3188 3188 op1.use(); 3189 3189 3190 if (!(m_state.forNode(node->child1()).m_type & ~(Spec FullNumber | SpecBoolean))) {3190 if (!(m_state.forNode(node->child1()).m_type & ~(SpecNumber | SpecBoolean))) { 3191 3191 m_jit.move(op1TagGPR, resultTagGPR); 3192 3192 m_jit.move(op1PayloadGPR, resultPayloadGPR); … … 3290 3290 FPRReg opFPR = operand.fpr(); 3291 3291 DFG_TYPE_CHECK( 3292 JSValueRegs(), use, Spec FullRealNumber,3292 JSValueRegs(), use, SpecRealNumber, 3293 3293 m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR)); 3294 3294 … … 3355 3355 FPRReg opFPR = operand.fpr(); 3356 3356 DFG_TYPE_CHECK( 3357 JSValueRegs(), use, Spec FullRealNumber,3357 JSValueRegs(), use, SpecRealNumber, 3358 3358 m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR)); 3359 3359 … … 4798 4798 case CheckTierUpAtReturn: 4799 4799 case CheckTierUpAndOSREnter: 4800 case Int52ToDouble:4801 case Int52ToValue:4802 4800 RELEASE_ASSERT_NOT_REACHED(); 4803 4801 break; -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r156019 r156029 41 41 #if USE(JSVALUE64) 42 42 43 void SpeculativeJIT::boxInt52(GPRReg sourceGPR, GPRReg targetGPR, DataFormat format)44 {45 GPRReg tempGPR;46 if (sourceGPR == targetGPR)47 tempGPR = allocate();48 else49 tempGPR = targetGPR;50 51 FPRReg fpr = fprAllocate();52 53 if (format == DataFormatInt52)54 m_jit.rshift64(TrustedImm32(JSValue::int52ShiftAmount), sourceGPR);55 else56 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 66 43 GPRReg SpeculativeJIT::fillJSValue(Edge edge) 67 44 { … … 93 70 DataFormat spillFormat = info.spillFormat(); 94 71 m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled); 95 switch (spillFormat) { 96 case DataFormatInt32: { 72 if (spillFormat == DataFormatInt32) { 97 73 m_jit.load32(JITCompiler::addressFor(virtualRegister), gpr); 98 74 m_jit.or64(GPRInfo::tagTypeNumberRegister, gpr); 99 75 spillFormat = DataFormatJSInt32; 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: 76 } else { 111 77 m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr); 112 78 if (spillFormat == DataFormatDouble) { … … 116 82 } else 117 83 RELEASE_ASSERT(spillFormat & DataFormatJS); 118 break;119 84 } 120 85 info.fillJSValue(*m_stream, gpr, spillFormat); … … 148 113 149 114 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;160 115 } 161 116 … … 814 769 DataFormat spillFormat = info.spillFormat(); 815 770 816 RELEASE_ASSERT((spillFormat & DataFormatJS) || spillFormat == DataFormatInt32 || spillFormat == DataFormatInt52 || spillFormat == DataFormatStrictInt52);771 RELEASE_ASSERT((spillFormat & DataFormatJS) || spillFormat == DataFormatInt32); 817 772 818 773 m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled); … … 835 790 return gpr; 836 791 } 837 if (spillFormat == DataFormatInt52 || spillFormat == DataFormatStrictInt52) {838 // Generally, this can only happen if we've already proved that the839 // value is an int32. That's because if a value originated as a JSValue840 // then we would speculate that it's an int32 before representing it as841 // an int52. Otherwise, if we knowingly produced an int52, then we would842 // be boxing it into a value using Int52ToValue. This assertion is valid843 // only because Int52 is something that we introduce at prediction time.844 // However: we may have an int32-producing node replaced by an845 // 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 }867 792 m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr); 868 793 … … 873 798 874 799 case DataFormatJS: { 875 RELEASE_ASSERT(!(type & SpecInt52));876 800 // Check the value is an integer. 877 801 GPRReg gpr = info.gpr(); … … 920 844 return gpr; 921 845 } 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 }951 846 952 847 case DataFormatDouble: … … 991 886 } 992 887 993 GPRReg 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 Int521063 // at this point but this is too costly. We only *prove* that this is an Int521064 // 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 } else1114 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 } else1131 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 1167 888 FPRReg SpeculativeJIT::fillSpeculateDouble(Edge edge) 1168 889 { … … 1172 893 AbstractValue& value = m_state.forNode(edge); 1173 894 SpeculatedType type = value.m_type; 1174 ASSERT(edge.useKind() != KnownNumberUse || !(value.m_type & ~Spec FullNumber));1175 m_interpreter.filter(value, Spec FullNumber);895 ASSERT(edge.useKind() != KnownNumberUse || !(value.m_type & ~SpecNumber)); 896 m_interpreter.filter(value, SpecNumber); 1176 897 VirtualRegister virtualRegister = edge->virtualRegister(); 1177 898 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister); … … 1225 946 break; 1226 947 } 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 }1245 948 1246 949 default: … … 1276 979 JITCompiler::Jump isInteger = m_jit.branch64(MacroAssembler::AboveOrEqual, jsValueGpr, GPRInfo::tagTypeNumberRegister); 1277 980 1278 if (type & ~Spec FullNumber)981 if (type & ~SpecNumber) 1279 982 speculationCheck(BadType, JSValueRegs(jsValueGpr), edge, m_jit.branchTest64(MacroAssembler::Zero, jsValueGpr, GPRInfo::tagTypeNumberRegister)); 1280 983 … … 1304 1007 m_gprs.lock(gpr); 1305 1008 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);1328 1009 m_gprs.unlock(gpr); 1329 1010 return fpr; … … 1431 1112 case DataFormatDouble: 1432 1113 case DataFormatJSBoolean: 1433 case DataFormatBoolean: 1434 case DataFormatInt52: 1435 case DataFormatStrictInt52: { 1114 case DataFormatBoolean: { 1436 1115 terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0); 1437 1116 return allocate(); … … 1516 1195 case DataFormatDouble: 1517 1196 case DataFormatJSCell: 1518 case DataFormatCell: 1519 case DataFormatInt52: 1520 case DataFormatStrictInt52: { 1197 case DataFormatCell: { 1521 1198 terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0); 1522 1199 return allocate(); … … 1825 1502 m_jit.or32(TrustedImm32(ValueFalse), result.gpr()); 1826 1503 jsValueResult(result.gpr(), m_currentNode, DataFormatJSBoolean); 1827 }1828 1829 void 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 1842 void 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);1861 1504 } 1862 1505 … … 2264 1907 } 2265 1908 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 2276 1909 default: 2277 1910 GPRTemporary result(this); … … 2349 1982 } 2350 1983 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 2359 1984 case FlushedCell: { 2360 1985 SpeculateCellOperand cell(this, node->child1()); … … 2477 2102 case Int32ToDouble: { 2478 2103 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);2495 2104 break; 2496 2105 } … … 3281 2890 3282 2891 DFG_TYPE_CHECK( 3283 JSValueRegs(), node->child2(), Spec FullRealNumber,2892 JSValueRegs(), node->child2(), SpecRealNumber, 3284 2893 m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, valueFPR, valueFPR)); 3285 2894 … … 3497 3106 op1.use(); 3498 3107 3499 if (!(m_state.forNode(node->child1()).m_type & ~(Spec FullNumber | SpecBoolean)))3108 if (!(m_state.forNode(node->child1()).m_type & ~(SpecNumber | SpecBoolean))) 3500 3109 m_jit.move(op1GPR, resultGPR); 3501 3110 else { … … 3594 3203 FPRReg opFPR = operand.fpr(); 3595 3204 DFG_TYPE_CHECK( 3596 JSValueRegs(), use, Spec FullRealNumber,3205 JSValueRegs(), use, SpecRealNumber, 3597 3206 m_jit.branchDouble( 3598 3207 MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR)); … … 3659 3268 GPRReg scratchGPR = scratch.gpr(); 3660 3269 DFG_TYPE_CHECK( 3661 JSValueRegs(), use, Spec FullRealNumber,3270 JSValueRegs(), use, SpecRealNumber, 3662 3271 m_jit.branchDouble( 3663 3272 MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR)); -
trunk/Source/JavaScriptCore/dfg/DFGUseKind.cpp
r156019 r156029 44 44 case KnownInt32Use: 45 45 out.print("KnownInt32"); 46 break;47 case MachineIntUse:48 out.print("MachineInt");49 46 break; 50 47 case RealNumberUse: -
trunk/Source/JavaScriptCore/dfg/DFGUseKind.h
r156019 r156029 40 40 Int32Use, 41 41 KnownInt32Use, 42 MachineIntUse,43 42 RealNumberUse, 44 43 NumberUse, … … 68 67 case KnownInt32Use: 69 68 return SpecInt32; 70 case MachineIntUse:71 return SpecMachineInt;72 69 case RealNumberUse: 73 return Spec FullRealNumber;70 return SpecRealNumber; 74 71 case NumberUse: 75 72 case KnownNumberUse: 76 return Spec FullNumber;73 return SpecNumber; 77 74 case BooleanUse: 78 75 return SpecBoolean; … … 129 126 case Int32Use: 130 127 case KnownInt32Use: 131 case MachineIntUse:132 128 case RealNumberUse: 133 129 case NumberUse: -
trunk/Source/JavaScriptCore/dfg/DFGValueSource.cpp
r156019 r156029 46 46 out.print("Int32"); 47 47 break; 48 case Int52InJSStack:49 out.print("Int52");50 break;51 48 case CellInJSStack: 52 49 out.print("Cell"); -
trunk/Source/JavaScriptCore/dfg/DFGValueSource.h
r156019 r156029 44 44 ValueInJSStack, 45 45 Int32InJSStack, 46 Int52InJSStack,47 46 CellInJSStack, 48 47 BooleanInJSStack, … … 58 57 case DataFormatInt32: 59 58 return Int32InJSStack; 60 case DataFormatInt52:61 return Int52InJSStack;62 59 case DataFormatDouble: 63 60 return DoubleInJSStack; … … 83 80 case Int32InJSStack: 84 81 return DataFormatInt32; 85 case Int52InJSStack:86 return DataFormatInt52;87 82 case CellInJSStack: 88 83 return DataFormatCell; … … 145 140 case FlushedInt32: 146 141 return ValueSource(Int32InJSStack); 147 case FlushedInt52:148 return ValueSource(Int52InJSStack);149 142 case FlushedCell: 150 143 return ValueSource(CellInJSStack); … … 189 182 return ValueRecovery::alreadyInJSStackAsUnboxedInt32(); 190 183 191 case Int52InJSStack:192 return ValueRecovery::alreadyInJSStackAsUnboxedInt52();193 194 184 case CellInJSStack: 195 185 return ValueRecovery::alreadyInJSStackAsUnboxedCell(); -
trunk/Source/JavaScriptCore/dfg/DFGVariableAccessData.h
r156019 r156029 236 236 // If the variable is not a number prediction, then this doesn't 237 237 // make any sense. 238 if (!is FullNumberSpeculation(prediction())) {238 if (!isNumberSpeculation(prediction())) { 239 239 // FIXME: we may end up forcing a local in inlined argument position to be a double even 240 240 // if it is sometimes not even numeric, since this never signals the fact that it doesn't … … 333 333 if (isInt32Speculation(prediction)) 334 334 return FlushedInt32; 335 336 if (enableInt52() && !operandIsArgument(m_local) && isMachineIntSpeculation(prediction))337 return FlushedInt52;338 335 339 336 if (isCellSpeculation(prediction)) -
trunk/Source/JavaScriptCore/ftl/FTLCArgumentGetter.cpp
r156019 r156029 33 33 using namespace DFG; 34 34 35 void CArgumentGetter::loadNextAndBox( 36 ValueFormat format, GPRReg destination, GPRReg scratch1, GPRReg scratch2) 35 void CArgumentGetter::loadNextAndBox(ValueFormat format, GPRReg destination, GPRReg scratch) 37 36 { 38 if (scratch1 == InvalidGPRReg) { 39 ASSERT(scratch2 == InvalidGPRReg); 37 if (scratch == InvalidGPRReg) { 40 38 if (destination == GPRInfo::nonArgGPR0) 41 scratch 1= GPRInfo::nonArgGPR1;39 scratch = GPRInfo::nonArgGPR1; 42 40 else 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; 41 scratch = GPRInfo::nonArgGPR0; 52 42 } 53 43 … … 61 51 case ValueFormatUInt32: { 62 52 loadNext32(destination); 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 } 53 MacroAssembler::Jump isInt = m_jit.branch32( 54 MacroAssembler::GreaterThanOrEqual, 55 destination, MacroAssembler::TrustedImm32(0)); 77 56 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); 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); 83 68 break; 84 69 } … … 96 81 97 82 case ValueFormatDouble: { 98 m_jit.moveDoubleTo64(FPRInfo::fpRegT0, scratch 1);83 m_jit.moveDoubleTo64(FPRInfo::fpRegT0, scratch); 99 84 loadNextDouble(FPRInfo::fpRegT0); 100 85 m_jit.boxDouble(FPRInfo::fpRegT0, destination); 101 m_jit.move64ToDouble(scratch 1, FPRInfo::fpRegT0);86 m_jit.move64ToDouble(scratch, FPRInfo::fpRegT0); 102 87 break; 103 88 } -
trunk/Source/JavaScriptCore/ftl/FTLCArgumentGetter.h
r156019 r156029 116 116 117 117 void loadNextAndBox( 118 ValueFormat, DFG::GPRReg destination, 119 DFG::GPRReg scratch1 = InvalidGPRReg, DFG::GPRReg scratch2 = InvalidGPRReg); 118 ValueFormat format, DFG::GPRReg destination, DFG::GPRReg scratch = InvalidGPRReg); 120 119 121 120 private: -
trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
r156019 r156029 165 165 if (node->isBinaryUseKind(Int32Use)) 166 166 break; 167 if (node->isBinaryUseKind(MachineIntUse))168 break;169 167 if (node->isBinaryUseKind(NumberUse)) 170 168 break; … … 177 175 case CompareGreaterEq: 178 176 if (node->isBinaryUseKind(Int32Use)) 179 break;180 if (node->isBinaryUseKind(MachineIntUse))181 177 break; 182 178 if (node->isBinaryUseKind(NumberUse)) … … 241 237 case Int32Use: 242 238 case KnownInt32Use: 243 case MachineIntUse:244 239 case NumberUse: 245 240 case KnownNumberUse: -
trunk/Source/JavaScriptCore/ftl/FTLExitValue.cpp
r156019 r156029 54 54 out.print("InJSStackAsInt32"); 55 55 return; 56 case ExitValueInJSStackAsInt52:57 out.print("InJSStackAsInt52");58 return;59 56 case ExitValueInJSStackAsDouble: 60 57 out.print("InJSStackAsDouble"); -
trunk/Source/JavaScriptCore/ftl/FTLExitValue.h
r156019 r156029 50 50 ExitValueInJSStack, 51 51 ExitValueInJSStackAsInt32, 52 ExitValueInJSStackAsInt52,53 52 ExitValueInJSStackAsDouble 54 53 }; … … 81 80 ExitValue result; 82 81 result.m_kind = ExitValueInJSStackAsInt32; 83 return result;84 }85 86 static ExitValue inJSStackAsInt52()87 {88 ExitValue result;89 result.m_kind = ExitValueInJSStackAsInt52;90 82 return result; 91 83 } -
trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h
r156019 r156029 39 39 #define FOR_EACH_FTL_INTRINSIC(macro) \ 40 40 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)) \42 41 macro(doubleAbs, "llvm.fabs.f64", functionType(doubleType, doubleType)) \ 43 42 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)) \45 43 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)) \47 44 macro(trap, "llvm.trap", functionType(voidType)) \ 48 45 macro(osrExit, "webkit_osr_exit", functionType(voidType, boolean, int32, Variadic)) -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
r156019 r156029 152 152 type = m_out.int32; 153 153 break; 154 case NodeResultInt52:155 type = m_out.int64;156 break;157 154 case NodeResultBoolean: 158 155 type = m_out.boolean; … … 243 240 break; 244 241 case JSConstant: 242 compileJSConstant(); 245 243 break; 246 244 case WeakJSConstant: … … 464 462 m_out.set(lowInt32(m_node->child1()), destination); 465 463 break; 466 case MachineIntUse:467 m_out.set(lowInt52(m_node->child1()), destination);468 break;469 464 case BooleanUse: 470 465 m_out.set(lowBoolean(m_node->child1()), destination); … … 492 487 case NodeResultInt32: 493 488 setInt32(m_out.get(source)); 494 break;495 case NodeResultInt52:496 setInt52(m_out.get(source));497 489 break; 498 490 case NodeResultBoolean: … … 600 592 } 601 593 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 609 594 case FlushedCell: { 610 595 LValue value = lowCell(m_node->child1()); … … 671 656 } 672 657 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 691 658 case NumberUse: { 692 659 setDouble( … … 716 683 speculate(Overflow, noValue(), 0, m_out.extractValue(result, 1)); 717 684 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));736 685 break; 737 686 } … … 779 728 780 729 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);807 730 break; 808 731 } … … 1107 1030 1108 1031 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);1129 1032 break; 1130 1033 } … … 1571 1474 1572 1475 FTL_TYPE_CHECK( 1573 doubleValue(value), child3, Spec FullRealNumber,1476 doubleValue(value), child3, SpecRealNumber, 1574 1477 m_out.doubleNotEqualOrUnordered(value, value)); 1575 1478 … … 1806 1709 { 1807 1710 if (m_node->isBinaryUseKind(Int32Use) 1808 || m_node->isBinaryUseKind(MachineIntUse)1809 1711 || m_node->isBinaryUseKind(NumberUse) 1810 1712 || m_node->isBinaryUseKind(ObjectUse)) { … … 1830 1732 setBoolean( 1831 1733 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));1840 1734 return; 1841 1735 } … … 1889 1783 } 1890 1784 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 1899 1785 if (m_node->isBinaryUseKind(NumberUse)) { 1900 1786 setBoolean( … … 1911 1797 setBoolean( 1912 1798 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));1921 1799 return; 1922 1800 } … … 1940 1818 } 1941 1819 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 1950 1820 if (m_node->isBinaryUseKind(NumberUse)) { 1951 1821 setBoolean( … … 1964 1834 m_out.greaterThanOrEqual( 1965 1835 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));1974 1836 return; 1975 1837 } … … 2491 2353 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || (edge.useKind() == Int32Use || edge.useKind() == KnownInt32Use)); 2492 2354 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 2502 2355 LoweredNodeValue value = m_int32Values.get(edge.node()); 2503 2356 if (isValid(value)) 2504 2357 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()));2513 2358 2514 2359 value = m_jsValueValues.get(edge.node()); … … 2527 2372 } 2528 2373 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 2632 2374 LValue lowCell(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation) 2633 2375 { 2634 2376 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 }2644 2377 2645 2378 LoweredNodeValue value = m_jsValueValues.get(edge.node()); … … 2686 2419 { 2687 2420 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 }2697 2421 2698 2422 LoweredNodeValue value = m_booleanValues.get(edge.node()); … … 2719 2443 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || isDouble(edge.useKind())); 2720 2444 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 2730 2445 LoweredNodeValue value = m_doubleValues.get(edge.node()); 2731 2446 if (isValid(value)) … … 2739 2454 } 2740 2455 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 2749 2456 value = m_jsValueValues.get(edge.node()); 2750 2457 if (isValid(value)) { … … 2766 2473 2767 2474 FTL_TYPE_CHECK( 2768 jsValueValue(boxedResult), edge, Spec FullNumber, isCellOrMisc(boxedResult));2475 jsValueValue(boxedResult), edge, SpecNumber, isCellOrMisc(boxedResult)); 2769 2476 2770 2477 ValueFromBlock unboxedDouble = m_out.anchor(unboxDouble(boxedResult)); … … 2779 2486 } 2780 2487 2781 RELEASE_ASSERT(!(m_state.forNode(edge).m_type & Spec FullNumber));2488 RELEASE_ASSERT(!(m_state.forNode(edge).m_type & SpecNumber)); 2782 2489 terminate(Uncountable); 2783 2490 return m_out.doubleZero; … … 2787 2494 { 2788 2495 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())));2792 2496 2793 2497 LoweredNodeValue value = m_jsValueValues.get(edge.node()); … … 2802 2506 } 2803 2507 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 2812 2508 value = m_booleanValues.get(edge.node()); 2813 2509 if (isValid(value)) { … … 2837 2533 setStorage(edge.node(), result); 2838 2534 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));2910 2535 } 2911 2536 … … 3170 2795 LValue value = lowDouble(edge); 3171 2796 FTL_TYPE_CHECK( 3172 doubleValue(value), edge, Spec FullRealNumber,2797 doubleValue(value), edge, SpecRealNumber, 3173 2798 m_out.doubleNotEqualOrUnordered(value, value)); 3174 2799 } … … 3178 2803 lowBoolean(edge); 3179 2804 } 3180 2805 3181 2806 bool masqueradesAsUndefinedWatchpointIsStillValid() 3182 2807 { … … 3309 2934 break; 3310 2935 3311 case FlushedInt52:3312 m_valueSources[i] = ValueSource(Int52InJSStack);3313 break;3314 3315 2936 case FlushedDouble: 3316 2937 m_valueSources[i] = ValueSource(DoubleInJSStack); … … 3415 3036 case Int32InJSStack: 3416 3037 exit.m_values[i] = ExitValue::inJSStackAsInt32(); 3417 break;3418 case Int52InJSStack:3419 exit.m_values[i] = ExitValue::inJSStackAsInt52();3420 3038 break; 3421 3039 case DoubleInJSStack: … … 3522 3140 } 3523 3141 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 3536 3142 value = m_booleanValues.get(node); 3537 3143 if (isValid(value)) { … … 3637 3243 m_int32Values.set(node, LoweredNodeValue(value, m_highBlock)); 3638 3244 } 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 }3661 3245 void setJSValue(Node* node, LValue value) 3662 3246 { … … 3679 3263 { 3680 3264 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);3693 3265 } 3694 3266 void setJSValue(LValue value) … … 3771 3343 3772 3344 HashMap<Node*, LoweredNodeValue> m_int32Values; 3773 HashMap<Node*, LoweredNodeValue> m_strictInt52Values;3774 HashMap<Node*, LoweredNodeValue> m_int52Values;3775 3345 HashMap<Node*, LoweredNodeValue> m_jsValueValues; 3776 3346 HashMap<Node*, LoweredNodeValue> m_booleanValues; -
trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp
r156019 r156029 105 105 } 106 106 107 // All temp registers are free at this point.108 109 107 // Box anything that is already on the stack, or that is a constant. 110 108 … … 129 127 GPRInfo::regT0); 130 128 jit.or64(GPRInfo::tagTypeNumberRegister, GPRInfo::regT0); 131 jit.store64(GPRInfo::regT0, address);132 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 129 jit.store64(GPRInfo::regT0, address); 139 130 break; … … 170 161 shouldShowDisassembly(), 171 162 patchBuffer, 172 ("FTL OSR exit #%u (bc#%u, %s) from %s , with operands = %s",163 ("FTL OSR exit #%u (bc#%u, %s) from %s", 173 164 exitID, exit.m_codeOrigin.bytecodeIndex, 174 exitKindToString(exit.m_kind), toCString(*codeBlock).data(), 175 toCString(ignoringContext<DumpContext>(exit.m_values)).data())); 165 exitKindToString(exit.m_kind), toCString(*codeBlock).data())); 176 166 } 177 167 -
trunk/Source/JavaScriptCore/ftl/FTLOutput.h
r156019 r156029 167 167 return call(mulWithOverflow32Intrinsic(), left, right); 168 168 } 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 }181 169 LValue doubleAbs(LValue value) 182 170 { -
trunk/Source/JavaScriptCore/ftl/FTLValueFormat.cpp
r156019 r156029 45 45 out.print("UInt32"); 46 46 return; 47 case ValueFormatInt52:48 out.print("Int52");49 return;50 case ValueFormatStrictInt52:51 out.print("StrictInt52");52 return;53 47 case ValueFormatBoolean: 54 48 out.print("Boolean"); -
trunk/Source/JavaScriptCore/ftl/FTLValueFormat.h
r156019 r156029 42 42 ValueFormatInt32, 43 43 ValueFormatUInt32, 44 ValueFormatInt52,45 ValueFormatStrictInt52,46 44 ValueFormatBoolean, 47 45 ValueFormatJSValue, -
trunk/Source/JavaScriptCore/ftl/FTLValueSource.cpp
r156019 r156029 43 43 out.print("Int32InJSStack"); 44 44 return; 45 case Int52InJSStack:46 out.print("Int52InJSStack");47 return;48 45 case DoubleInJSStack: 49 46 out.print("DoubleInJSStack"); -
trunk/Source/JavaScriptCore/ftl/FTLValueSource.h
r156019 r156029 41 41 ValueInJSStack, 42 42 Int32InJSStack, 43 Int52InJSStack,44 43 DoubleInJSStack, 45 44 SourceIsDead, -
trunk/Source/JavaScriptCore/interpreter/Register.h
r156019 r156029 74 74 InlineCallFrame* asInlineCallFrame() const; 75 75 int32_t unboxedInt32() const; 76 int64_t unboxedInt52() const;77 76 bool unboxedBoolean() const; 78 77 double unboxedDouble() const; … … 100 99 EncodedValueDescriptor encodedValue; 101 100 double number; 102 int64_t integer;103 101 } u; 104 102 }; … … 186 184 { 187 185 return payload(); 188 }189 190 ALWAYS_INLINE int64_t Register::unboxedInt52() const191 {192 return u.integer >> JSValue::int52ShiftAmount;193 186 } 194 187 -
trunk/Source/JavaScriptCore/runtime/Arguments.cpp
r156019 r156029 384 384 value = jsNumber(location->unboxedInt32()); 385 385 break; 386 case AlreadyInJSStackAsUnboxedInt52:387 value = jsNumber(location->unboxedInt52());388 break;389 386 case AlreadyInJSStackAsUnboxedCell: 390 387 value = location->unboxedCell(); -
trunk/Source/JavaScriptCore/runtime/IndexingType.cpp
r156019 r156029 51 51 if (isInt32Speculation(type)) 52 52 return (indexingType & ~IndexingShapeMask) | Int32Shape; 53 if (is FullNumberSpeculation(type))53 if (isNumberSpeculation(type)) 54 54 return (indexingType & ~IndexingShapeMask) | DoubleShape; 55 55 return (indexingType & ~IndexingShapeMask) | ContiguousShape; 56 56 case ALL_DOUBLE_INDEXING_TYPES: 57 if (is FullNumberSpeculation(type))57 if (isNumberSpeculation(type)) 58 58 return indexingType; 59 59 return (indexingType & ~IndexingShapeMask) | ContiguousShape; -
trunk/Source/JavaScriptCore/runtime/JSCJSValue.h
r156020 r156029 192 192 int32_t asInt32() const; 193 193 uint32_t asUInt32() const; 194 int64_t asMachineInt() const;195 194 double asDouble() const; 196 195 bool asBoolean() const; … … 204 203 bool isUndefinedOrNull() const; 205 204 bool isBoolean() const; 206 bool isMachineInt() const;207 205 bool isNumber() const; 208 206 bool isString() const; … … 276 274 277 275 JS_EXPORT_PRIVATE JSObject* synthesizePrototype(ExecState*) const; 278 279 // Constants used for Int52. Int52 isn't part of JSValue right now, but JSValues may be280 // converted to Int52s and back again.281 static const unsigned numberOfInt52Bits = 52;282 static const unsigned int52ShiftAmount = 12;283 276 284 277 private: -
trunk/Source/JavaScriptCore/runtime/JSCJSValueInlines.h
r156019 r156029 495 495 #endif // USE(JSVALUE64) 496 496 497 inline bool JSValue::isMachineInt() const498 {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 518 inline int64_t JSValue::asMachineInt() const519 {520 ASSERT(isMachineInt());521 if (isInt32())522 return asInt32();523 return static_cast<int64_t>(asDouble());524 }525 526 497 inline bool JSValue::isString() const 527 498 { -
trunk/Source/WTF/ChangeLog
r156019 r156029 1 2013-09-18 Commit Queue <commit-queue@webkit.org> 2 3 Unreviewed, rolling out r156019 and r156020. 4 http://trac.webkit.org/changeset/156019 5 http://trac.webkit.org/changeset/156020 6 https://bugs.webkit.org/show_bug.cgi?id=121540 7 8 Broke tests (Requested by ap on #webkit). 9 10 * wtf/PrintStream.h: 11 1 12 2013-09-16 Filip Pizlo <fpizlo@apple.com> 2 13 -
trunk/Source/WTF/wtf/PrintStream.h
r156019 r156029 361 361 } 362 362 363 template<typename T, typename U>364 class ValueIgnoringContext {365 public:366 ValueIgnoringContext(const U& value)367 : m_value(&value)368 {369 }370 371 void dump(PrintStream& out) const372 {373 T context;374 m_value->dumpInContext(out, &context);375 }376 377 private:378 const U* m_value;379 };380 381 template<typename T, typename U>382 ValueIgnoringContext<T, U> ignoringContext(const U& value)383 {384 return ValueIgnoringContext<T, U>(value);385 }386 387 363 } // namespace WTF 388 364 … … 390 366 using WTF::PointerDump; 391 367 using WTF::PrintStream; 392 using WTF::ignoringContext;393 368 using WTF::inContext; 394 369 using WTF::pointerDump; -
trunk/Tools/ChangeLog
r156026 r156029 1 2013-09-18 Commit Queue <commit-queue@webkit.org> 2 3 Unreviewed, rolling out r156019 and r156020. 4 http://trac.webkit.org/changeset/156019 5 http://trac.webkit.org/changeset/156020 6 https://bugs.webkit.org/show_bug.cgi?id=121540 7 8 Broke tests (Requested by ap on #webkit). 9 10 * Scripts/run-jsc-stress-tests: 11 1 12 2013-09-17 Gwang Yoon Hwang <ryumiel@company100.net> 2 13 -
trunk/Tools/Scripts/run-jsc-stress-tests
r156019 r156029 215 215 runAlwaysTriggerCopyPhase 216 216 runNoCJIT 217 runDFGEager218 217 if $enableFTL 219 218 runDefaultFTL 220 219 runFTLNoCJIT 221 220 runFTLEager 221 else 222 runDFGEager 222 223 end 223 224 end
Note: See TracChangeset
for help on using the changeset viewer.