Changeset 190267 in webkit
- Timestamp:
- Sep 26, 2015 11:07:09 AM (9 years ago)
- Location:
- trunk/Source
- Files:
-
- 5 added
- 2 deleted
- 19 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/API/tests/testapi.mm
r186966 r190267 33 33 34 34 #import <pthread.h> 35 #import <vector> 35 36 36 37 extern "C" void JSSynchronousGarbageCollectForDebugging(JSContextRef); … … 482 483 TestObject *testObject = [TestObject testObject]; 483 484 context[@"testObject"] = testObject; 484 pthread_exit(nullptr); 485 return nullptr; 486 } 487 488 static void* multiVMThreadMain(void* okPtr) 489 { 490 bool& ok = *static_cast<bool*>(okPtr); 491 JSVirtualMachine *vm = [[JSVirtualMachine alloc] init]; 492 JSContext* context = [[JSContext alloc] initWithVirtualMachine:vm]; 493 [context evaluateScript: 494 @"var array = [{}];\n" 495 "for (var i = 0; i < 20; ++i) {\n" 496 " var newArray = new Array(array.length * 2);\n" 497 " for (var j = 0; j < newArray.length; ++j)\n" 498 " newArray[j] = {parent: array[j / 2]};\n" 499 " array = newArray;\n" 500 "}\n"]; 501 if (context.exception) { 502 NSLog(@"Uncaught exception.\n"); 503 ok = false; 504 } 505 if (![context.globalObject valueForProperty:@"array"].toObject) { 506 NSLog(@"Did not find \"array\" variable.\n"); 507 ok = false; 508 } 509 JSSynchronousGarbageCollectForDebugging([context JSGlobalContextRef]); 510 return nullptr; 485 511 } 486 512 … … 1417 1443 } 1418 1444 1445 @autoreleasepool { 1446 std::vector<pthread_t> threads; 1447 bool ok = true; 1448 for (unsigned i = 0; i < 5; ++i) { 1449 pthread_t threadID; 1450 pthread_create(&threadID, nullptr, multiVMThreadMain, &ok); 1451 threads.push_back(threadID); 1452 } 1453 1454 for (pthread_t thread : threads) 1455 pthread_join(thread, nullptr); 1456 1457 checkResult(@"Ran code in five concurrent VMs that GC'd", ok); 1458 } 1459 1419 1460 currentThisInsideBlockGetterTest(); 1420 1461 runDateTests(); -
trunk/Source/JavaScriptCore/CMakeLists.txt
r190155 r190267 295 295 heap/GCActivityCallback.cpp 296 296 heap/GCLogging.cpp 297 heap/GCThread.cpp298 297 heap/HandleSet.cpp 299 298 heap/HandleStack.cpp 300 299 heap/Heap.cpp 300 heap/HeapHelperPool.cpp 301 301 heap/HeapStatistics.cpp 302 302 heap/HeapTimer.cpp -
trunk/Source/JavaScriptCore/ChangeLog
r190261 r190267 1 2015-09-24 Filip Pizlo <fpizlo@apple.com> 2 3 VMs should share GC threads 4 https://bugs.webkit.org/show_bug.cgi?id=149433 5 rdar://problem/12859344 6 7 Reviewed by Geoffrey Garen. 8 9 This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. 10 This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of 11 code and also gives our GC magical thread sharing powers. If two GCs in two different VMs 12 fire at the same time, then they will both get a random subset of the available shared GC 13 threads. If one GC happens before the other, then it will probably get all of the available 14 threads. If a GC happens while another VM already started GCing, then it will probably not 15 get any helper threads. This is probably fine, since in multi-VM scenarios we have no 16 reason to optimize for anything other than total throughput. 17 18 The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It 19 would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap 20 instance has a helper client attached to the pool. 21 22 The marking phase tells the ParallelHelperClient to asynchronously run a function that 23 joins parallel marking and finishes once marking reaches termination. It uses the 24 client.setFunction() idiom where the threads share work with each other using a specialized 25 worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. 26 27 The copying phase tells the ParallelHelperClient to run a copying function in parallel. It 28 uses the client.runFunctionInParallel() idiom. The copying function gets work from the 29 m_blocksToCopy worklist inside Heap. 30 31 To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test 32 creates five concurrent VMs and has each of them allocate about 30MB of memory before doing 33 a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core 34 computer (this is correct since we are currently configured for 7-way parallelism). 35 36 This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of 37 VM instances. 38 39 * CMakeLists.txt: 40 * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: 41 * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: 42 * JavaScriptCore.xcodeproj/project.pbxproj: 43 * assembler/AbstractMacroAssembler.h: 44 * heap/GCThread.cpp: Removed. 45 * heap/GCThread.h: Removed. 46 * heap/Heap.cpp: 47 (JSC::Heap::Heap): 48 (JSC::Heap::~Heap): 49 (JSC::Heap::isPagedOut): 50 (JSC::Heap::markRoots): 51 (JSC::Heap::copyBackingStores): 52 (JSC::Heap::resetVisitors): 53 (JSC::Heap::threadVisitCount): 54 (JSC::Heap::threadBytesVisited): 55 (JSC::Heap::threadBytesCopied): 56 (JSC::Heap::startNextPhase): Deleted. 57 (JSC::Heap::endCurrentPhase): Deleted. 58 * heap/Heap.h: 59 * heap/HeapHelperPool.cpp: Added. 60 (JSC::heapHelperPool): 61 * heap/HeapHelperPool.h: Added. 62 * heap/MarkStack.cpp: 63 (JSC::MarkStackArray::stealSomeCellsFrom): 64 * heap/SlotVisitor.cpp: 65 (JSC::SlotVisitor::didStartMarking): 66 (JSC::SlotVisitor::reset): 67 (JSC::SlotVisitor::drainFromShared): 68 * jit/BinarySwitch.h: 69 * runtime/CodeCache.h: 70 * runtime/VM.h: 71 * runtime/WeakRandom.h: Removed. 72 * API/tests/testapi.mm: 73 1 74 2015-09-25 Saam barati <sbarati@apple.com> 2 75 -
trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj
r190151 r190267 570 570 <ClCompile Include="..\heap\HandleStack.cpp" /> 571 571 <ClCompile Include="..\heap\Heap.cpp" /> 572 <ClCompile Include="..\heap\HeapHelperPool.cpp" /> 572 573 <ClCompile Include="..\heap\HeapStatistics.cpp" /> 573 574 <ClCompile Include="..\heap\HeapTimer.cpp" /> … … 1351 1352 <ClInclude Include="..\heap\HandleTypes.h" /> 1352 1353 <ClInclude Include="..\heap\Heap.h" /> 1354 <ClInclude Include="..\heap\HeapHelperPool.h" /> 1353 1355 <ClInclude Include="..\heap\HeapInlines.h" /> 1354 1356 <ClInclude Include="..\heap\HeapOperation.h" /> … … 1810 1812 <ClInclude Include="..\runtime\WeakSetConstructor.h" /> 1811 1813 <ClInclude Include="..\runtime\WeakSetPrototype.h" /> 1812 <ClInclude Include="..\runtime\WeakRandom.h" />1813 1814 <ClInclude Include="..\runtime\WriteBarrier.h" /> 1814 1815 <ClInclude Include="..\runtime\WriteBarrierInlines.h" /> -
trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters
r190151 r190267 292 292 <Filter>heap</Filter> 293 293 </ClCompile> 294 <ClCompile Include="..\heap\HeapHelperPool.cpp"> 295 <Filter>heap</Filter> 296 </ClCompile> 294 297 <ClCompile Include="..\heap\HeapStatistics.cpp"> 295 298 <Filter>heap</Filter> … … 2289 2292 <Filter>heap</Filter> 2290 2293 </ClInclude> 2294 <ClInclude Include="..\heap\HeapHelperPool.h"> 2295 <Filter>heap</Filter> 2296 </ClInclude> 2291 2297 <ClInclude Include="..\heap\HeapInlines.h"> 2292 2298 <Filter>heap</Filter> … … 3166 3172 </ClInclude> 3167 3173 <ClInclude Include="..\runtime\WeakGCMap.h"> 3168 <Filter>runtime</Filter>3169 </ClInclude>3170 <ClInclude Include="..\runtime\WeakRandom.h">3171 3174 <Filter>runtime</Filter> 3172 3175 </ClInclude> -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r190201 r190267 275 275 0F300B7B18AB1B1400A6D72E /* DFGIntegerCheckCombiningPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F300B7918AB1B1400A6D72E /* DFGIntegerCheckCombiningPhase.cpp */; }; 276 276 0F300B7C18AB1B1400A6D72E /* DFGIntegerCheckCombiningPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F300B7A18AB1B1400A6D72E /* DFGIntegerCheckCombiningPhase.h */; }; 277 0F32BD101BB34F190093A57F /* HeapHelperPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F32BD0E1BB34F190093A57F /* HeapHelperPool.cpp */; }; 278 0F32BD111BB34F190093A57F /* HeapHelperPool.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F32BD0F1BB34F190093A57F /* HeapHelperPool.h */; }; 277 279 0F34B14916D42010001CDA5A /* DFGUseKind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F34B14716D4200E001CDA5A /* DFGUseKind.cpp */; }; 278 280 0F34B14A16D42013001CDA5A /* DFGUseKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F34B14816D4200E001CDA5A /* DFGUseKind.h */; }; … … 776 778 141448CD13A1783700F5BA1A /* TinyBloomFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 141448CC13A1783700F5BA1A /* TinyBloomFilter.h */; settings = {ATTRIBUTES = (Private, ); }; }; 777 779 14150133154BB13F005D8C98 /* WeakSetInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 14150132154BB13F005D8C98 /* WeakSetInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; 778 1420BE7B10AA6DDB00F455D2 /* WeakRandom.h in Headers */ = {isa = PBXBuildFile; fileRef = 1420BE7A10AA6DDB00F455D2 /* WeakRandom.h */; settings = {ATTRIBUTES = (Private, ); }; };779 780 1421359B0A677F4F00A8195E /* JSBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1421359A0A677F4F00A8195E /* JSBase.cpp */; }; 780 781 14280823107EC02C0013E7B2 /* Debugger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A8580255597D01FF60F7 /* Debugger.cpp */; }; … … 1666 1667 C2239D1816262BDD005AC5FD /* CopyVisitor.h in Headers */ = {isa = PBXBuildFile; fileRef = C2239D1316262BDD005AC5FD /* CopyVisitor.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1667 1668 C2239D1916262BDD005AC5FD /* CopyVisitorInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = C2239D1416262BDD005AC5FD /* CopyVisitorInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1668 C2239D1A16262BDD005AC5FD /* GCThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2239D1516262BDD005AC5FD /* GCThread.cpp */; };1669 C2239D1B16262BDD005AC5FD /* GCThread.h in Headers */ = {isa = PBXBuildFile; fileRef = C2239D1616262BDD005AC5FD /* GCThread.h */; settings = {ATTRIBUTES = (Private, ); }; };1670 1669 C225494315F7DBAA0065E898 /* SlotVisitor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C225494215F7DBAA0065E898 /* SlotVisitor.cpp */; }; 1671 1670 C22B31B9140577D700DB475A /* SamplingCounter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F77008E1402FDD60078EB39 /* SamplingCounter.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 2120 2119 0F300B7918AB1B1400A6D72E /* DFGIntegerCheckCombiningPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGIntegerCheckCombiningPhase.cpp; path = dfg/DFGIntegerCheckCombiningPhase.cpp; sourceTree = "<group>"; }; 2121 2120 0F300B7A18AB1B1400A6D72E /* DFGIntegerCheckCombiningPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGIntegerCheckCombiningPhase.h; path = dfg/DFGIntegerCheckCombiningPhase.h; sourceTree = "<group>"; }; 2121 0F32BD0E1BB34F190093A57F /* HeapHelperPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HeapHelperPool.cpp; sourceTree = "<group>"; }; 2122 0F32BD0F1BB34F190093A57F /* HeapHelperPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapHelperPool.h; sourceTree = "<group>"; }; 2122 2123 0F34B14716D4200E001CDA5A /* DFGUseKind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGUseKind.cpp; path = dfg/DFGUseKind.cpp; sourceTree = "<group>"; }; 2123 2124 0F34B14816D4200E001CDA5A /* DFGUseKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGUseKind.h; path = dfg/DFGUseKind.h; sourceTree = "<group>"; }; … … 2617 2618 141448CC13A1783700F5BA1A /* TinyBloomFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TinyBloomFilter.h; sourceTree = "<group>"; }; 2618 2619 14150132154BB13F005D8C98 /* WeakSetInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakSetInlines.h; sourceTree = "<group>"; }; 2619 1420BE7A10AA6DDB00F455D2 /* WeakRandom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakRandom.h; sourceTree = "<group>"; };2620 2620 1421359A0A677F4F00A8195E /* JSBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSBase.cpp; sourceTree = "<group>"; }; 2621 2621 142711380A460BBB0080EEEA /* JSBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSBase.h; sourceTree = "<group>"; }; … … 3538 3538 C2239D1316262BDD005AC5FD /* CopyVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopyVisitor.h; sourceTree = "<group>"; }; 3539 3539 C2239D1416262BDD005AC5FD /* CopyVisitorInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopyVisitorInlines.h; sourceTree = "<group>"; }; 3540 C2239D1516262BDD005AC5FD /* GCThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCThread.cpp; sourceTree = "<group>"; };3541 C2239D1616262BDD005AC5FD /* GCThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCThread.h; sourceTree = "<group>"; };3542 3540 C225494215F7DBAA0065E898 /* SlotVisitor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SlotVisitor.cpp; sourceTree = "<group>"; }; 3543 3541 C240305314B404C90079EB64 /* CopiedSpace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CopiedSpace.cpp; sourceTree = "<group>"; }; … … 4252 4250 2A343F7418A1748B0039B085 /* GCSegmentedArray.h */, 4253 4251 2A343F7718A1749D0039B085 /* GCSegmentedArrayInlines.h */, 4254 C2239D1516262BDD005AC5FD /* GCThread.cpp */,4255 C2239D1616262BDD005AC5FD /* GCThread.h */,4256 4252 142E312B134FF0A600AFADB5 /* Handle.h */, 4257 4253 C28318FF16FE4B7D00157BFD /* HandleBlock.h */, … … 4264 4260 14BA7A9513AADFF8005B7C2C /* Heap.cpp */, 4265 4261 14BA7A9613AADFF8005B7C2C /* Heap.h */, 4262 0F32BD0E1BB34F190093A57F /* HeapHelperPool.cpp */, 4263 0F32BD0F1BB34F190093A57F /* HeapHelperPool.h */, 4266 4264 C2DA778218E259990066FCB6 /* HeapInlines.h */, 4267 4265 2AD8932917E3868F00668276 /* HeapIterationScope.h */, … … 5093 5091 A7CA3ADF17DA41AE006538AF /* WeakMapPrototype.cpp */, 5094 5092 A7CA3AE017DA41AE006538AF /* WeakMapPrototype.h */, 5095 1420BE7A10AA6DDB00F455D2 /* WeakRandom.h */,5096 5093 709FB8631AE335C60039D069 /* WeakSetConstructor.cpp */, 5097 5094 709FB8641AE335C60039D069 /* WeakSetConstructor.h */, … … 6156 6153 0F2BDC16151C5D4F00CD8910 /* DFGFixupPhase.h in Headers */, 6157 6154 0F9D339717FFC4E60073C2BC /* DFGFlushedAt.h in Headers */, 6155 0F32BD111BB34F190093A57F /* HeapHelperPool.h in Headers */, 6158 6156 A7D89CF817A0B8CC00773AD8 /* DFGFlushFormat.h in Headers */, 6159 6157 0F2DD8151AB3D8BE00BBB8E8 /* DFGForAllKills.h in Headers */, … … 6932 6930 A7CA3AEC17DA5168006538AF /* WeakMapData.h in Headers */, 6933 6931 A7CA3AE617DA41AE006538AF /* WeakMapPrototype.h in Headers */, 6934 1420BE7B10AA6DDB00F455D2 /* WeakRandom.h in Headers */,6935 6932 0F242DA713F3B1E8007ADD4C /* WeakReferenceHarvester.h in Headers */, 6936 6933 14E84FA114EE1ACC00D6D5D4 /* WeakSet.h in Headers */, … … 8063 8060 0FF42743158EBE91004CB9FF /* udis86_input.c in Sources */, 8064 8061 0FF4274D158EBFE6004CB9FF /* udis86_itab_holder.c in Sources */, 8062 0F32BD101BB34F190093A57F /* HeapHelperPool.cpp in Sources */, 8065 8063 0FF42745158EBE91004CB9FF /* udis86_syn-att.c in Sources */, 8066 8064 0FF42746158EBE91004CB9FF /* udis86_syn-intel.c in Sources */, -
trunk/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h
r189884 r190267 32 32 #include "MacroAssemblerCodeRef.h" 33 33 #include "Options.h" 34 #include "WeakRandom.h"35 34 #include <wtf/CryptographicallyRandomNumber.h> 36 35 #include <wtf/Noncopyable.h> 36 #include <wtf/WeakRandom.h> 37 37 38 38 #if ENABLE(ASSEMBLER) -
trunk/Source/JavaScriptCore/heap/Heap.cpp
r190185 r190267 1 1 /* 2 * Copyright (C) 2003 , 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2013, 2014Apple Inc. All rights reserved.2 * Copyright (C) 2003-2009, 2011, 2013-2015 Apple Inc. All rights reserved. 3 3 * Copyright (C) 2007 Eric Seidel <eric@webkit.org> 4 4 * … … 32 32 #include "GCActivityCallback.h" 33 33 #include "GCIncomingRefCountedSetInlines.h" 34 #include "HeapHelperPool.h" 34 35 #include "HeapIterationScope.h" 35 36 #include "HeapRootVisitor.h" … … 337 338 , m_machineThreads(this) 338 339 , m_slotVisitor(*this) 339 , m_copyVisitor(*this)340 340 , m_handleSet(vm) 341 341 , m_isSafeToCollect(false) … … 357 357 , m_delayedReleaseRecursionCount(0) 358 358 #endif 359 { 360 { 361 // Grab the lock so the new GC threads can be properly initialized before they start running. 362 std::unique_lock<Lock> lock(m_phaseMutex); 363 for (unsigned i = 1; i < Options::numberOfGCMarkers(); ++i) { 364 m_numberOfActiveGCThreads++; 365 GCThread* newThread = new GCThread(*this, std::make_unique<SlotVisitor>(*this)); 366 ThreadIdentifier threadID = createThread(GCThread::gcThreadStartFunc, newThread, "JavaScriptCore::Marking"); 367 newThread->initializeThreadID(threadID); 368 m_gcThreads.append(newThread); 369 } 370 371 // Wait for all the GCThreads to get to the right place. 372 m_activityConditionVariable.wait(lock, [this] { return !m_numberOfActiveGCThreads; }); 373 } 374 359 , m_helperClient(&heapHelperPool()) 360 { 375 361 m_storageSpace.init(); 376 362 if (Options::verifyHeap()) … … 382 368 for (WeakBlock* block : m_logicallyEmptyWeakBlocks) 383 369 WeakBlock::destroy(block); 384 385 // Destroy our marking threads.386 {387 std::lock_guard<Lock> markingLock(m_markingMutex);388 std::lock_guard<Lock> phaseLock(m_phaseMutex);389 ASSERT(m_currentPhase == NoPhase);390 m_parallelMarkersShouldExit = true;391 m_gcThreadsShouldWait = false;392 m_currentPhase = Exit;393 m_phaseConditionVariable.notifyAll();394 }395 for (unsigned i = 0; i < m_gcThreads.size(); ++i) {396 waitForThreadCompletion(m_gcThreads[i]->threadID());397 delete m_gcThreads[i];398 }399 370 } 400 371 … … 571 542 if (m_operationInProgress == FullCollection) 572 543 m_opaqueRoots.clear(); 573 { 574 std::lock_guard<Lock> lock(m_markingMutex); 575 m_parallelMarkersShouldExit = false; 576 startNextPhase(Mark); 577 } 544 545 m_shouldHashCons = m_vm->haveEnoughNewStringsToHashCons(); 546 547 m_parallelMarkersShouldExit = false; 548 549 m_helperClient.setFunction( 550 [this] () { 551 SlotVisitor* slotVisitor; 552 { 553 LockHolder locker(m_parallelSlotVisitorLock); 554 if (m_availableParallelSlotVisitors.isEmpty()) { 555 std::unique_ptr<SlotVisitor> newVisitor = 556 std::make_unique<SlotVisitor>(*this); 557 slotVisitor = newVisitor.get(); 558 m_parallelSlotVisitors.append(WTF::move(newVisitor)); 559 } else 560 slotVisitor = m_availableParallelSlotVisitors.takeLast(); 561 } 562 563 { 564 ParallelModeEnabler parallelModeEnabler(*slotVisitor); 565 slotVisitor->didStartMarking(); 566 slotVisitor->drainFromShared(SlotVisitor::SlaveDrain); 567 } 568 569 { 570 LockHolder locker(m_parallelSlotVisitorLock); 571 m_availableParallelSlotVisitors.append(slotVisitor); 572 } 573 }); 574 578 575 m_slotVisitor.didStartMarking(); 576 579 577 HeapRootVisitor heapRootVisitor(m_slotVisitor); 580 578 … … 604 602 m_markingConditionVariable.notifyAll(); 605 603 } 606 ASSERT(m_currentPhase == Mark); 607 endCurrentPhase(); 604 m_helperClient.finish(); 608 605 updateObjectCounts(gcStartTime); 609 606 resetVisitors(); … … 634 631 m_copyIndex = 0; 635 632 } 636 637 startNextPhase(Copy);638 639 m_copyVisitor.startCopying();640 m_copyVisitor.copyFromShared();641 m_copyVisitor.doneCopying();642 643 ASSERT(m_currentPhase == Copy);644 endCurrentPhase();633 634 m_helperClient.runFunctionInParallel( 635 [this] () { 636 CopyVisitor copyVisitor(*this); 637 copyVisitor.startCopying(); 638 copyVisitor.copyFromShared(); 639 copyVisitor.doneCopying(); 640 WTF::releaseFastMallocFreeMemoryForThisThread(); 641 }); 645 642 } 646 643 … … 871 868 m_slotVisitor.reset(); 872 869 873 for ( GCThread* thread : m_gcThreads)874 thread->slotVisitor()->reset();870 for (auto& parallelVisitor : m_parallelSlotVisitors) 871 parallelVisitor->reset(); 875 872 876 873 ASSERT(m_sharedMarkStack.isEmpty()); … … 1533 1530 { 1534 1531 unsigned long result = 0; 1535 for ( unsigned i = 0; i < m_gcThreads.size(); ++i)1536 result += m_gcThreads[i]->slotVisitor()->visitCount();1532 for (auto& parallelVisitor : m_parallelSlotVisitors) 1533 result += parallelVisitor->visitCount(); 1537 1534 return result; 1538 1535 } … … 1541 1538 { 1542 1539 size_t result = 0; 1543 for ( unsigned i = 0; i < m_gcThreads.size(); ++i)1544 result += m_gcThreads[i]->slotVisitor()->bytesVisited();1540 for (auto& parallelVisitor : m_parallelSlotVisitors) 1541 result += parallelVisitor->bytesVisited(); 1545 1542 return result; 1546 1543 } … … 1549 1546 { 1550 1547 size_t result = 0; 1551 for ( unsigned i = 0; i < m_gcThreads.size(); ++i)1552 result += m_gcThreads[i]->slotVisitor()->bytesCopied();1548 for (auto& parallelVisitor : m_parallelSlotVisitors) 1549 result += parallelVisitor->bytesCopied(); 1553 1550 return result; 1554 1551 } 1555 1552 1556 void Heap::startNextPhase(GCPhase phase)1557 {1558 std::lock_guard<Lock> lock(m_phaseMutex);1559 ASSERT(!m_gcThreadsShouldWait);1560 ASSERT(m_currentPhase == NoPhase);1561 m_gcThreadsShouldWait = true;1562 m_currentPhase = phase;1563 m_phaseConditionVariable.notifyAll();1564 }1565 1566 void Heap::endCurrentPhase()1567 {1568 ASSERT(m_gcThreadsShouldWait);1569 std::unique_lock<Lock> lock(m_phaseMutex);1570 m_currentPhase = NoPhase;1571 m_gcThreadsShouldWait = false;1572 m_phaseConditionVariable.notifyAll();1573 m_activityConditionVariable.wait(lock, [this] { return !m_numberOfActiveGCThreads; });1574 }1575 1576 1553 } // namespace JSC -
trunk/Source/JavaScriptCore/heap/Heap.h
r190217 r190267 27 27 #include "CopyVisitor.h" 28 28 #include "GCIncomingRefCountedSet.h" 29 #include "GCThread.h"30 29 #include "HandleSet.h" 31 30 #include "HandleStack.h" … … 47 46 #include <wtf/HashCountedSet.h> 48 47 #include <wtf/HashSet.h> 48 #include <wtf/ParallelHelperPool.h> 49 49 50 50 namespace JSC { … … 348 348 349 349 void getNextBlocksToCopy(size_t&, size_t&); 350 void startNextPhase(GCPhase);351 void endCurrentPhase();352 350 353 351 const HeapType m_heapType; … … 384 382 385 383 SlotVisitor m_slotVisitor; 386 CopyVisitor m_copyVisitor; 384 385 // We pool the slot visitors used by parallel marking threads. It's useful to be able to 386 // enumerate over them, and it's useful to have them cache some small amount of memory from 387 // one GC to the next. GC marking threads claim these at the start of marking, and return 388 // them at the end. 389 Vector<std::unique_ptr<SlotVisitor>> m_parallelSlotVisitors; 390 Vector<SlotVisitor*> m_availableParallelSlotVisitors; 391 Lock m_parallelSlotVisitorLock; 387 392 388 393 HandleSet m_handleSet; … … 422 427 423 428 bool m_shouldHashCons { false }; 424 425 Vector<GCThread*> m_gcThreads;426 429 427 430 Lock m_markingMutex; … … 440 443 static const size_t s_blockFragmentLength = 32; 441 444 442 Lock m_phaseMutex;443 Condition m_phaseConditionVariable;444 Condition m_activityConditionVariable;445 unsigned m_numberOfActiveGCThreads { 0 };446 bool m_gcThreadsShouldWait { false };447 GCPhase m_currentPhase { NoPhase };448 449 445 ListableHandler<WeakReferenceHarvester>::List m_weakReferenceHarvesters; 450 446 ListableHandler<UnconditionalFinalizer>::List m_unconditionalFinalizers; 447 448 ParallelHelperClient m_helperClient; 451 449 }; 452 450 -
trunk/Source/JavaScriptCore/heap/MarkStack.cpp
r179348 r190267 1 1 /* 2 * Copyright (C) 2009, 2011 Apple Inc. All rights reserved.2 * Copyright (C) 2009, 2011, 2015 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 108 108 } 109 109 110 size_t numberOfCellsToSteal = (other.size() + idleThreadCount - 1) / idleThreadCount; // Round up to steal 1 / 1. 110 // Steal ceil(other.size() / idleThreadCount) things. 111 size_t numberOfCellsToSteal = (other.size() + idleThreadCount - 1) / idleThreadCount; 111 112 while (numberOfCellsToSteal-- > 0 && other.canRemoveLast()) 112 113 append(other.removeLast()); -
trunk/Source/JavaScriptCore/heap/SlotVisitor.cpp
r190217 r190267 31 31 #include "CopiedSpace.h" 32 32 #include "CopiedSpaceInlines.h" 33 #include "GCThread.h"34 33 #include "JSArray.h" 35 34 #include "JSDestructibleObject.h" … … 68 67 ASSERT(m_opaqueRoots.isEmpty()); // Should have merged by now. 69 68 70 m_heap.m_shouldHashCons = m_heap.m_vm->haveEnoughNewStringsToHashCons();71 69 m_shouldHashCons = m_heap.m_shouldHashCons; 72 for (unsigned i = 0; i < m_heap.m_gcThreads.size(); ++i)73 m_heap.m_gcThreads[i]->slotVisitor()->m_shouldHashCons = m_heap.m_shouldHashCons;74 70 } 75 71 … … 222 218 return; 223 219 } 224 220 225 221 m_stack.stealSomeCellsFrom( 226 222 m_heap.m_sharedMarkStack, m_heap.m_numberOfWaitingParallelMarkers); -
trunk/Source/JavaScriptCore/jit/BinarySwitch.h
r189586 r190267 31 31 #include "GPRInfo.h" 32 32 #include "MacroAssembler.h" 33 #include "WeakRandom.h"33 #include <wtf/WeakRandom.h> 34 34 35 35 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/CodeCache.h
r189201 r190267 32 32 #include "Strong.h" 33 33 #include "VariableEnvironment.h" 34 #include "WeakRandom.h"35 34 #include <wtf/CurrentTime.h> 36 35 #include <wtf/Forward.h> 37 36 #include <wtf/RandomNumber.h> 37 #include <wtf/WeakRandom.h> 38 38 #include <wtf/text/WTFString.h> 39 39 -
trunk/Source/JavaScriptCore/runtime/VM.h
r190076 r190267 55 55 #include "VMEntryRecord.h" 56 56 #include "Watchpoint.h" 57 #include "WeakRandom.h"58 57 #include <wtf/Bag.h> 59 58 #include <wtf/BumpPointerAllocator.h> … … 68 67 #include <wtf/ThreadSpecific.h> 69 68 #include <wtf/WTFThreadData.h> 69 #include <wtf/WeakRandom.h> 70 70 #include <wtf/text/SymbolRegistry.h> 71 71 #include <wtf/text/WTFString.h> -
trunk/Source/WTF/ChangeLog
r190255 r190267 1 2015-09-24 Filip Pizlo <fpizlo@apple.com> 2 3 VMs should share GC threads 4 https://bugs.webkit.org/show_bug.cgi?id=149433 5 rdar://problem/12859344 6 7 Reviewed by Geoffrey Garen. 8 9 This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was 10 already in JSC; we're just hoisting it into WTF. It's just a weak random number generator 11 that's suitable for places where you need just a tiny bit of randomness. 12 13 ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. 14 In a data-parallel algorithm, we want to run one task on as many cores as possible and let 15 the task worry about which subset of the input data to work on. In some cases, the 16 algorithm will not need to do any load balancing - and if load balancing is required, it's 17 up to the user. This is appropriate in contexts where the load balancing needs to be 18 custom-tuned for performance, like the GC's marking phase. 19 20 This new API has three concepts: task, client, and pool. A task is a reference counted 21 object with a run() method, which may be run in parallel. It is usually used to wrap a 22 functor. A pool is a pool of threads that can run things. A client is a placeholder for a 23 task. A client can have zero or one tasks. A client must be registered with a pool. When a 24 client has a task, the pool's threads may choose to run it. If a thread starts running a 25 task, it will run it to completion. When the task returns on any thread, the client takes 26 it to mean that the task should be removed. That means that any currently running instances 27 of the task will finish but no new threads will attempt to run the task. You can easily ask 28 a client to wait until a task finishes. You can also easily ask a client to run a task on 29 the current thread in addition to possibly some helper threads from the pool. 30 31 For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: 32 33 client.runFunctionInParallel( 34 [=] () { 35 do things; 36 }); 37 38 Note that you cannot tell ahead of time how many threads will join to help the task. 39 Threads may become available after the task has already started running. Those threads may 40 join after the other threads have already started. It's not advisable to make algorithmic 41 decisions based on client.numberOfActiveThreads(), since that number may change. Usually 42 the best way to use ParallelHelperPool is with an algorithm that has its own custom 43 worklist. An example of a very simple custom worklist is the one in the JSC GC's copying 44 phase - it's just a Vector and an index that indicates the next set of elements to process. 45 46 This new API was initially designed to simplify how GCThread works, by replacing Phase with 47 a callback that contains the phase's workload. I then realized that with a few tweaks, I 48 could make this somewhat general enough that it might become interesting outside GC. I also 49 realized that I could use this to enable thread sharing. So, although the API is kinda 50 quirky, it's grounded in the reality of how the JSC GC does parallelism. 51 52 * WTF.vcxproj/WTF.vcxproj: 53 * WTF.vcxproj/WTF.vcxproj.filters: 54 * WTF.xcodeproj/project.pbxproj: 55 * wtf/CMakeLists.txt: 56 * wtf/ParallelHelperPool.cpp: Added. 57 (WTF::ParallelHelperClient::ParallelHelperClient): 58 (WTF::ParallelHelperClient::~ParallelHelperClient): 59 (WTF::ParallelHelperClient::setTask): 60 (WTF::ParallelHelperClient::finish): 61 (WTF::ParallelHelperClient::doSomeHelping): 62 (WTF::ParallelHelperClient::runTaskInParallel): 63 (WTF::ParallelHelperClient::claimTask): 64 (WTF::ParallelHelperClient::runTask): 65 (WTF::ParallelHelperPool::ParallelHelperPool): 66 (WTF::ParallelHelperPool::~ParallelHelperPool): 67 (WTF::ParallelHelperPool::addThreads): 68 (WTF::ParallelHelperPool::ensureThreads): 69 (WTF::ParallelHelperPool::doSomeHelping): 70 (WTF::ParallelHelperPool::didMakeWorkAvailable): 71 (WTF::ParallelHelperPool::helperThreadBody): 72 (WTF::ParallelHelperPool::hasClientWithTask): 73 (WTF::ParallelHelperPool::getClientWithTask): 74 (WTF::ParallelHelperPool::waitForClientWithTask): 75 * wtf/ParallelHelperPool.h: Added. 76 (WTF::ParallelHelperClient::setFunction): 77 (WTF::ParallelHelperClient::runFunctionInParallel): 78 (WTF::ParallelHelperClient::pool): 79 (WTF::ParallelHelperClient::numberOfActiveThreads): 80 (WTF::ParallelHelperPool::numberOfThreads): 81 * wtf/SharedTask.h: Added. 82 (WTF::SharedTask::SharedTask): 83 (WTF::SharedTask::~SharedTask): 84 (WTF::SharedTaskFunctor::SharedTaskFunctor): 85 (WTF::createSharedTask): 86 * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. 87 (WTF::WeakRandom::WeakRandom): 88 (WTF::WeakRandom::initializeSeed): 89 (WTF::WeakRandom::seedUnsafe): 90 (WTF::WeakRandom::getUint32): 91 (WTF::WeakRandom::advance): 92 (JSC::WeakRandom::WeakRandom): Deleted. 93 (JSC::WeakRandom::seedUnsafe): Deleted. 94 (JSC::WeakRandom::getUint32): Deleted. 95 (JSC::WeakRandom::advance): Deleted. 96 (JSC::WeakRandom::initializeSeed): Deleted. 97 1 98 2015-09-25 Alex Christensen <achristensen@webkit.org> 2 99 -
trunk/Source/WTF/WTF.vcxproj/WTF.vcxproj
r188677 r190267 116 116 <ClCompile Include="..\wtf\OSRandomSource.cpp" /> 117 117 <ClCompile Include="..\wtf\PageBlock.cpp" /> 118 <ClCompile Include="..\wtf\ParallelHelperPool.cpp" /> 118 119 <ClCompile Include="..\wtf\ParallelJobsGeneric.cpp" /> 119 120 <ClCompile Include="..\wtf\ParkingLot.cpp" /> … … 247 248 <ClInclude Include="..\wtf\PageBlock.h" /> 248 249 <ClInclude Include="..\wtf\PageReservation.h" /> 250 <ClInclude Include="..\wtf\ParallelHelperPool.h" /> 249 251 <ClInclude Include="..\wtf\ParallelJobs.h" /> 250 252 <ClInclude Include="..\wtf\ParallelJobsGeneric.h" /> … … 270 272 <ClInclude Include="..\wtf\SentinelLinkedList.h" /> 271 273 <ClInclude Include="..\wtf\SHA1.h" /> 274 <ClInclude Include="..\wtf\SharedTask.h" /> 272 275 <ClInclude Include="..\wtf\SinglyLinkedList.h" /> 273 276 <ClInclude Include="..\wtf\SixCharacterHash.h" /> … … 314 317 <ClInclude Include="..\wtf\win\GDIObject.h" /> 315 318 <ClInclude Include="..\wtf\win\WorkItemWin.h" /> 319 <ClInclude Include="..\wtf\WeakRandom.h" /> 316 320 <ClInclude Include="..\wtf\WordLock.h" /> 317 321 <ClInclude Include="..\wtf\WorkQueue.h" /> -
trunk/Source/WTF/WTF.vcxproj/WTF.vcxproj.filters
r188557 r190267 1 <?xml version="1.0" encoding="utf-8"?>1 <?xml version="1.0" encoding="utf-8"?> 2 2 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 3 3 <ItemGroup> … … 175 175 <Filter>wtf</Filter> 176 176 </ClCompile> 177 <ClCompile Include="..\wtf\ParallelHelperPool.cpp"> 178 <Filter>wtf</Filter> 179 </ClCompile> 177 180 <ClCompile Include="..\wtf\ParallelJobsGeneric.cpp"> 178 181 <Filter>wtf</Filter> … … 548 551 <Filter>wtf</Filter> 549 552 </ClInclude> 553 <ClInclude Include="..\wtf\ParallelHelperPool.h"> 554 <Filter>wtf</Filter> 555 </ClInclude> 550 556 <ClInclude Include="..\wtf\ParallelJobs.h"> 551 557 <Filter>wtf</Filter> … … 603 609 </ClInclude> 604 610 <ClInclude Include="..\wtf\SHA1.h"> 611 <Filter>wtf</Filter> 612 </ClInclude> 613 <ClInclude Include="..\wtf\SharedTask.h"> 605 614 <Filter>wtf</Filter> 606 615 </ClInclude> -
trunk/Source/WTF/WTF.xcodeproj/project.pbxproj
r190201 r190267 25 25 0F2B66A617B6B4FB00A7AE3F /* DeferrableRefCounted.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66A417B6B4F700A7AE3F /* DeferrableRefCounted.h */; }; 26 26 0F2B66A717B6B4FD00A7AE3F /* FlipBytes.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66A517B6B4F700A7AE3F /* FlipBytes.h */; }; 27 0F3501641BB258D500F0A2A3 /* WeakRandom.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3501631BB258C800F0A2A3 /* WeakRandom.h */; }; 27 28 0F824A681B7443A0002E345D /* ParkingLot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F824A641B7443A0002E345D /* ParkingLot.cpp */; }; 28 29 0F824A691B7443A0002E345D /* ParkingLot.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F824A651B7443A0002E345D /* ParkingLot.h */; }; … … 48 49 0FE4479C1B7AAA03009498EB /* WordLock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE4479A1B7AAA03009498EB /* WordLock.cpp */; }; 49 50 0FE4479D1B7AAA03009498EB /* WordLock.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE4479B1B7AAA03009498EB /* WordLock.h */; }; 51 0FEB3DCF1BB5D684009D7AAD /* SharedTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEB3DCE1BB5D684009D7AAD /* SharedTask.h */; }; 50 52 0FED67B61B22D4D80066CE15 /* TinyPtrSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FED67B51B22D4D80066CE15 /* TinyPtrSet.h */; }; 53 0FFF19DC1BB334EB00886D91 /* ParallelHelperPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FFF19DA1BB334EB00886D91 /* ParallelHelperPool.cpp */; }; 54 0FFF19DD1BB334EB00886D91 /* ParallelHelperPool.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FFF19DB1BB334EB00886D91 /* ParallelHelperPool.h */; }; 51 55 14022F4118F5C3FC007FF0EB /* libbmalloc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 14022F4018F5C3FC007FF0EB /* libbmalloc.a */; }; 52 56 143F611F1565F0F900DB514A /* RAMSize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 143F611D1565F0F900DB514A /* RAMSize.cpp */; }; … … 313 317 0F2B66A517B6B4F700A7AE3F /* FlipBytes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FlipBytes.h; sourceTree = "<group>"; }; 314 318 0F300B7D18AB48B400A6D72E /* HashMethod.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HashMethod.h; sourceTree = "<group>"; }; 319 0F3501631BB258C800F0A2A3 /* WeakRandom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakRandom.h; sourceTree = "<group>"; }; 315 320 0F824A641B7443A0002E345D /* ParkingLot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParkingLot.cpp; sourceTree = "<group>"; }; 316 321 0F824A651B7443A0002E345D /* ParkingLot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParkingLot.h; sourceTree = "<group>"; }; … … 336 341 0FE4479A1B7AAA03009498EB /* WordLock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WordLock.cpp; sourceTree = "<group>"; }; 337 342 0FE4479B1B7AAA03009498EB /* WordLock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WordLock.h; sourceTree = "<group>"; }; 343 0FEB3DCE1BB5D684009D7AAD /* SharedTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SharedTask.h; sourceTree = "<group>"; }; 338 344 0FED67B51B22D4D80066CE15 /* TinyPtrSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TinyPtrSet.h; sourceTree = "<group>"; }; 345 0FFF19DA1BB334EB00886D91 /* ParallelHelperPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParallelHelperPool.cpp; sourceTree = "<group>"; }; 346 0FFF19DB1BB334EB00886D91 /* ParallelHelperPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParallelHelperPool.h; sourceTree = "<group>"; }; 339 347 14022F4018F5C3FC007FF0EB /* libbmalloc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libbmalloc.a; sourceTree = BUILT_PRODUCTS_DIR; }; 340 348 143F611D1565F0F900DB514A /* RAMSize.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RAMSize.cpp; sourceTree = "<group>"; }; … … 819 827 A8A472E4151A825B004123FF /* PageBlock.h */, 820 828 A8A472E5151A825B004123FF /* PageReservation.h */, 829 0FFF19DA1BB334EB00886D91 /* ParallelHelperPool.cpp */, 830 0FFF19DB1BB334EB00886D91 /* ParallelHelperPool.h */, 821 831 A8A472E6151A825B004123FF /* ParallelJobs.h */, 822 832 A8A472E9151A825B004123FF /* ParallelJobsLibdispatch.h */, … … 856 866 A8A47308151A825B004123FF /* SHA1.cpp */, 857 867 A8A47309151A825B004123FF /* SHA1.h */, 868 0FEB3DCE1BB5D684009D7AAD /* SharedTask.h */, 858 869 A8A4730A151A825B004123FF /* SimpleStats.h */, 859 870 A8A4730B151A825B004123FF /* SinglyLinkedList.h */, … … 893 904 A8A47372151A825B004123FF /* VMTags.h */, 894 905 974CFC8D16A4F327006D5404 /* WeakPtr.h */, 906 0F3501631BB258C800F0A2A3 /* WeakRandom.h */, 895 907 0FE4479A1B7AAA03009498EB /* WordLock.cpp */, 896 908 0FE4479B1B7AAA03009498EB /* WordLock.h */, … … 1064 1076 A8A47434151A825B004123FF /* ASCIIFastPath.h in Headers */, 1065 1077 A8A47387151A825B004123FF /* Assertions.h in Headers */, 1078 0F3501641BB258D500F0A2A3 /* WeakRandom.h in Headers */, 1066 1079 A8A47388151A825B004123FF /* Atomics.h in Headers */, 1067 1080 A8A47436151A825B004123FF /* AtomicString.h in Headers */, … … 1075 1088 A8A473A9151A825B004123FF /* bignum-dtoa.h in Headers */, 1076 1089 A8A473AB151A825B004123FF /* bignum.h in Headers */, 1090 0FFF19DD1BB334EB00886D91 /* ParallelHelperPool.h in Headers */, 1077 1091 A8A47452151A825B004123FF /* BinarySemaphore.h in Headers */, 1078 1092 A8A4738A151A825B004123FF /* Bitmap.h in Headers */, … … 1127 1141 A8A473D5151A825B004123FF /* HashIterators.h in Headers */, 1128 1142 A8A473D6151A825B004123FF /* HashMap.h in Headers */, 1143 0FEB3DCF1BB5D684009D7AAD /* SharedTask.h in Headers */, 1129 1144 A8A473D7151A825B004123FF /* HashSet.h in Headers */, 1130 1145 A8A473D9151A825B004123FF /* HashTable.h in Headers */, … … 1393 1408 2CDED0EF18115C38004DBA70 /* RunLoopCF.cpp in Sources */, 1394 1409 1469419316EAAF6D0024E146 /* RunLoopTimerCF.cpp in Sources */, 1410 0FFF19DC1BB334EB00886D91 /* ParallelHelperPool.cpp in Sources */, 1395 1411 1469419916EAB0410024E146 /* SchedulePairCF.cpp in Sources */, 1396 1412 1469419716EAAFF80024E146 /* SchedulePairMac.mm in Sources */, -
trunk/Source/WTF/wtf/CMakeLists.txt
r188677 r190267 83 83 RunLoop.h 84 84 SHA1.h 85 SharedTask.h 85 86 SaturatedArithmetic.h 86 87 SegmentedVector.h … … 168 169 OSRandomSource.cpp 169 170 PageBlock.cpp 171 ParallelHelperPool.cpp 170 172 ParallelJobsGeneric.cpp 171 173 ParkingLot.cpp -
trunk/Source/WTF/wtf/WeakRandom.h
r190151 r190267 1 1 /* 2 * Copyright (C) 2009 Apple Inc. All rights reserved.2 * Copyright (C) 2009, 2015 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 52 52 53 53 #include <limits.h> 54 #include <wtf/RandomNumber.h> 54 55 #include <wtf/StdLibExtras.h> 55 56 56 namespace JSC{57 namespace WTF { 57 58 58 59 class WeakRandom { 59 friend class JSGlobalObject; // For access to initializeSeed() during replay.60 60 public: 61 WeakRandom() 62 { 63 initializeSeed(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)); 64 } 65 61 66 WeakRandom(unsigned seed) 62 67 { … … 64 69 } 65 70 71 void initializeSeed(unsigned seed) 72 { 73 m_low = seed ^ 0x49616E42; 74 m_high = seed; 75 } 76 66 77 // Returns the seed provided that you've never called get() or getUint32(). 67 78 unsigned seedUnsafe() const { return m_high; } … … 77 88 } 78 89 90 unsigned getUint32(unsigned limit) 91 { 92 if (limit <= 1) 93 return 0; 94 uint64_t cutoff = (static_cast<uint64_t>(UINT_MAX) + 1) / limit * limit; 95 for (;;) { 96 uint64_t value = getUint32(); 97 if (value >= cutoff) 98 continue; 99 return value % limit; 100 } 101 } 102 79 103 private: 80 104 unsigned advance() … … 86 110 } 87 111 88 void initializeSeed(unsigned seed)89 {90 m_low = seed ^ 0x49616E42;91 m_high = seed;92 }93 94 112 unsigned m_low; 95 113 unsigned m_high; 96 114 }; 97 115 98 } // namespace JSC 116 } // namespace WTF 117 118 using WTF::WeakRandom; 99 119 100 120 #endif // WeakRandom_h
Note: See TracChangeset
for help on using the changeset viewer.