Changeset 194087 in webkit
- Timestamp:
- Dec 14, 2015 7:51:42 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 5 added
- 29 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r194083 r194087 1 2015-12-14 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 Math.random should have an intrinsic thunk and it should be later handled as a DFG Node 4 https://bugs.webkit.org/show_bug.cgi?id=152133 5 6 Reviewed by Geoffrey Garen. 7 8 Add new regression test. 9 10 * js/regress/math-random-expected.txt: Added. 11 * js/regress/math-random.html: Added. 12 * js/regress/script-tests/math-random.js: Added. 13 (test): 14 1 15 2015-12-14 Joseph Pecoraro <pecoraro@apple.com> 2 16 -
trunk/Source/JavaScriptCore/ChangeLog
r194073 r194087 1 2015-12-14 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 Math.random should have an intrinsic thunk and it should be later handled as a DFG Node 4 https://bugs.webkit.org/show_bug.cgi?id=152133 5 6 Reviewed by Geoffrey Garen. 7 8 In this patch, we implement new RandomIntrinsic. It emits a machine code to generate random numbers efficiently. 9 And later it will be recognized by DFG and converted to ArithRandom node. 10 It provides type information SpecDoubleReal since Math.random only generates a number within [0, 1.0). 11 12 Currently, only 64bit version is supported. On 32bit environment, ArithRandom will be converted to callOperation. 13 While it emits a function call, ArithRandom node on 32bit still represents SpecDoubleReal as a result type. 14 15 * dfg/DFGAbstractHeap.h: 16 * dfg/DFGAbstractInterpreterInlines.h: 17 (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): 18 * dfg/DFGByteCodeParser.cpp: 19 (JSC::DFG::ByteCodeParser::handleIntrinsicCall): 20 * dfg/DFGClobberize.h: 21 (JSC::DFG::clobberize): 22 * dfg/DFGDoesGC.cpp: 23 (JSC::DFG::doesGC): 24 * dfg/DFGFixupPhase.cpp: 25 (JSC::DFG::FixupPhase::fixupNode): 26 * dfg/DFGNodeType.h: 27 * dfg/DFGOperations.cpp: 28 * dfg/DFGOperations.h: 29 * dfg/DFGPredictionPropagationPhase.cpp: 30 (JSC::DFG::PredictionPropagationPhase::propagate): 31 * dfg/DFGSafeToExecute.h: 32 (JSC::DFG::safeToExecute): 33 * dfg/DFGSpeculativeJIT.h: 34 (JSC::DFG::SpeculativeJIT::callOperation): 35 * dfg/DFGSpeculativeJIT32_64.cpp: 36 (JSC::DFG::SpeculativeJIT::compile): 37 (JSC::DFG::SpeculativeJIT::compileArithRandom): 38 * dfg/DFGSpeculativeJIT64.cpp: 39 (JSC::DFG::SpeculativeJIT::compile): 40 (JSC::DFG::SpeculativeJIT::compileArithRandom): 41 * ftl/FTLCapabilities.cpp: 42 (JSC::FTL::canCompile): 43 * ftl/FTLLowerDFGToLLVM.cpp: 44 (JSC::FTL::DFG::LowerDFGToLLVM::compileNode): 45 (JSC::FTL::DFG::LowerDFGToLLVM::compileArithRandom): 46 * jit/AssemblyHelpers.cpp: 47 (JSC::emitRandomThunkImpl): 48 (JSC::AssemblyHelpers::emitRandomThunk): 49 * jit/AssemblyHelpers.h: 50 * jit/JITOperations.h: 51 * jit/ThunkGenerators.cpp: 52 (JSC::randomThunkGenerator): 53 * jit/ThunkGenerators.h: 54 * runtime/Intrinsic.h: 55 * runtime/JSGlobalObject.h: 56 (JSC::JSGlobalObject::weakRandomOffset): 57 * runtime/MathObject.cpp: 58 (JSC::MathObject::finishCreation): 59 * runtime/VM.cpp: 60 (JSC::thunkGeneratorForIntrinsic): 61 * tests/stress/random-53bit.js: Added. 62 (test): 63 * tests/stress/random-in-range.js: Added. 64 (test): 65 1 66 2015-12-14 Benjamin Poulain <benjamin@webkit.org> 2 67 -
trunk/Source/JavaScriptCore/dfg/DFGAbstractHeap.h
r188979 r194087 70 70 macro(HeapObjectCount) /* Used to reflect the fact that some allocations reveal object identity */\ 71 71 macro(RegExpState) \ 72 macro(MathDotRandomState) \ 72 73 macro(InternalState) \ 73 74 macro(Absolute) \ -
trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
r194036 r194087 820 820 } 821 821 forNode(node).setType(typeOfDoublePow(forNode(node->child1()).m_type, forNode(node->child2()).m_type)); 822 break; 823 } 824 825 case ArithRandom: { 826 forNode(node).setType(m_graph, SpecDoubleReal); 822 827 break; 823 828 } -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r194036 r194087 2213 2213 Node* right = get(rightOperand); 2214 2214 set(VirtualRegister(resultOperand), addToGraph(ArithIMul, left, right)); 2215 return true; 2216 } 2217 2218 case RandomIntrinsic: { 2219 if (argumentCountIncludingThis != 1) 2220 return false; 2221 insertChecks(); 2222 set(VirtualRegister(resultOperand), addToGraph(ArithRandom)); 2215 2223 return true; 2216 2224 } -
trunk/Source/JavaScriptCore/dfg/DFGClobberize.h
r194036 r194087 164 164 def(PureValue(node)); 165 165 return; 166 167 case ArithRandom: 168 read(MathDotRandomState); 169 write(MathDotRandomState); 170 return; 166 171 167 172 case HasGenericProperty: -
trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
r194036 r194087 86 86 case ArithPow: 87 87 case ArithSqrt: 88 case ArithRandom: 88 89 case ArithRound: 89 90 case ArithFRound: -
trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
r194040 r194087 349 349 fixDoubleOrBooleanEdge(node->child1()); 350 350 fixDoubleOrBooleanEdge(node->child2()); 351 break; 352 } 353 354 case ArithRandom: { 355 node->setResult(NodeResultDouble); 351 356 break; 352 357 } -
trunk/Source/JavaScriptCore/dfg/DFGNodeType.h
r194036 r194087 153 153 macro(ArithFRound, NodeResultNumber) \ 154 154 macro(ArithPow, NodeResultNumber) \ 155 macro(ArithRandom, NodeResultDouble | NodeMustGenerate) \ 155 156 macro(ArithRound, NodeResultNumber) \ 156 157 macro(ArithSqrt, NodeResultNumber) \ -
trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp
r193781 r194087 1229 1229 } 1230 1230 1231 #if USE(JSVALUE32_64) 1232 double JIT_OPERATION operationRandom(JSGlobalObject* globalObject) 1233 { 1234 return globalObject->weakRandomNumber(); 1235 } 1236 #endif 1237 1231 1238 JSCell* JIT_OPERATION operationStringFromCharCode(ExecState* exec, int32_t op1) 1232 1239 { -
trunk/Source/JavaScriptCore/dfg/DFGOperations.h
r193781 r194087 151 151 void JIT_OPERATION triggerReoptimizationNow(CodeBlock*, OSRExitBase*) WTF_INTERNAL; 152 152 153 #if USE(JSVALUE32_64) 154 double JIT_OPERATION operationRandom(JSGlobalObject*); 155 #endif 156 153 157 #if ENABLE(FTL_JIT) 154 158 void JIT_OPERATION triggerTierUpNow(ExecState*) WTF_INTERNAL; -
trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
r194036 r194087 375 375 case ArithLog: { 376 376 changed |= setPrediction(SpecBytecodeDouble); 377 break; 378 } 379 380 case ArithRandom: { 381 changed |= setPrediction(SpecDoubleReal); 377 382 break; 378 383 } -
trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
r194036 r194087 178 178 case ArithMax: 179 179 case ArithPow: 180 case ArithRandom: 180 181 case ArithSqrt: 181 182 case ArithFRound: -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r194036 r194087 1551 1551 #endif 1552 1552 1553 JITCompiler::Call callOperation(D_JITOperation_G operation, FPRReg result, JSGlobalObject* globalObject) 1554 { 1555 m_jit.setupArguments(TrustedImmPtr(globalObject)); 1556 return appendCallSetResult(operation, result); 1557 } 1553 1558 JITCompiler::Call callOperation(Z_JITOperation_D operation, GPRReg result, FPRReg arg1) 1554 1559 { … … 2226 2231 void compileArithPow(Node*); 2227 2232 void compileArithRound(Node*); 2233 void compileArithRandom(Node*); 2228 2234 void compileArithSqrt(Node*); 2229 2235 void compileArithLog(Node*); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r194036 r194087 2287 2287 break; 2288 2288 } 2289 2290 case ArithRandom: 2291 compileArithRandom(node); 2292 break; 2289 2293 2290 2294 case ArithRound: … … 4847 4851 } 4848 4852 4853 void SpeculativeJIT::compileArithRandom(Node* node) 4854 { 4855 JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->origin.semantic); 4856 4857 flushRegisters(); 4858 4859 FPRResult result(this); 4860 callOperation(operationRandom, result.fpr(), globalObject); 4861 // operationRandom does not raise any exception. 4862 doubleResult(result.fpr(), node); 4863 } 4864 4849 4865 #endif 4850 4866 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r194036 r194087 2409 2409 break; 2410 2410 } 2411 2412 case ArithRandom: 2413 compileArithRandom(node); 2414 break; 2411 2415 2412 2416 case ArithRound: … … 4953 4957 } 4954 4958 4959 void SpeculativeJIT::compileArithRandom(Node* node) 4960 { 4961 JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->origin.semantic); 4962 GPRTemporary temp1(this); 4963 GPRTemporary temp2(this); 4964 GPRTemporary temp3(this); 4965 FPRTemporary result(this); 4966 m_jit.emitRandomThunk(globalObject, temp1.gpr(), temp2.gpr(), temp3.gpr(), result.fpr()); 4967 doubleResult(result.fpr(), node); 4968 } 4969 4955 4970 #endif 4956 4971 -
trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
r194036 r194087 95 95 case ArithCos: 96 96 case ArithPow: 97 case ArithRandom: 97 98 case ArithRound: 98 99 case ArithSqrt: -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
r194073 r194087 626 626 compileArithPow(); 627 627 break; 628 case ArithRandom: 629 compileArithRandom(); 630 break; 628 631 case ArithRound: 629 632 compileArithRound(); … … 2118 2121 setDouble(m_out.phi(m_out.doubleType, powDoubleIntResult, powResult, pureNan)); 2119 2122 } 2123 } 2124 2125 void compileArithRandom() 2126 { 2127 JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic); 2128 2129 // Inlined WeakRandom::advance(). 2130 // uint64_t x = m_low; 2131 void* lowAddress = reinterpret_cast<uint8_t*>(globalObject) + JSGlobalObject::weakRandomOffset() + WeakRandom::lowOffset(); 2132 LValue low = m_out.load64(m_out.absolute(lowAddress)); 2133 // uint64_t y = m_high; 2134 void* highAddress = reinterpret_cast<uint8_t*>(globalObject) + JSGlobalObject::weakRandomOffset() + WeakRandom::highOffset(); 2135 LValue high = m_out.load64(m_out.absolute(highAddress)); 2136 // m_low = y; 2137 m_out.store64(high, m_out.absolute(lowAddress)); 2138 2139 // x ^= x << 23; 2140 LValue phase1 = m_out.bitXor(m_out.shl(low, m_out.constInt64(23)), low); 2141 2142 // x ^= x >> 17; 2143 LValue phase2 = m_out.bitXor(m_out.lShr(phase1, m_out.constInt64(17)), phase1); 2144 2145 // x ^= y ^ (y >> 26); 2146 LValue phase3 = m_out.bitXor(m_out.bitXor(high, m_out.lShr(high, m_out.constInt64(26))), phase2); 2147 2148 // m_high = x; 2149 m_out.store64(phase3, m_out.absolute(highAddress)); 2150 2151 // return x + y; 2152 LValue random64 = m_out.add(phase3, high); 2153 2154 // Extract random 53bit. [0, 53] bit is safe integer number ranges in double representation. 2155 LValue random53 = m_out.bitAnd(random64, m_out.constInt64((1ULL << 53) - 1)); 2156 2157 LValue double53Integer = m_out.intToDouble(random53); 2158 2159 // Convert `(53bit double integer value) / (1 << 53)` to `(53bit double integer value) * (1.0 / (1 << 53))`. 2160 // In latter case, `1.0 / (1 << 53)` will become a double value represented as (mantissa = 0 & exp = 970, it means 1e-(2**54)). 2161 static const double scale = 1.0 / (1ULL << 53); 2162 2163 // Multiplying 1e-(2**54) with the double integer does not change anything of the mantissa part of the double integer. 2164 // It just reduces the exp part of the given 53bit double integer. 2165 // (Except for 0.0. This is specially handled and in this case, exp just becomes 0.) 2166 // Now we get 53bit precision random double value in [0, 1). 2167 LValue result = m_out.doubleMul(double53Integer, m_out.constDouble(scale)); 2168 2169 setDouble(result); 2120 2170 } 2121 2171 -
trunk/Source/JavaScriptCore/jit/AssemblyHelpers.cpp
r193424 r194087 421 421 } 422 422 423 #if USE(JSVALUE64) 424 template<typename LoadFromHigh, typename StoreToHigh, typename LoadFromLow, typename StoreToLow> 425 void emitRandomThunkImpl(AssemblyHelpers& jit, GPRReg scratch0, GPRReg scratch1, GPRReg scratch2, FPRReg result, const LoadFromHigh& loadFromHigh, const StoreToHigh& storeToHigh, const LoadFromLow& loadFromLow, const StoreToLow& storeToLow) 426 { 427 // Inlined WeakRandom::advance(). 428 // uint64_t x = m_low; 429 loadFromLow(scratch0); 430 // uint64_t y = m_high; 431 loadFromHigh(scratch1); 432 // m_low = y; 433 storeToLow(scratch1); 434 435 // x ^= x << 23; 436 jit.move(scratch0, scratch2); 437 jit.lshift64(AssemblyHelpers::TrustedImm32(23), scratch2); 438 jit.xor64(scratch2, scratch0); 439 440 // x ^= x >> 17; 441 jit.move(scratch0, scratch2); 442 jit.rshift64(AssemblyHelpers::TrustedImm32(17), scratch2); 443 jit.xor64(scratch2, scratch0); 444 445 // x ^= y ^ (y >> 26); 446 jit.move(scratch1, scratch2); 447 jit.rshift64(AssemblyHelpers::TrustedImm32(26), scratch2); 448 jit.xor64(scratch1, scratch2); 449 jit.xor64(scratch2, scratch0); 450 451 // m_high = x; 452 storeToHigh(scratch0); 453 454 // return x + y; 455 jit.add64(scratch1, scratch0); 456 457 // Extract random 53bit. [0, 53] bit is safe integer number ranges in double representation. 458 jit.move(AssemblyHelpers::TrustedImm64((1ULL << 53) - 1), scratch1); 459 jit.and64(scratch1, scratch0); 460 // Now, scratch0 is always in range of int64_t. Safe to convert it to double with cvtsi2sdq. 461 jit.convertInt64ToDouble(scratch0, result); 462 463 // Convert `(53bit double integer value) / (1 << 53)` to `(53bit double integer value) * (1.0 / (1 << 53))`. 464 // In latter case, `1.0 / (1 << 53)` will become a double value represented as (mantissa = 0 & exp = 970, it means 1e-(2**54)). 465 static const double scale = 1.0 / (1ULL << 53); 466 467 // Multiplying 1e-(2**54) with the double integer does not change anything of the mantissa part of the double integer. 468 // It just reduces the exp part of the given 53bit double integer. 469 // (Except for 0.0. This is specially handled and in this case, exp just becomes 0.) 470 // Now we get 53bit precision random double value in [0, 1). 471 jit.move(AssemblyHelpers::TrustedImmPtr(&scale), scratch1); 472 jit.mulDouble(AssemblyHelpers::Address(scratch1), result); 473 } 474 475 void AssemblyHelpers::emitRandomThunk(JSGlobalObject* globalObject, GPRReg scratch0, GPRReg scratch1, GPRReg scratch2, FPRReg result) 476 { 477 void* lowAddress = reinterpret_cast<uint8_t*>(globalObject) + JSGlobalObject::weakRandomOffset() + WeakRandom::lowOffset(); 478 void* highAddress = reinterpret_cast<uint8_t*>(globalObject) + JSGlobalObject::weakRandomOffset() + WeakRandom::highOffset(); 479 480 auto loadFromHigh = [&](GPRReg high) { 481 load64(highAddress, high); 482 }; 483 auto storeToHigh = [&](GPRReg high) { 484 store64(high, highAddress); 485 }; 486 auto loadFromLow = [&](GPRReg low) { 487 load64(lowAddress, low); 488 }; 489 auto storeToLow = [&](GPRReg low) { 490 store64(low, lowAddress); 491 }; 492 493 emitRandomThunkImpl(*this, scratch0, scratch1, scratch2, result, loadFromHigh, storeToHigh, loadFromLow, storeToLow); 494 } 495 496 void AssemblyHelpers::emitRandomThunk(GPRReg scratch0, GPRReg scratch1, GPRReg scratch2, GPRReg scratch3, FPRReg result) 497 { 498 emitGetFromCallFrameHeaderPtr(JSStack::Callee, scratch3); 499 emitLoadStructure(scratch3, scratch3, scratch0); 500 loadPtr(Address(scratch3, Structure::globalObjectOffset()), scratch3); 501 // Now, scratch3 holds JSGlobalObject*. 502 503 auto loadFromHigh = [&](GPRReg high) { 504 load64(Address(scratch3, JSGlobalObject::weakRandomOffset() + WeakRandom::highOffset()), high); 505 }; 506 auto storeToHigh = [&](GPRReg high) { 507 store64(high, Address(scratch3, JSGlobalObject::weakRandomOffset() + WeakRandom::highOffset())); 508 }; 509 auto loadFromLow = [&](GPRReg low) { 510 load64(Address(scratch3, JSGlobalObject::weakRandomOffset() + WeakRandom::lowOffset()), low); 511 }; 512 auto storeToLow = [&](GPRReg low) { 513 store64(low, Address(scratch3, JSGlobalObject::weakRandomOffset() + WeakRandom::lowOffset())); 514 }; 515 516 emitRandomThunkImpl(*this, scratch0, scratch1, scratch2, result, loadFromHigh, storeToHigh, loadFromLow, storeToLow); 517 } 518 #endif 519 423 520 } // namespace JSC 424 521 -
trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h
r193471 r194087 1372 1372 addPtr(TrustedImm32(stackOffset), stackPointerRegister); 1373 1373 } 1374 1375 #if USE(JSVALUE64) 1376 void emitRandomThunk(JSGlobalObject*, GPRReg scratch0, GPRReg scratch1, GPRReg scratch2, FPRReg result); 1377 void emitRandomThunk(GPRReg scratch0, GPRReg scratch1, GPRReg scratch2, GPRReg scratch3, FPRReg result); 1378 #endif 1374 1379 1375 1380 protected: -
trunk/Source/JavaScriptCore/jit/JITOperations.h
r194036 r194087 165 165 typedef JSCell* JIT_OPERATION (*C_JITOperation_EZ)(ExecState*, int32_t); 166 166 typedef double JIT_OPERATION (*D_JITOperation_D)(double); 167 typedef double JIT_OPERATION (*D_JITOperation_G)(JSGlobalObject*); 167 168 typedef double JIT_OPERATION (*D_JITOperation_DD)(double, double); 168 169 typedef double JIT_OPERATION (*D_JITOperation_ZZ)(int32_t, int32_t); -
trunk/Source/JavaScriptCore/jit/ThunkGenerators.cpp
r194062 r194087 1005 1005 } 1006 1006 1007 MacroAssemblerCodeRef randomThunkGenerator(VM* vm) 1008 { 1009 SpecializedThunkJIT jit(vm, 0); 1010 if (!jit.supportsFloatingPoint()) 1011 return MacroAssemblerCodeRef::createSelfManagedCodeRef(vm->jitStubs->ctiNativeCall(vm)); 1012 1013 #if USE(JSVALUE64) 1014 jit.emitRandomThunk(SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT1, SpecializedThunkJIT::regT2, SpecializedThunkJIT::regT3, SpecializedThunkJIT::fpRegT0); 1015 jit.returnDouble(SpecializedThunkJIT::fpRegT0); 1016 1017 return jit.finalize(vm->jitStubs->ctiNativeTailCall(vm), "random"); 1018 #else 1019 return MacroAssemblerCodeRef::createSelfManagedCodeRef(vm->jitStubs->ctiNativeCall(vm)); 1020 #endif 1021 } 1022 1007 1023 } 1008 1024 -
trunk/Source/JavaScriptCore/jit/ThunkGenerators.h
r191937 r194087 63 63 MacroAssemblerCodeRef powThunkGenerator(VM*); 64 64 MacroAssemblerCodeRef imulThunkGenerator(VM*); 65 MacroAssemblerCodeRef randomThunkGenerator(VM*); 65 66 66 67 } -
trunk/Source/JavaScriptCore/runtime/Intrinsic.h
r191215 r194087 54 54 StringPrototypeValueOfIntrinsic, 55 55 IMulIntrinsic, 56 RandomIntrinsic, 56 57 FRoundIntrinsic, 57 58 -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h
r194036 r194087 666 666 TemplateRegistry& templateRegistry() { return m_templateRegistry; } 667 667 668 static ptrdiff_t weakRandomOffset() { return OBJECT_OFFSETOF(JSGlobalObject, m_weakRandom); } 668 669 double weakRandomNumber() { return m_weakRandom.get(); } 669 670 unsigned weakRandomInteger() { return m_weakRandom.getUint32(); } -
trunk/Source/JavaScriptCore/runtime/MathObject.cpp
r191864 r194087 122 122 putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "min"), 2, mathProtoFuncMin, MinIntrinsic, DontEnum); 123 123 putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "pow"), 2, mathProtoFuncPow, PowIntrinsic, DontEnum); 124 putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "random"), 0, mathProtoFuncRandom, NoIntrinsic, DontEnum);124 putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "random"), 0, mathProtoFuncRandom, RandomIntrinsic, DontEnum); 125 125 putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "round"), 1, mathProtoFuncRound, RoundIntrinsic, DontEnum); 126 126 putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "sign"), 1, mathProtoFuncSign, NoIntrinsic, DontEnum); -
trunk/Source/JavaScriptCore/runtime/VM.cpp
r193649 r194087 449 449 case IMulIntrinsic: 450 450 return imulThunkGenerator; 451 case RandomIntrinsic: 452 return randomThunkGenerator; 451 453 default: 452 454 return 0; -
trunk/Source/WTF/ChangeLog
r194041 r194087 1 2015-12-14 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 Math.random should have an intrinsic thunk and it should be later handled as a DFG Node 4 https://bugs.webkit.org/show_bug.cgi?id=152133 5 6 Reviewed by Geoffrey Garen. 7 8 Change 64bit random to double logic to convert efficiently. 9 10 * wtf/WeakRandom.h: 11 (WTF::WeakRandom::get): 12 (WTF::WeakRandom::lowOffset): 13 (WTF::WeakRandom::highOffset): 14 1 15 2015-12-14 Sukolsak Sakshuwong <sukolsak@gmail.com> 2 16 -
trunk/Source/WTF/wtf/WeakRandom.h
r192855 r194087 38 38 namespace WTF { 39 39 40 // The code used to generate random numbers are inlined manually in JIT code. 41 // So it needs to stay in sync with the JIT one. 40 42 class WeakRandom { 41 43 public: … … 61 63 double get() 62 64 { 63 return advance() / (std::numeric_limits<uint64_t>::max() + 1.0); 65 uint64_t value = advance() & ((1ULL << 53) - 1); 66 return value * (1.0 / (1ULL << 53)); 64 67 } 65 68 … … 81 84 } 82 85 } 86 87 static unsigned lowOffset() { return OBJECT_OFFSETOF(WeakRandom, m_low); } 88 static unsigned highOffset() { return OBJECT_OFFSETOF(WeakRandom, m_high); } 83 89 84 90 private:
Note: See TracChangeset
for help on using the changeset viewer.