Changeset 198981 in webkit
- Timestamp:
- Apr 3, 2016 1:37:26 AM (8 years ago)
- Location:
- trunk
- Files:
-
- 9 added
- 37 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r198978 r198981 1 2016-04-03 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 [JSC] Add truncate operation (rounding to zero) 4 https://bugs.webkit.org/show_bug.cgi?id=156072 5 6 Reviewed by Saam Barati. 7 8 * js/regress/many-foreach-calls-expected.txt: Added. 9 * js/regress/many-foreach-calls.html: Added. 10 * js/regress/math-trunc-expected.txt: Added. 11 * js/regress/math-trunc.html: Added. 12 * js/regress/script-tests/many-foreach-calls.js: Added. 13 forEach calls @toInteger. It includes @trunc now. 14 (i.array.forEach): 15 * js/regress/script-tests/math-trunc.js: Added. 16 Call Math.trunc repeatedly. 17 (mathTruncInt): 18 (mathTruncDouble): 19 (mathTruncMixed): 20 (mathTruncDoubleDoesNotCareNegativeZero): 21 1 22 2016-04-02 Skachkov Oleksandr <gskachkov@gmail.com> 2 23 -
trunk/Source/JavaScriptCore/ChangeLog
r198980 r198981 1 2016-04-03 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 [JSC] Add truncate operation (rounding to zero) 4 https://bugs.webkit.org/show_bug.cgi?id=156072 5 6 Reviewed by Saam Barati. 7 8 Add TruncIntrinsic for Math.trunc. DFG handles it as ArithTrunc. 9 In DFG, ArithTrunc behaves similar to ArithRound, ArithCeil, and ArithFloor. 10 ArithTrunc rounds the value towards zero. 11 12 And we rewrite @toInteger to use @trunc instead of @abs, @floor, negation and branch. 13 This is completely the same to what we do in JSValue::toInteger. 14 15 Since DFG recognize it, DFG can convert ArithTrunc to Identity if the given argument is Int32. 16 This is useful because almost all the argument is Int32 in @toLength -> @toInteger -> @trunc case. 17 In such cases, we can eliminate trunc() call. 18 19 As a bonus, to speed up Math.trunc operation, we use x86 SSE round and frintz in ARM64 for ArithRound. 20 In DFG, we emit these instructions. In FTL, we use Patchpoint to emit these instructions to avoid adding a new B3 IR. 21 22 * assembler/MacroAssemblerARM64.h: 23 (JSC::MacroAssemblerARM64::roundTowardZeroDouble): 24 (JSC::MacroAssemblerARM64::roundTowardZeroFloat): 25 * assembler/MacroAssemblerARMv7.h: 26 (JSC::MacroAssemblerARMv7::roundTowardZeroDouble): 27 * assembler/MacroAssemblerMIPS.h: 28 (JSC::MacroAssemblerMIPS::roundTowardZeroDouble): 29 * assembler/MacroAssemblerSH4.h: 30 (JSC::MacroAssemblerSH4::roundTowardZeroDouble): 31 * assembler/MacroAssemblerX86Common.h: 32 (JSC::MacroAssemblerX86Common::roundTowardZeroDouble): 33 (JSC::MacroAssemblerX86Common::roundTowardZeroFloat): 34 * builtins/GlobalObject.js: 35 (toInteger): 36 * dfg/DFGAbstractInterpreterInlines.h: 37 (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): 38 * dfg/DFGByteCodeParser.cpp: 39 (JSC::DFG::ByteCodeParser::handleIntrinsicCall): 40 * dfg/DFGClobberize.h: 41 (JSC::DFG::clobberize): 42 * dfg/DFGDoesGC.cpp: 43 (JSC::DFG::doesGC): 44 * dfg/DFGFixupPhase.cpp: 45 (JSC::DFG::FixupPhase::fixupNode): 46 * dfg/DFGGraph.h: 47 (JSC::DFG::Graph::roundShouldSpeculateInt32): 48 * dfg/DFGNode.h: 49 (JSC::DFG::Node::arithNodeFlags): 50 (JSC::DFG::Node::hasHeapPrediction): 51 (JSC::DFG::Node::hasArithRoundingMode): 52 * dfg/DFGNodeType.h: 53 * dfg/DFGPredictionPropagationPhase.cpp: 54 (JSC::DFG::PredictionPropagationPhase::propagate): 55 * dfg/DFGSafeToExecute.h: 56 (JSC::DFG::safeToExecute): 57 * dfg/DFGSpeculativeJIT.cpp: 58 (JSC::DFG::SpeculativeJIT::compileArithRounding): 59 * dfg/DFGSpeculativeJIT.h: 60 * dfg/DFGSpeculativeJIT32_64.cpp: 61 (JSC::DFG::SpeculativeJIT::compile): 62 * dfg/DFGSpeculativeJIT64.cpp: 63 (JSC::DFG::SpeculativeJIT::compile): 64 * ftl/FTLCapabilities.cpp: 65 (JSC::FTL::canCompile): 66 * ftl/FTLLowerDFGToB3.cpp: 67 (JSC::FTL::DFG::LowerDFGToB3::compileNode): 68 (JSC::FTL::DFG::LowerDFGToB3::compileArithTrunc): 69 * ftl/FTLOutput.cpp: 70 (JSC::FTL::Output::doubleTrunc): 71 * ftl/FTLOutput.h: 72 * jit/ThunkGenerators.cpp: 73 (JSC::truncThunkGenerator): 74 * jit/ThunkGenerators.h: 75 * runtime/CommonIdentifiers.h: 76 * runtime/Intrinsic.h: 77 * runtime/JSGlobalObject.cpp: 78 (JSC::JSGlobalObject::init): 79 * runtime/MathObject.cpp: 80 (JSC::MathObject::finishCreation): 81 * runtime/MathObject.h: 82 * runtime/VM.cpp: 83 (JSC::thunkGeneratorForIntrinsic): 84 * tests/stress/math-rounding-infinity.js: 85 (testTrunc): 86 * tests/stress/math-rounding-nan.js: 87 (testTrunc): 88 * tests/stress/math-rounding-negative-zero.js: 89 (testTrunc): 90 * tests/stress/math-trunc-arith-rounding-mode.js: Added. 91 (firstCareAboutZeroSecondDoesNot): 92 (firstDoNotCareAboutZeroSecondDoes): 93 (warmup): 94 (verifyNegativeZeroIsPreserved): 95 * tests/stress/math-trunc-basics.js: Added. 96 (mathTruncOnIntegers): 97 (mathTruncOnDoubles): 98 (mathTruncOnBooleans): 99 (uselessMathTrunc): 100 (mathTruncWithOverflow): 101 (mathTruncConsumedAsDouble): 102 (mathTruncDoesNotCareAboutMinusZero): 103 (mathTruncNoArguments): 104 (mathTruncTooManyArguments): 105 (testMathTruncOnConstants): 106 (mathTruncStructTransition): 107 (Math.trunc): 108 * tests/stress/math-trunc-should-be-truncate.js: Added. 109 (mathTrunc): 110 1 111 2016-04-03 Skachkov Oleksandr <gskachkov@gmail.com> 2 112 -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h
r197895 r198981 1501 1501 } 1502 1502 1503 void roundTowardZeroDouble(FPRegisterID src, FPRegisterID dest) 1504 { 1505 m_assembler.frintz<64>(dest, src); 1506 } 1507 1508 void roundTowardZeroFloat(FPRegisterID src, FPRegisterID dest) 1509 { 1510 m_assembler.frintz<32>(dest, src); 1511 } 1512 1503 1513 // Convert 'src' to an integer, and places the resulting 'dest'. 1504 1514 // If the result is not representable as a 32 bit value, branch. -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
r197687 r198981 1085 1085 } 1086 1086 1087 NO_RETURN_DUE_TO_CRASH void roundTowardZeroDouble(FPRegisterID, FPRegisterID) 1088 { 1089 ASSERT(!supportsFloatingPointRounding()); 1090 CRASH(); 1091 } 1092 1087 1093 void convertInt32ToDouble(RegisterID src, FPRegisterID dest) 1088 1094 { -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
r197380 r198981 655 655 656 656 NO_RETURN_DUE_TO_CRASH void floorDouble(FPRegisterID, FPRegisterID) 657 { 658 ASSERT(!supportsFloatingPointRounding()); 659 CRASH(); 660 } 661 662 NO_RETURN_DUE_TO_CRASH void roundTowardZeroDouble(FPRegisterID, FPRegisterID) 657 663 { 658 664 ASSERT(!supportsFloatingPointRounding()); -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h
r197380 r198981 1588 1588 } 1589 1589 1590 NO_RETURN_DUE_TO_CRASH void roundTowardZeroDouble(FPRegisterID, FPRegisterID) 1591 { 1592 ASSERT(!supportsFloatingPointRounding()); 1593 CRASH(); 1594 } 1595 1590 1596 Jump branchTest8(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1)) 1591 1597 { -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h
r198953 r198981 734 734 { 735 735 m_assembler.roundss_mr(src.offset, src.base, dst, X86Assembler::RoundingType::TowardNegativeInfiniti); 736 } 737 738 void roundTowardZeroDouble(FPRegisterID src, FPRegisterID dst) 739 { 740 m_assembler.roundsd_rr(src, dst, X86Assembler::RoundingType::TowardZero); 741 } 742 743 void roundTowardZeroDouble(Address src, FPRegisterID dst) 744 { 745 m_assembler.roundsd_mr(src.offset, src.base, dst, X86Assembler::RoundingType::TowardZero); 746 } 747 748 void roundTowardZeroFloat(FPRegisterID src, FPRegisterID dst) 749 { 750 m_assembler.roundss_rr(src, dst, X86Assembler::RoundingType::TowardZero); 751 } 752 753 void roundTowardZeroFloat(Address src, FPRegisterID dst) 754 { 755 m_assembler.roundss_mr(src.offset, src.base, dst, X86Assembler::RoundingType::TowardZero); 736 756 } 737 757 -
trunk/Source/JavaScriptCore/builtins/GlobalObject.js
r196276 r198981 35 35 if (numberValue !== numberValue) 36 36 return 0; 37 38 if (numberValue === 0 || !@isFinite(numberValue)) 39 return numberValue; 40 41 return (numberValue > 0 ? 1 : -1) * @floor(@abs(numberValue)); 37 return @trunc(numberValue); 42 38 } 43 39 -
trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
r198902 r198981 851 851 case ArithRound: 852 852 case ArithFloor: 853 case ArithCeil: { 853 case ArithCeil: 854 case ArithTrunc: { 854 855 JSValue operand = forNode(node->child1()).value(); 855 856 if (operand && operand.isNumber()) { … … 859 860 else if (node->op() == ArithFloor) 860 861 roundedValue = floor(operand.asNumber()); 862 else if (node->op() == ArithCeil) 863 roundedValue = ceil(operand.asNumber()); 861 864 else { 862 ASSERT(node->op() == Arith Ceil);863 roundedValue = ceil(operand.asNumber());865 ASSERT(node->op() == ArithTrunc); 866 roundedValue = trunc(operand.asNumber()); 864 867 } 865 868 -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r198844 r198981 2204 2204 case RoundIntrinsic: 2205 2205 case FloorIntrinsic: 2206 case CeilIntrinsic: { 2206 case CeilIntrinsic: 2207 case TruncIntrinsic: { 2207 2208 if (argumentCountIncludingThis == 1) { 2208 2209 insertChecks(); … … 2218 2219 else if (intrinsic == FloorIntrinsic) 2219 2220 op = ArithFloor; 2221 else if (intrinsic == CeilIntrinsic) 2222 op = ArithCeil; 2220 2223 else { 2221 ASSERT(intrinsic == CeilIntrinsic);2222 op = Arith Ceil;2224 ASSERT(intrinsic == TruncIntrinsic); 2225 op = ArithTrunc; 2223 2226 } 2224 2227 Node* roundNode = addToGraph(op, OpInfo(0), OpInfo(prediction), operand); -
trunk/Source/JavaScriptCore/dfg/DFGClobberize.h
r198844 r198981 306 306 case ArithFloor: 307 307 case ArithCeil: 308 case ArithTrunc: 308 309 def(PureValue(node, static_cast<uintptr_t>(node->arithRoundingMode()))); 309 310 return; -
trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
r198844 r198981 91 91 case ArithFloor: 92 92 case ArithCeil: 93 case ArithTrunc: 93 94 case ArithFRound: 94 95 case ArithSin: -
trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
r198844 r198981 366 366 case ArithRound: 367 367 case ArithFloor: 368 case ArithCeil: { 368 case ArithCeil: 369 case ArithTrunc: { 369 370 if (m_graph.unaryArithShouldSpeculateInt32(node, FixupPass)) { 370 371 fixIntOrBooleanEdge(node->child1()); -
trunk/Source/JavaScriptCore/dfg/DFGGraph.h
r198600 r198981 317 317 bool roundShouldSpeculateInt32(Node* arithRound, PredictionPass pass) 318 318 { 319 ASSERT(arithRound->op() == ArithRound || arithRound->op() == ArithFloor || arithRound->op() == ArithCeil );319 ASSERT(arithRound->op() == ArithRound || arithRound->op() == ArithFloor || arithRound->op() == ArithCeil || arithRound->op() == ArithTrunc); 320 320 return arithRound->canSpeculateInt32(pass) && !hasExitSite(arithRound->origin.semantic, Overflow) && !hasExitSite(arithRound->origin.semantic, NegativeZero); 321 321 } -
trunk/Source/JavaScriptCore/dfg/DFGNode.h
r198935 r198981 944 944 { 945 945 NodeFlags result = m_flags & NodeArithFlagsMask; 946 if (op() == ArithMul || op() == ArithDiv || op() == ArithMod || op() == ArithNegate || op() == ArithPow || op() == ArithRound || op() == ArithFloor || op() == ArithCeil || op() == DoubleAsInt32)946 if (op() == ArithMul || op() == ArithDiv || op() == ArithMod || op() == ArithNegate || op() == ArithPow || op() == ArithRound || op() == ArithFloor || op() == ArithCeil || op() == ArithTrunc || op() == DoubleAsInt32) 947 947 return result; 948 948 return result & ~NodeBytecodeNeedsNegZero; … … 1352 1352 case ArithFloor: 1353 1353 case ArithCeil: 1354 case ArithTrunc: 1354 1355 case GetDirectPname: 1355 1356 case GetById: … … 1734 1735 bool hasArithRoundingMode() 1735 1736 { 1736 return op() == ArithRound || op() == ArithFloor || op() == ArithCeil ;1737 return op() == ArithRound || op() == ArithFloor || op() == ArithCeil || op() == ArithTrunc; 1737 1738 } 1738 1739 -
trunk/Source/JavaScriptCore/dfg/DFGNodeType.h
r198844 r198981 159 159 macro(ArithFloor, NodeResultNumber) \ 160 160 macro(ArithCeil, NodeResultNumber) \ 161 macro(ArithTrunc, NodeResultNumber) \ 161 162 macro(ArithSqrt, NodeResultNumber) \ 162 163 macro(ArithSin, NodeResultNumber) \ -
trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
r198844 r198981 390 390 case ArithRound: 391 391 case ArithFloor: 392 case ArithCeil: { 392 case ArithCeil: 393 case ArithTrunc: { 393 394 if (isInt32OrBooleanSpeculation(node->getHeapPrediction()) && m_graph.roundShouldSpeculateInt32(node, m_pass)) 394 395 changed |= setPrediction(SpecInt32); -
trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
r198844 r198981 187 187 case ArithFloor: 188 188 case ArithCeil: 189 case ArithTrunc: 189 190 case ArithSin: 190 191 case ArithCos: -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r198844 r198981 4506 4506 } 4507 4507 4508 case ArithTrunc: { 4509 FPRTemporary rounded(this); 4510 FPRReg resultFPR = rounded.fpr(); 4511 m_jit.roundTowardZeroDouble(valueFPR, resultFPR); 4512 setResult(resultFPR); 4513 return; 4514 } 4515 4508 4516 default: 4509 4517 RELEASE_ASSERT_NOT_REACHED(); … … 4517 4525 else if (node->op() == ArithFloor) 4518 4526 callOperation(floor, resultFPR, valueFPR); 4527 else if (node->op() == ArithCeil) 4528 callOperation(ceil, resultFPR, valueFPR); 4519 4529 else { 4520 ASSERT(node->op() == Arith Ceil);4521 callOperation( ceil, resultFPR, valueFPR);4530 ASSERT(node->op() == ArithTrunc); 4531 callOperation(trunc, resultFPR, valueFPR); 4522 4532 } 4523 4533 m_jit.exceptionCheck(); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r198844 r198981 2374 2374 void compileArithPow(Node*); 2375 2375 void compileArithRounding(Node*); 2376 void compileArithFloor(Node*);2377 void compileArithCeil(Node*);2378 2376 void compileArithRandom(Node*); 2379 2377 void compileArithSqrt(Node*); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r198844 r198981 2307 2307 case ArithFloor: 2308 2308 case ArithCeil: 2309 case ArithTrunc: 2309 2310 compileArithRounding(node); 2310 2311 break; -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r198844 r198981 2445 2445 case ArithFloor: 2446 2446 case ArithCeil: 2447 case ArithTrunc: 2447 2448 compileArithRounding(node); 2448 2449 break; -
trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
r198844 r198981 100 100 case ArithFloor: 101 101 case ArithCeil: 102 case ArithTrunc: 102 103 case ArithSqrt: 103 104 case ArithLog: -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
r198844 r198981 533 533 compileArithCeil(); 534 534 break; 535 case ArithTrunc: 536 compileArithTrunc(); 537 break; 535 538 case ArithSqrt: 536 539 compileArithSqrt(); … … 1975 1978 else 1976 1979 setDouble(integerValue); 1980 } 1981 1982 void compileArithTrunc() 1983 { 1984 LValue value = lowDouble(m_node->child1()); 1985 LValue result = m_out.doubleTrunc(value); 1986 if (producesInteger(m_node->arithRoundingMode())) 1987 setInt32(convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode()))); 1988 else 1989 setDouble(result); 1977 1990 } 1978 1991 -
trunk/Source/JavaScriptCore/ftl/FTLOutput.cpp
r198364 r198981 147 147 } 148 148 149 LValue Output::doubleTrunc(LValue value) 150 { 151 if (MacroAssembler::supportsFloatingPointRounding()) { 152 PatchpointValue* result = patchpoint(Double); 153 result->append(value, ValueRep::SomeRegister); 154 result->setGenerator( 155 [] (CCallHelpers& jit, const StackmapGenerationParams& params) { 156 jit.roundTowardZeroDouble(params[1].fpr(), params[0].fpr()); 157 }); 158 result->effects = Effects::none(); 159 return result; 160 } 161 double (*truncDouble)(double) = trunc; 162 return callWithoutSideEffects(Double, truncDouble, value); 163 } 164 149 165 LValue Output::unsignedToDouble(LValue value) 150 166 { -
trunk/Source/JavaScriptCore/ftl/FTLOutput.h
r198364 r198981 157 157 LValue doubleCeil(LValue operand) { return m_block->appendNew<B3::Value>(m_proc, B3::Ceil, origin(), operand); } 158 158 LValue doubleFloor(LValue operand) { return m_block->appendNew<B3::Value>(m_proc, B3::Floor, origin(), operand); } 159 LValue doubleTrunc(LValue); 159 160 160 161 LValue doubleSin(LValue value) -
trunk/Source/JavaScriptCore/jit/ThunkGenerators.cpp
r198513 r198981 741 741 static double (_cdecl *floorFunction)(double) = floor; 742 742 static double (_cdecl *ceilFunction)(double) = ceil; 743 static double (_cdecl *truncFunction)(double) = trunc; 743 744 static double (_cdecl *expFunction)(double) = exp; 744 745 static double (_cdecl *logFunction)(double) = log; … … 772 773 defineUnaryDoubleOpWrapper(floor); 773 774 defineUnaryDoubleOpWrapper(ceil); 775 defineUnaryDoubleOpWrapper(trunc); 774 776 775 777 static const double oneConstant = 1.0; … … 841 843 jit.returnDouble(SpecializedThunkJIT::fpRegT0); 842 844 return jit.finalize(vm->jitStubs->ctiNativeTailCall(vm), "ceil"); 845 } 846 847 MacroAssemblerCodeRef truncThunkGenerator(VM* vm) 848 { 849 SpecializedThunkJIT jit(vm, 1); 850 if (!UnaryDoubleOpWrapper(trunc) || !jit.supportsFloatingPoint()) 851 return MacroAssemblerCodeRef::createSelfManagedCodeRef(vm->jitStubs->ctiNativeCall(vm)); 852 MacroAssembler::Jump nonIntJump; 853 jit.loadInt32Argument(0, SpecializedThunkJIT::regT0, nonIntJump); 854 jit.returnInt32(SpecializedThunkJIT::regT0); 855 nonIntJump.link(&jit); 856 jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0); 857 if (jit.supportsFloatingPointRounding()) 858 jit.roundTowardZeroDouble(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::fpRegT0); 859 else 860 jit.callDoubleToDoublePreservingReturn(UnaryDoubleOpWrapper(trunc)); 861 862 SpecializedThunkJIT::JumpList doubleResult; 863 jit.branchConvertDoubleToInt32(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0, doubleResult, SpecializedThunkJIT::fpRegT1); 864 jit.returnInt32(SpecializedThunkJIT::regT0); 865 doubleResult.link(&jit); 866 jit.returnDouble(SpecializedThunkJIT::fpRegT0); 867 return jit.finalize(vm->jitStubs->ctiNativeTailCall(vm), "trunc"); 843 868 } 844 869 -
trunk/Source/JavaScriptCore/jit/ThunkGenerators.h
r194087 r198981 64 64 MacroAssemblerCodeRef imulThunkGenerator(VM*); 65 65 MacroAssemblerCodeRef randomThunkGenerator(VM*); 66 MacroAssemblerCodeRef truncThunkGenerator(VM*); 66 67 67 68 } -
trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h
r198844 r198981 316 316 macro(abs) \ 317 317 macro(floor) \ 318 macro(trunc) \ 318 319 macro(isFinite) \ 319 320 macro(isNaN) \ -
trunk/Source/JavaScriptCore/runtime/Intrinsic.h
r198844 r198981 57 57 RandomIntrinsic, 58 58 FRoundIntrinsic, 59 TruncIntrinsic, 59 60 60 61 // Getter intrinsics. -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
r198980 r198981 527 527 JSFunction* privateFuncIsFinite = JSFunction::create(vm, this, 0, String(), globalFuncIsFinite); 528 528 JSFunction* privateFuncIsNaN = JSFunction::create(vm, this, 0, String(), globalFuncIsNaN); 529 JSFunction* privateFuncTrunc = JSFunction::create(vm, this, 0, String(), mathProtoFuncTrunc, TruncIntrinsic); 529 530 530 531 JSFunction* privateFuncGetTemplateObject = JSFunction::create(vm, this, 0, String(), getTemplateObject); … … 564 565 GlobalPropertyInfo(vm.propertyNames->absPrivateName, privateFuncAbs, DontEnum | DontDelete | ReadOnly), 565 566 GlobalPropertyInfo(vm.propertyNames->floorPrivateName, privateFuncFloor, DontEnum | DontDelete | ReadOnly), 567 GlobalPropertyInfo(vm.propertyNames->truncPrivateName, privateFuncTrunc, DontEnum | DontDelete | ReadOnly), 566 568 GlobalPropertyInfo(vm.propertyNames->isFinitePrivateName, privateFuncIsFinite, DontEnum | DontDelete | ReadOnly), 567 569 GlobalPropertyInfo(vm.propertyNames->isNaNPrivateName, privateFuncIsNaN, DontEnum | DontDelete | ReadOnly), -
trunk/Source/JavaScriptCore/runtime/MathObject.cpp
r194087 r198981 68 68 EncodedJSValue JSC_HOST_CALL mathProtoFuncTan(ExecState*); 69 69 EncodedJSValue JSC_HOST_CALL mathProtoFuncTanh(ExecState*); 70 EncodedJSValue JSC_HOST_CALL mathProtoFuncTrunc(ExecState*);71 70 EncodedJSValue JSC_HOST_CALL mathProtoFuncIMul(ExecState*); 72 71 … … 130 129 putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "tan"), 1, mathProtoFuncTan, NoIntrinsic, DontEnum); 131 130 putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "tanh"), 1, mathProtoFuncTanh, NoIntrinsic, DontEnum); 132 putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "trunc"), 1, mathProtoFuncTrunc, NoIntrinsic, DontEnum);131 putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "trunc"), 1, mathProtoFuncTrunc, TruncIntrinsic, DontEnum); 133 132 putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "imul"), 2, mathProtoFuncIMul, IMulIntrinsic, DontEnum); 134 133 } -
trunk/Source/JavaScriptCore/runtime/MathObject.h
r183785 r198981 54 54 EncodedJSValue JSC_HOST_CALL mathProtoFuncAbs(ExecState*); 55 55 EncodedJSValue JSC_HOST_CALL mathProtoFuncFloor(ExecState*); 56 EncodedJSValue JSC_HOST_CALL mathProtoFuncTrunc(ExecState*); 56 57 57 58 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/VM.cpp
r198364 r198981 480 480 case CeilIntrinsic: 481 481 return ceilThunkGenerator; 482 case TruncIntrinsic: 483 return truncThunkGenerator; 482 484 case RoundIntrinsic: 483 485 return roundThunkGenerator; -
trunk/Source/JavaScriptCore/tests/stress/math-rounding-infinity.js
r197380 r198981 22 22 noInline(testCeil); 23 23 24 function testTrunc(value) 25 { 26 return Math.trunc(value); 27 } 28 noInline(testTrunc); 29 24 30 for (var i = 0; i < 1e4; ++i) { 25 31 shouldBe(testRound(Infinity), Infinity); … … 29 35 shouldBe(testCeil(Infinity), Infinity); 30 36 shouldBe(testCeil(-Infinity), -Infinity); 37 shouldBe(testTrunc(Infinity), Infinity); 38 shouldBe(testTrunc(-Infinity), -Infinity); 31 39 } -
trunk/Source/JavaScriptCore/tests/stress/math-rounding-nan.js
r197380 r198981 22 22 noInline(testCeil); 23 23 24 function testTrunc(value) 25 { 26 return Math.trunc(value); 27 } 28 noInline(testTrunc); 29 24 30 for (var i = 0; i < 1e4; ++i) { 25 31 shouldBe(Number.isNaN(testRound(NaN)), true); 26 32 shouldBe(Number.isNaN(testFloor(NaN)), true); 27 33 shouldBe(Number.isNaN(testCeil(NaN)), true); 34 shouldBe(Number.isNaN(testTrunc(NaN)), true); 28 35 } -
trunk/Source/JavaScriptCore/tests/stress/math-rounding-negative-zero.js
r197380 r198981 68 68 } 69 69 70 function testTrunc(value) 71 { 72 return Math.trunc(value); 73 } 74 noInline(testTrunc); 70 75 76 for (var i = 0; i < 1e4; ++i) { 77 shouldBe(1 / testTrunc(0.0), Infinity); 78 shouldBe(1 / testTrunc(-0.0), -Infinity); 79 }
Note: See TracChangeset
for help on using the changeset viewer.