Ignore:
Timestamp:
Sep 10, 2012, 11:41:05 AM (13 years ago)
Author:
[email protected]
Message:

Combine MarkStack and SlotVisitor into single class
https://bugs.webkit.org/show_bug.cgi?id=96043

Reviewed by Geoff Garen.

Move all of MarkStack into SlotVisitor. The remaining stuff in MarkStack.cpp actually has to do
with MarkStack management/allocation. Cleaned up a few of the header files while I was at it.

  • CMakeLists.txt:
  • GNUmakefile.list.am:
  • JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • Target.pri:
  • bytecode/CodeBlock.cpp:
  • dfg/DFGCommon.h:
  • heap/GCThreadSharedData.cpp:
  • heap/GCThreadSharedData.h:

(GCThreadSharedData):

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

(JSC):

  • heap/MarkStack.h:

(JSC):
(MarkStackSegment):
(JSC::MarkStackSegment::data):
(JSC::MarkStackSegment::capacityFromSize):
(JSC::MarkStackSegment::sizeFromCapacity):
(MarkStackSegmentAllocator):
(MarkStackArray):

  • heap/MarkStackInlineMethods.h:

(JSC::MarkStackArray::postIncTop):
(JSC):
(JSC::MarkStackArray::preDecTop):
(JSC::MarkStackArray::setTopForFullSegment):
(JSC::MarkStackArray::setTopForEmptySegment):
(JSC::MarkStackArray::top):
(JSC::MarkStackArray::validatePrevious):
(JSC::MarkStackArray::append):
(JSC::MarkStackArray::canRemoveLast):
(JSC::MarkStackArray::removeLast):
(JSC::MarkStackArray::isEmpty):
(JSC::MarkStackArray::size):

  • heap/SlotVisitor.cpp: Added.

(JSC):
(JSC::SlotVisitor::SlotVisitor):
(JSC::SlotVisitor::~SlotVisitor):
(JSC::SlotVisitor::setup):
(JSC::SlotVisitor::reset):
(JSC::SlotVisitor::append):
(JSC::visitChildren):
(JSC::SlotVisitor::donateKnownParallel):
(JSC::SlotVisitor::drain):
(JSC::SlotVisitor::drainFromShared):
(JSC::SlotVisitor::mergeOpaqueRoots):
(JSC::SlotVisitor::startCopying):
(JSC::SlotVisitor::allocateNewSpaceSlow):
(JSC::SlotVisitor::allocateNewSpaceOrPin):
(JSC::JSString::tryHashConstLock):
(JSC::JSString::releaseHashConstLock):
(JSC::JSString::shouldTryHashConst):
(JSC::SlotVisitor::internalAppend):
(JSC::SlotVisitor::copyAndAppend):
(JSC::SlotVisitor::doneCopying):
(JSC::SlotVisitor::harvestWeakReferences):
(JSC::SlotVisitor::finalizeUnconditionalFinalizers):
(JSC::SlotVisitor::validate):

  • heap/SlotVisitor.h:

(JSC):
(SlotVisitor):
(JSC::SlotVisitor::sharedData):
(JSC::SlotVisitor::isEmpty):
(JSC::SlotVisitor::visitCount):
(JSC::SlotVisitor::resetChildCount):
(JSC::SlotVisitor::childCount):
(JSC::SlotVisitor::incrementChildCount):
(ParallelModeEnabler):
(JSC::ParallelModeEnabler::ParallelModeEnabler):
(JSC::ParallelModeEnabler::~ParallelModeEnabler):

  • heap/SlotVisitorInlineMethods.h:

(JSC::SlotVisitor::append):
(JSC):
(JSC::SlotVisitor::appendUnbarrieredPointer):
(JSC::SlotVisitor::appendUnbarrieredValue):
(JSC::SlotVisitor::internalAppend):
(JSC::SlotVisitor::addWeakReferenceHarvester):
(JSC::SlotVisitor::addUnconditionalFinalizer):
(JSC::SlotVisitor::addOpaqueRoot):
(JSC::SlotVisitor::containsOpaqueRoot):
(JSC::SlotVisitor::opaqueRootCount):
(JSC::SlotVisitor::mergeOpaqueRootsIfNecessary):
(JSC::SlotVisitor::mergeOpaqueRootsIfProfitable):
(JSC::SlotVisitor::donate):
(JSC::SlotVisitor::donateAndDrain):

  • jit/JITWriteBarrier.h:

