Ignore:
Timestamp:
Oct 31, 2011, 11:43:37 PM (14 years ago)
Author:
[email protected]
Message:

The GC should be parallel
https://bugs.webkit.org/show_bug.cgi?id=70995

Source/JavaScriptCore:

Reviewed by Geoff Garen.

Added parallel tracing to the GC. This works by having local mark
stacks per thread, and a global shared one. Threads sometimes
donate cells from the mark stack to the global one if the heuristics
tell them that it's affordable to do so. Threads that have depleted
their local mark stacks try to steal some from the shared one.

Marking is now done using an atomic weak relaxed CAS (compare-and-swap).

This is a 23% speed-up on V8-splay when I use 4 marking threads,
leading to a 3.5% speed-up on V8.

It also appears that this reduces GC pause times on real websites by
more than half.

(JSC::Heap::Heap):
(JSC::Heap::~Heap):
(JSC::Heap::markRoots):

  • heap/Heap.h:
  • heap/MarkStack.cpp:

(JSC::MarkStackSegmentAllocator::MarkStackSegmentAllocator):
(JSC::MarkStackSegmentAllocator::~MarkStackSegmentAllocator):
(JSC::MarkStackSegmentAllocator::allocate):
(JSC::MarkStackSegmentAllocator::release):
(JSC::MarkStackSegmentAllocator::shrinkReserve):
(JSC::MarkStackArray::MarkStackArray):
(JSC::MarkStackArray::~MarkStackArray):
(JSC::MarkStackArray::expand):
(JSC::MarkStackArray::refill):
(JSC::MarkStackArray::donateSomeCellsTo):
(JSC::MarkStackArray::stealSomeCellsFrom):
(JSC::MarkStackThreadSharedData::markingThreadMain):
(JSC::MarkStackThreadSharedData::markingThreadStartFunc):
(JSC::MarkStackThreadSharedData::MarkStackThreadSharedData):
(JSC::MarkStackThreadSharedData::~MarkStackThreadSharedData):
(JSC::MarkStackThreadSharedData::reset):
(JSC::MarkStack::reset):
(JSC::SlotVisitor::donateSlow):
(JSC::SlotVisitor::drain):
(JSC::SlotVisitor::drainFromShared):
(JSC::MarkStack::mergeOpaqueRoots):
(JSC::SlotVisitor::harvestWeakReferences):

  • heap/MarkStack.h:

(JSC::MarkStackSegment::data):
(JSC::MarkStackSegment::capacityFromSize):
(JSC::MarkStackSegment::sizeFromCapacity):
(JSC::MarkStackArray::postIncTop):
(JSC::MarkStackArray::preDecTop):
(JSC::MarkStackArray::setTopForFullSegment):
(JSC::MarkStackArray::setTopForEmptySegment):
(JSC::MarkStackArray::top):
(JSC::MarkStackArray::validatePrevious):
(JSC::MarkStack::addWeakReferenceHarvester):
(JSC::MarkStack::mergeOpaqueRootsIfNecessary):
(JSC::MarkStack::mergeOpaqueRootsIfProfitable):
(JSC::MarkStack::MarkStack):
(JSC::MarkStack::addOpaqueRoot):
(JSC::MarkStack::containsOpaqueRoot):
(JSC::MarkStack::opaqueRootCount):
(JSC::MarkStackArray::append):
(JSC::MarkStackArray::canRemoveLast):
(JSC::MarkStackArray::removeLast):
(JSC::MarkStackArray::isEmpty):
(JSC::MarkStackArray::canDonateSomeCells):
(JSC::MarkStackArray::size):
(JSC::ParallelModeEnabler::ParallelModeEnabler):
(JSC::ParallelModeEnabler::~ParallelModeEnabler):

  • heap/MarkedBlock.h:

(JSC::MarkedBlock::testAndSetMarked):

  • heap/SlotVisitor.h:

(JSC::SlotVisitor::donate):
(JSC::SlotVisitor::donateAndDrain):
(JSC::SlotVisitor::donateKnownParallel):
(JSC::SlotVisitor::SlotVisitor):

  • heap/WeakReferenceHarvester.h:
  • runtime/Heuristics.cpp:

(JSC::Heuristics::initializeHeuristics):

  • runtime/Heuristics.h:
  • wtf/Atomics.h:

(WTF::weakCompareAndSwap):

  • wtf/Bitmap.h:

(WTF::::Bitmap):
(WTF::::get):
(WTF::::set):
(WTF::::testAndSet):
(WTF::::testAndClear):
(WTF::::concurrentTestAndSet):
(WTF::::concurrentTestAndClear):
(WTF::::clear):
(WTF::::clearAll):
(WTF::::nextPossiblyUnset):
(WTF::::findRunOfZeros):
(WTF::::count):
(WTF::::isEmpty):
(WTF::::isFull):

  • wtf/MainThread.h:

(WTF::isMainThreadOrGCThread):

  • wtf/Platform.h:
  • wtf/ThreadSpecific.h:

(WTF::::isSet):

  • wtf/mac/MainThreadMac.mm:

(WTF::initializeGCThreads):
(WTF::initializeMainThreadPlatform):
(WTF::initializeMainThreadToProcessMainThreadPlatform):
(WTF::registerGCThread):
(WTF::isMainThreadOrGCThread):

Source/WebCore:

Reviewed by Geoff Garen.

Added parallel tracing to the GC. This required loosening some assertions,
since some code may now be called from outside the main thread.

No new tests, since no behavior was changed.

  • platform/TreeShared.h:

(WebCore::TreeShared::parent):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/wtf/Atomics.h

    r97557 r98937  
    6161
    6262#include "Platform.h"
     63#include "UnusedParam.h"
    6364
    6465#if OS(WINDOWS)
     
    117118#endif
    118119
     120inline bool weakCompareAndSwap(unsigned* location, unsigned expected, unsigned newValue)
     121{
     122    // FIXME: Implement COMPARE_AND_SWAP on other architectures and compilers. Currently
     123    // it only works on X86 or X86_64 with a GCC-style compiler.
     124#if ENABLE(COMPARE_AND_SWAP)
     125    bool result;
     126    asm volatile(
     127        "lock; cmpxchgl %3, %2\n\t"
     128        "sete %1"
     129        : "+a"(expected), "=r"(result), "+m"(*location)
     130        : "r"(newValue)
     131        : "memory"
     132        );
     133    return result;
     134#else
     135    UNUSED_PARAM(location);
     136    UNUSED_PARAM(expected);
     137    UNUSED_PARAM(newValue);
     138    CRASH();
     139    return 0;
     140#endif
     141}
     142
    119143} // namespace WTF
    120144
Note: See TracChangeset for help on using the changeset viewer.