Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / platform / heap / ThreadState.h
index d01986d..2513756 100644 (file)
@@ -33,6 +33,7 @@
 
 #include "platform/PlatformExport.h"
 #include "platform/heap/AddressSanitizer.h"
+#include "public/platform/WebThread.h"
 #include "wtf/HashSet.h"
 #include "wtf/OwnPtr.h"
 #include "wtf/PassOwnPtr.h"
@@ -55,6 +56,7 @@ class HeapContainsCache;
 class HeapObjectHeader;
 class PageMemory;
 class PersistentNode;
+class WrapperPersistentRegion;
 class Visitor;
 class SafePointBarrier;
 class SafePointAwareMutexLocker;
@@ -138,32 +140,76 @@ template<typename U> class ThreadingTrait<const U> : public ThreadingTrait<U> {
     H(Node)
 
 #define TypedHeapEnumName(Type) Type##Heap,
+#define TypedHeapEnumNameNonFinalized(Type) Type##HeapNonFinalized,
 
 enum TypedHeaps {
-    GeneralHeap,
+    GeneralHeap = 0,
+    CollectionBackingHeap,
     FOR_EACH_TYPED_HEAP(TypedHeapEnumName)
-    NumberOfHeaps
+    GeneralHeapNonFinalized,
+    CollectionBackingHeapNonFinalized,
+    FOR_EACH_TYPED_HEAP(TypedHeapEnumNameNonFinalized)
+    // Values used for iteration of heap segments.
+    NumberOfHeaps,
+    FirstFinalizedHeap = GeneralHeap,
+    FirstNonFinalizedHeap = GeneralHeapNonFinalized,
+    NumberOfFinalizedHeaps = GeneralHeapNonFinalized,
+    NumberOfNonFinalizedHeaps = NumberOfHeaps - NumberOfFinalizedHeaps,
+    NonFinalizedHeapOffset = FirstNonFinalizedHeap
 };
 
-// Trait to give an index in the thread state to all the
-// type-specialized heaps. The general heap is at index 0 in the
-// thread state. The index for other type-specialized heaps are given
-// by the TypedHeaps enum above.
-template<typename T>
-struct HeapTrait {
-    static const int index = GeneralHeap;
-    typedef ThreadHeap<FinalizedHeapObjectHeader> HeapType;
+// Base implementation for HeapIndexTrait found below.
+template<int heapIndex>
+struct HeapIndexTraitBase {
+    typedef FinalizedHeapObjectHeader HeaderType;
+    typedef ThreadHeap<HeaderType> HeapType;
+    static const int finalizedIndex = heapIndex;
+    static const int nonFinalizedIndex = heapIndex + static_cast<int>(NonFinalizedHeapOffset);
+    static int index(bool isFinalized)
+    {
+        return isFinalized ? finalizedIndex : nonFinalizedIndex;
+    }
 };
 
-#define DEFINE_HEAP_INDEX_TRAIT(Type)                  \
-    class Type;                                        \
-    template<>                                         \
-    struct HeapTrait<class Type> {                     \
-        static const int index = Type##Heap;           \
-        typedef ThreadHeap<HeapObjectHeader> HeapType; \
-    };
+// HeapIndexTrait defines properties for each heap in the TypesHeaps enum.
+template<int index>
+struct HeapIndexTrait;
+
+template<>
+struct HeapIndexTrait<GeneralHeap> : public HeapIndexTraitBase<GeneralHeap> { };
+template<>
+struct HeapIndexTrait<GeneralHeapNonFinalized> : public HeapIndexTrait<GeneralHeap> { };
+
+template<>
+struct HeapIndexTrait<CollectionBackingHeap> : public HeapIndexTraitBase<CollectionBackingHeap> { };
+template<>
+struct HeapIndexTrait<CollectionBackingHeapNonFinalized> : public HeapIndexTrait<CollectionBackingHeap> { };
+
+#define DEFINE_TYPED_HEAP_INDEX_TRAIT(Type)                                     \
+    template<>                                                                  \
+    struct HeapIndexTrait<Type##Heap> : public HeapIndexTraitBase<Type##Heap> { \
+        typedef HeapObjectHeader HeaderType;                                    \
+        typedef ThreadHeap<HeaderType> HeapType;                                \
+    };                                                                          \
+    template<>                                                                  \
+    struct HeapIndexTrait<Type##HeapNonFinalized> : public HeapIndexTrait<Type##Heap> { };
+FOR_EACH_TYPED_HEAP(DEFINE_TYPED_HEAP_INDEX_TRAIT)
+#undef DEFINE_TYPED_HEAP_INDEX_TRAIT
+
+// HeapTypeTrait defines which heap to use for particular types.
+// By default objects are allocated in the GeneralHeap.
+template<typename T>
+struct HeapTypeTrait : public HeapIndexTrait<GeneralHeap> { };
+
+// We don't have any type-based mappings to the CollectionBackingHeap.
 
-FOR_EACH_TYPED_HEAP(DEFINE_HEAP_INDEX_TRAIT)
+// Each typed-heap maps the respective type to its heap.
+#define DEFINE_TYPED_HEAP_TRAIT(Type)                                   \
+    class Type;                                                         \
+    template<>                                                          \
+    struct HeapTypeTrait<class Type> : public HeapIndexTrait<Type##Heap> { };
+FOR_EACH_TYPED_HEAP(DEFINE_TYPED_HEAP_TRAIT)
+#undef DEFINE_TYPED_HEAP_TRAIT
 
 // A HeapStats structure keeps track of the amount of memory allocated
 // for a Blink heap and how much of that memory is used for actual
@@ -171,6 +217,8 @@ FOR_EACH_TYPED_HEAP(DEFINE_HEAP_INDEX_TRAIT)
 // when to perform garbage collections.
 class HeapStats {
 public:
+    HeapStats() : m_totalObjectSpace(0), m_totalAllocatedSpace(0) { }
+
     size_t totalObjectSpace() const { return m_totalObjectSpace; }
     size_t totalAllocatedSpace() const { return m_totalAllocatedSpace; }
 
@@ -231,6 +279,28 @@ public:
         HeapPointersOnStack
     };
 
+    // When profiling we would like to identify forced GC requests.
+    enum CauseOfGC {
+        NormalGC,
+        ForcedGC
+    };
+
+    class NoSweepScope {
+    public:
+        explicit NoSweepScope(ThreadState* state) : m_state(state)
+        {
+            ASSERT(!m_state->m_sweepInProgress);
+            m_state->m_sweepInProgress = true;
+        }
+        ~NoSweepScope()
+        {
+            ASSERT(m_state->m_sweepInProgress);
+            m_state->m_sweepInProgress = false;
+        }
+    private:
+        ThreadState* m_state;
+    };
+
     // The set of ThreadStates for all threads attached to the Blink
     // garbage collector.
     typedef HashSet<ThreadState*> AttachedThreadStateSet;
@@ -313,16 +383,18 @@ public:
     void leaveNoAllocationScope() { m_noAllocationCount--; }
 
     // Before performing GC the thread-specific heap state should be
-    // made consistent for garbage collection.
-    bool isConsistentForGC();
-    void makeConsistentForGC();
+    // made consistent for sweeping.
+    void makeConsistentForSweeping();
+#if ENABLE(ASSERT)
+    bool isConsistentForSweeping();
+#endif
 
     // Is the thread corresponding to this thread state currently
     // performing GC?
     bool isInGC() const { return m_inGC; }
 
     // Is any of the threads registered with the blink garbage collection
-    // infrastructure currently perform GC?
+    // infrastructure currently performing GC?
     static bool isAnyThreadInGC() { return s_inGC; }
 
     void enterGC()
@@ -470,7 +542,7 @@ public:
     //
     // The heap is split into multiple heap parts based on object
     // types. To get the index for a given type, use
-    // HeapTrait<Type>::index.
+    // HeapTypeTrait<Type>::index.
     BaseHeap* heap(int index) const { return m_heaps[index]; }
 
     // Infrastructure to determine if an address is within one of the
@@ -481,6 +553,14 @@ public:
     BaseHeapPage* contains(void* pointer) { return contains(reinterpret_cast<Address>(pointer)); }
     BaseHeapPage* contains(const void* pointer) { return contains(const_cast<void*>(pointer)); }
 
+    WrapperPersistentRegion* wrapperRoots() const
+    {
+        ASSERT(m_liveWrapperPersistents);
+        return m_liveWrapperPersistents;
+    }
+    WrapperPersistentRegion* takeWrapperPersistentRegion();
+    void freeWrapperPersistentRegion(WrapperPersistentRegion*);
+
     // List of persistent roots allocated on the given thread.
     PersistentNode* roots() const { return m_persistents.get(); }
 
@@ -512,24 +592,24 @@ public:
     struct SnapshotInfo {
         ThreadState* state;
 
-        size_t liveSize;
-        size_t deadSize;
         size_t freeSize;
         size_t pageCount;
 
         // Map from base-classes to a snapshot class-ids (used as index below).
         HashMap<const GCInfo*, size_t> classTags;
 
-        // Map from class-id (index) to count.
+        // Map from class-id (index) to count/size.
         Vector<int> liveCount;
         Vector<int> deadCount;
+        Vector<size_t> liveSize;
+        Vector<size_t> deadSize;
 
         // Map from class-id (index) to a vector of generation counts.
         // For i < 7, the count is the number of objects that died after surviving |i| GCs.
         // For i == 7, the count is the number of objects that survived at least 7 GCs.
         Vector<Vector<int, 8> > generations;
 
-        explicit SnapshotInfo(ThreadState* state) : state(state), liveSize(0), deadSize(0), freeSize(0), pageCount(0) { }
+        explicit SnapshotInfo(ThreadState* state) : state(state), freeSize(0), pageCount(0) { }
 
         size_t getClassTag(const GCInfo*);
     };
@@ -546,6 +626,11 @@ public:
 
     void setupHeapsForTermination();
 
+    void registerSweepingTask();
+    void unregisterSweepingTask();
+
+    Mutex& sweepMutex() { return m_sweepMutex; }
+
 private:
     explicit ThreadState();
     ~ThreadState();
@@ -581,6 +666,8 @@ private:
 
     void setLowCollectionRate(bool value) { m_lowCollectionRate = value; }
 
+    void waitUntilSweepersDone();
+
     static WTF::ThreadSpecific<ThreadState*>* s_threadSpecific;
     static SafePointBarrier* s_safePointBarrier;
 
@@ -598,6 +685,9 @@ private:
     static uint8_t s_mainThreadStateStorage[];
 
     ThreadIdentifier m_thread;
+    WrapperPersistentRegion* m_liveWrapperPersistents;
+    WrapperPersistentRegion* m_pooledWrapperPersistents;
+    size_t m_pooledWrapperPersistentRegionCount;
     OwnPtr<PersistentNode> m_persistents;
     StackState m_stackState;
     intptr_t* m_startOfStack;
@@ -622,6 +712,11 @@ private:
 
     bool m_lowCollectionRate;
 
+    OwnPtr<blink::WebThread> m_sweeperThread;
+    int m_numberOfSweeperTasks;
+    Mutex m_sweepMutex;
+    ThreadCondition m_sweepThreadCondition;
+
     CallbackStack* m_weakCallbackStack;
 
 #if defined(ADDRESS_SANITIZER)
@@ -718,7 +813,7 @@ public:
     virtual void checkAndMarkPointer(Visitor*, Address) = 0;
     virtual bool contains(Address) = 0;
 
-#if ENABLE(GC_TRACING)
+#if ENABLE(GC_PROFILE_MARKING)
     virtual const GCInfo* findGCInfo(Address) = 0;
 #endif
 
@@ -739,6 +834,9 @@ public:
     void setTerminating() { m_terminating = true; }
     bool tracedAfterOrphaned() { return m_tracedAfterOrphaned; }
     void setTracedAfterOrphaned() { m_tracedAfterOrphaned = true; }
+    size_t promptlyFreedSize() { return m_promptlyFreedSize; }
+    void resetPromptlyFreedSize() { m_promptlyFreedSize = 0; }
+    void addToPromptlyFreedSize(size_t size) { m_promptlyFreedSize += size; }
 
 private:
     PageMemory* m_storage;
@@ -750,6 +848,7 @@ private:
     // if the page is traced after being terminated (orphaned).
     uintptr_t m_terminating : 1;
     uintptr_t m_tracedAfterOrphaned : 1;
+    uintptr_t m_promptlyFreedSize : 17; // == blinkPageSizeLog2
 };
 
 }