(JSC::SlotVisitor::append):

  • jit/JumpReplacementWatchpoint.cpp:
  • runtime/JSCell.h:
  • runtime/Structure.h:

(JSC::SlotVisitor::internalAppend):

  • runtime/WriteBarrier.h:

(JSC):
(JSC::SlotVisitor::append):
(JSC::SlotVisitor::appendValues):

  • yarr/YarrJIT.cpp:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/heap/MarkStack.h

    r126354 r128084  
    2727#define MarkStack_h
    2828
    29 #include "CopiedSpace.h"
    30 #include "HandleTypes.h"
    31 #include "JSValue.h"
    32 #include "Options.h"
    33 #include "Register.h"
    34 #include "UnconditionalFinalizer.h"
    35 #include "VTableSpectrum.h"
    36 #include "WeakReferenceHarvester.h"
    37 #include <wtf/DataLog.h>
    38 #include <wtf/Forward.h>
    39 #include <wtf/HashMap.h>
    40 #include <wtf/HashSet.h>
    41 #include <wtf/Noncopyable.h>
    42 #include <wtf/OSAllocator.h>
    43 #include <wtf/PageBlock.h>
    44 #include <wtf/TCSpinLock.h>
    45 #include <wtf/text/StringHash.h>
    46 #include <wtf/Vector.h>
    47 
    4829#if ENABLE(OBJECT_MARK_LOGGING)
    4930#define MARK_LOG_MESSAGE0(message) dataLog(message)
     
    7051#endif
    7152
     53#include <wtf/StdLibExtras.h>
     54#include <wtf/TCSpinLock.h>
     55
    7256namespace JSC {
    7357
    74     class ConservativeRoots;
    75     class JSGlobalData;
    76     class MarkStack;
    77     class GCThreadSharedData;
    78     class ParallelModeEnabler;
    79     class Register;
    80     class SlotVisitor;
    81     template<typename T> class WriteBarrierBase;
    82     template<typename T> class JITWriteBarrier;
    83    
    84     struct MarkStackSegment {
    85         MarkStackSegment* m_previous;
     58class JSCell;
     59
     60struct MarkStackSegment {
     61    MarkStackSegment* m_previous;
    8662#if !ASSERT_DISABLED
    87         size_t m_top;
     63    size_t m_top;
    8864#endif
    8965       
    90         const JSCell** data()
    91         {
    92             return bitwise_cast<const JSCell**>(this + 1);
    93         }
    94        
    95         static size_t capacityFromSize(size_t size)
    96         {
    97             return (size - sizeof(MarkStackSegment)) / sizeof(const JSCell*);
    98         }
    99        
    100         static size_t sizeFromCapacity(size_t capacity)
    101         {
    102             return sizeof(MarkStackSegment) + capacity * sizeof(const JSCell*);
    103         }
    104     };
     66    const JSCell** data()
     67    {
     68        return bitwise_cast<const JSCell**>(this + 1);
     69    }
     70   
     71    static size_t capacityFromSize(size_t size)
     72    {
     73        return (size - sizeof(MarkStackSegment)) / sizeof(const JSCell*);
     74    }
     75   
     76    static size_t sizeFromCapacity(size_t capacity)
     77    {
     78        return sizeof(MarkStackSegment) + capacity * sizeof(const JSCell*);
     79    }
     80};
    10581
    106     class MarkStackSegmentAllocator {
    107     public:
    108         MarkStackSegmentAllocator();
    109         ~MarkStackSegmentAllocator();
    110        
    111         MarkStackSegment* allocate();
    112         void release(MarkStackSegment*);
    113        
    114         void shrinkReserve();
    115        
    116     private:
    117         SpinLock m_lock;
    118         MarkStackSegment* m_nextFreeSegment;
    119     };
     82class MarkStackSegmentAllocator {
     83public:
     84    MarkStackSegmentAllocator();
     85    ~MarkStackSegmentAllocator();
     86   
     87    MarkStackSegment* allocate();
     88    void release(MarkStackSegment*);
     89   
     90    void shrinkReserve();
     91   
     92private:
     93    SpinLock m_lock;
     94    MarkStackSegment* m_nextFreeSegment;
     95};
    12096
    121     class MarkStackArray {
    122     public:
    123         MarkStackArray(MarkStackSegmentAllocator&);
    124         ~MarkStackArray();
     97class MarkStackArray {
     98public:
     99    MarkStackArray(MarkStackSegmentAllocator&);
     100    ~MarkStackArray();
    125101
    126         void append(const JSCell*);
     102    void append(const JSCell*);
    127103
    128         bool canRemoveLast();
    129         const JSCell* removeLast();
    130         bool refill();
    131        
    132         bool isEmpty();
    133        
    134         void donateSomeCellsTo(MarkStackArray& other);
    135        
    136         void stealSomeCellsFrom(MarkStackArray& other, size_t idleThreadCount);
     104    bool canRemoveLast();
     105    const JSCell* removeLast();
     106    bool refill();
     107   
     108    void donateSomeCellsTo(MarkStackArray& other);
     109    void stealSomeCellsFrom(MarkStackArray& other, size_t idleThreadCount);
    137110
    138         size_t size();
     111    size_t size();
     112    bool isEmpty();
    139113
    140     private:
    141         MarkStackSegment* m_topSegment;
    142        
    143         JS_EXPORT_PRIVATE void expand();
    144        
    145         MarkStackSegmentAllocator& m_allocator;
     114private:
     115    JS_EXPORT_PRIVATE void expand();
     116   
     117    size_t postIncTop();
     118    size_t preDecTop();
     119    void setTopForFullSegment();
     120    void setTopForEmptySegment();
     121    size_t top();
     122   
     123    void validatePrevious();
    146124
    147         size_t m_segmentCapacity;
    148         size_t m_top;
    149         size_t m_numberOfPreviousSegments;
    150        
    151         size_t postIncTop()
    152         {
    153             size_t result = m_top++;
    154             ASSERT(result == m_topSegment->m_top++);
    155             return result;
    156         }
    157        
    158         size_t preDecTop()
    159         {
    160             size_t result = --m_top;
    161             ASSERT(result == --m_topSegment->m_top);
    162             return result;
    163         }
    164        
    165         void setTopForFullSegment()
    166         {
    167             ASSERT(m_topSegment->m_top == m_segmentCapacity);
    168             m_top = m_segmentCapacity;
    169         }
    170        
    171         void setTopForEmptySegment()
    172         {
    173             ASSERT(!m_topSegment->m_top);
    174             m_top = 0;
    175         }
    176        
    177         size_t top()
    178         {
    179             ASSERT(m_top == m_topSegment->m_top);
    180             return m_top;
    181         }
    182        
    183 #if ASSERT_DISABLED
    184         void validatePrevious() { }
    185 #else
    186         void validatePrevious()
    187         {
    188             unsigned count = 0;
    189             for (MarkStackSegment* current = m_topSegment->m_previous; current; current = current->m_previous)
    190                 count++;
    191             ASSERT(count == m_numberOfPreviousSegments);
    192         }
    193 #endif
    194     };
     125    MarkStackSegment* m_topSegment;
     126    MarkStackSegmentAllocator& m_allocator;
    195127
    196     class MarkStack {
    197         WTF_MAKE_NONCOPYABLE(MarkStack);
    198         friend class HeapRootVisitor; // Allowed to mark a JSValue* or JSCell** directly.
    199 
    200     public:
    201         MarkStack(GCThreadSharedData&);
    202         ~MarkStack();
    203 
    204         void append(ConservativeRoots&);
    205        
    206         template<typename T> void append(JITWriteBarrier<T>*);
    207         template<typename T> void append(WriteBarrierBase<T>*);
    208         void appendValues(WriteBarrierBase<Unknown>*, size_t count);
    209        
    210         template<typename T>
    211         void appendUnbarrieredPointer(T**);
    212         void appendUnbarrieredValue(JSValue*);
    213        
    214         void addOpaqueRoot(void*);
    215         bool containsOpaqueRoot(void*);
    216         int opaqueRootCount();
    217 
    218         GCThreadSharedData& sharedData() { return m_shared; }
    219         bool isEmpty() { return m_stack.isEmpty(); }
    220 
    221         void setup();
    222         void reset();
    223 
    224         size_t visitCount() const { return m_visitCount; }
    225 
    226 #if ENABLE(SIMPLE_HEAP_PROFILING)
    227         VTableSpectrum m_visitedTypeCounts;
    228 #endif
    229 
    230         void addWeakReferenceHarvester(WeakReferenceHarvester*);
    231         void addUnconditionalFinalizer(UnconditionalFinalizer*);
    232 
    233 #if ENABLE(OBJECT_MARK_LOGGING)
    234         inline void resetChildCount() { m_logChildCount = 0; }
    235         inline unsigned childCount() { return m_logChildCount; }
    236         inline void incrementChildCount() { m_logChildCount++; }
    237 #endif
    238 
    239     protected:
    240         JS_EXPORT_PRIVATE static void validate(JSCell*);
    241 
    242         void append(JSValue*);
    243         void append(JSValue*, size_t count);
    244         void append(JSCell**);
    245 
    246         void internalAppend(JSCell*);
    247         void internalAppend(JSValue);
    248         void internalAppend(JSValue*);
    249        
    250         JS_EXPORT_PRIVATE void mergeOpaqueRoots();
    251        
    252         void mergeOpaqueRootsIfNecessary()
    253         {
    254             if (m_opaqueRoots.isEmpty())
    255                 return;
    256             mergeOpaqueRoots();
    257         }
    258        
    259         void mergeOpaqueRootsIfProfitable()
    260         {
    261             if (static_cast<unsigned>(m_opaqueRoots.size()) < Options::opaqueRootMergeThreshold())
    262                 return;
    263             mergeOpaqueRoots();
    264         }
    265        
    266         MarkStackArray m_stack;
    267         HashSet<void*> m_opaqueRoots; // Handle-owning data structures not visible to the garbage collector.
    268        
    269 #if !ASSERT_DISABLED
    270     public:
    271         bool m_isCheckingForDefaultMarkViolation;
    272         bool m_isDraining;
    273 #endif
    274     protected:
    275         friend class ParallelModeEnabler;
    276        
    277         size_t m_visitCount;
    278         bool m_isInParallelMode;
    279        
    280         GCThreadSharedData& m_shared;
    281 
    282         bool m_shouldHashConst; // Local per-thread copy of shared flag for performance reasons
    283         typedef HashMap<StringImpl*, JSValue> UniqueStringMap;
    284         UniqueStringMap m_uniqueStrings;
    285 
    286 #if ENABLE(OBJECT_MARK_LOGGING)
    287         unsigned m_logChildCount;
    288 #endif
    289     };
    290 
    291     inline void MarkStackArray::append(const JSCell* cell)
    292     {
    293         if (m_top == m_segmentCapacity)
    294             expand();
    295         m_topSegment->data()[postIncTop()] = cell;
    296     }
    297 
    298     inline bool MarkStackArray::canRemoveLast()
    299     {
    300         return !!m_top;
    301     }
    302 
    303     inline const JSCell* MarkStackArray::removeLast()
    304     {
    305         return m_topSegment->data()[preDecTop()];
    306     }
    307 
    308     inline bool MarkStackArray::isEmpty()
    309     {
    310         if (m_top)
    311             return false;
    312         if (m_topSegment->m_previous) {
    313             ASSERT(m_topSegment->m_previous->m_top == m_segmentCapacity);
    314             return false;
    315         }
    316         return true;
    317     }
    318 
    319     inline size_t MarkStackArray::size()
    320     {
    321         return m_top + m_segmentCapacity * m_numberOfPreviousSegments;
    322     }
    323 
    324     class ParallelModeEnabler {
    325     public:
    326         ParallelModeEnabler(MarkStack& stack)
    327             : m_stack(stack)
    328         {
    329             ASSERT(!m_stack.m_isInParallelMode);
    330             m_stack.m_isInParallelMode = true;
    331         }
    332        
    333         ~ParallelModeEnabler()
    334         {
    335             ASSERT(m_stack.m_isInParallelMode);
    336             m_stack.m_isInParallelMode = false;
    337         }
    338        
    339     private:
    340         MarkStack& m_stack;
    341     };
     128    size_t m_segmentCapacity;
     129    size_t m_top;
     130    size_t m_numberOfPreviousSegments;
     131   
     132};
    342133
    343134} // namespace JSC
Note: See TracChangeset for help on using the changeset viewer.