]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - heap/SlotVisitor.h
JavaScriptCore-1218.tar.gz
[apple/javascriptcore.git] / heap / SlotVisitor.h
index 01eb219fc237b007d8604045760c9eddccdcba7e..e1808faf03c3d526e1bbf43f37f8149aed842789 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #ifndef SlotVisitor_h
 #define SlotVisitor_h
 
-#include "CopiedSpace.h"
-#include "MarkStack.h"
+#include "HandleTypes.h"
+#include "MarkStackInlines.h"
+
+#include <wtf/text/StringHash.h>
 
 namespace JSC {
 
+class ConservativeRoots;
+class GCThreadSharedData;
 class Heap;
+template<typename T> class Weak;
+template<typename T> class WriteBarrierBase;
+template<typename T> class JITWriteBarrier;
+
+class SlotVisitor {
+    WTF_MAKE_NONCOPYABLE(SlotVisitor);
+    friend class HeapRootVisitor; // Allowed to mark a JSValue* or JSCell** directly.
 
-class SlotVisitor : public MarkStack {
-    friend class HeapRootVisitor;
 public:
-    SlotVisitor(MarkStackThreadSharedData&);
+    SlotVisitor(GCThreadSharedData&);
+    ~SlotVisitor();
 
-    void donate()
-    {
-        ASSERT(m_isInParallelMode);
-        if (Options::numberOfGCMarkers == 1)
-            return;
-        
-        donateKnownParallel();
-    }
+    void append(ConservativeRoots&);
     
-    void drain();
+    template<typename T> void append(JITWriteBarrier<T>*);
+    template<typename T> void append(WriteBarrierBase<T>*);
+    void appendValues(WriteBarrierBase<Unknown>*, size_t count);
     
-    void donateAndDrain()
-    {
-        donate();
-        drain();
-    }
+    template<typename T>
+    void appendUnbarrieredPointer(T**);
+    void appendUnbarrieredValue(JSValue*);
+    template<typename T>
+    void appendUnbarrieredWeak(Weak<T>*);
+    
+    void addOpaqueRoot(void*);
+    bool containsOpaqueRoot(void*);
+    TriState containsOpaqueRootTriState(void*);
+    int opaqueRootCount();
+
+    GCThreadSharedData& sharedData() { return m_shared; }
+    bool isEmpty() { return m_stack.isEmpty(); }
+
+    void setup();
+    void reset();
+
+    size_t visitCount() const { return m_visitCount; }
+
+    void donate();
+    void drain();
+    void donateAndDrain();
     
     enum SharedDrainMode { SlaveDrain, MasterDrain };
     void drainFromShared(SharedDrainMode);
@@ -61,31 +83,82 @@ public:
     void harvestWeakReferences();
     void finalizeUnconditionalFinalizers();
 
-    void startCopying();
-    void copyAndAppend(void**, size_t, JSValue*, unsigned);
-    void doneCopying(); 
-        
+    void copyLater(JSCell*, void*, size_t);
+    
+#if ENABLE(SIMPLE_HEAP_PROFILING)
+    VTableSpectrum m_visitedTypeCounts;
+#endif
+
+    void addWeakReferenceHarvester(WeakReferenceHarvester*);
+    void addUnconditionalFinalizer(UnconditionalFinalizer*);
+
+#if ENABLE(OBJECT_MARK_LOGGING)
+    inline void resetChildCount() { m_logChildCount = 0; }
+    inline unsigned childCount() { return m_logChildCount; }
+    inline void incrementChildCount() { m_logChildCount++; }
+#endif
+
 private:
-    void* allocateNewSpace(void*, size_t);
+    friend class ParallelModeEnabler;
+    
+    JS_EXPORT_PRIVATE static void validate(JSCell*);
 
-    void donateSlow();
+    void append(JSValue*);
+    void append(JSValue*, size_t count);
+    void append(JSCell**);
+
+    void internalAppend(JSCell*);
+    void internalAppend(JSValue);
+    void internalAppend(JSValue*);
+    
+    JS_EXPORT_PRIVATE void mergeOpaqueRoots();
+    void mergeOpaqueRootsIfNecessary();
+    void mergeOpaqueRootsIfProfitable();
+    
+    void donateKnownParallel();
+
+    MarkStackArray m_stack;
+    HashSet<void*> m_opaqueRoots; // Handle-owning data structures not visible to the garbage collector.
+    
+    size_t m_visitCount;
+    bool m_isInParallelMode;
     
-    void donateKnownParallel()
+    GCThreadSharedData& m_shared;
+
+    bool m_shouldHashCons; // Local per-thread copy of shared flag for performance reasons
+    typedef HashMap<StringImpl*, JSValue> UniqueStringMap;
+    UniqueStringMap m_uniqueStrings;
+
+#if ENABLE(OBJECT_MARK_LOGGING)
+    unsigned m_logChildCount;
+#endif
+
+public:
+#if !ASSERT_DISABLED
+    bool m_isCheckingForDefaultMarkViolation;
+    bool m_isDraining;
+#endif
+};
+
+class ParallelModeEnabler {
+public:
+    ParallelModeEnabler(SlotVisitor& stack)
+        : m_stack(stack)
+    {
+        ASSERT(!m_stack.m_isInParallelMode);
+        m_stack.m_isInParallelMode = true;
+    }
+    
+    ~ParallelModeEnabler()
     {
-        if (!m_stack.canDonateSomeCells())
-            return;
-        donateSlow();
+        ASSERT(m_stack.m_isInParallelMode);
+        m_stack.m_isInParallelMode = false;
     }
     
-    CopiedBlock* m_copyBlock;
+private:
+    SlotVisitor& m_stack;
 };
 
-inline SlotVisitor::SlotVisitor(MarkStackThreadSharedData& shared)
-    : MarkStack(shared)
-    , m_copyBlock(0)
-{
-}
-
 } // namespace JSC
 
 #endif // SlotVisitor_h