Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / heap / ThreadState.h
index a814ec3..8b22a5b 100644 (file)
 #ifndef ThreadState_h
 #define ThreadState_h
 
+#include "heap/AddressSanitizer.h"
 #include "heap/HeapExport.h"
 #include "wtf/HashSet.h"
+#include "wtf/OwnPtr.h"
+#include "wtf/PassOwnPtr.h"
 #include "wtf/ThreadSpecific.h"
 #include "wtf/Threading.h"
+#include "wtf/ThreadingPrimitives.h"
 #include "wtf/Vector.h"
 
 namespace WebCore {
@@ -191,6 +195,7 @@ private:
 };
 
 class HEAP_EXPORT ThreadState {
+    WTF_MAKE_NONCOPYABLE(ThreadState);
 public:
     // When garbage collecting we need to know whether or not there
     // can be pointers to Blink GC managed objects on the stack for
@@ -219,6 +224,15 @@ public:
     // It also has to periodically check for safepoints.
     static void attach();
 
+    // When ThreadState is detaching from non-main thread its
+    // heap is expected to be empty (because it is going away).
+    // Perform registered cleanup tasks and garbage collection
+    // to sweep away any objects that are left on this heap.
+    // We assert that nothing must remain after this cleanup.
+    // If assertion does not hold we crash as we are potentially
+    // in the dangling pointer situation.
+    void cleanup();
+
     // Disassociate attached ThreadState from the current thread. The thread
     // can no longer use the garbage collected heap after this call.
     static void detach();
@@ -371,7 +385,7 @@ public:
     // can provide an interruptor object which would allow GC
     // to temporarily interrupt and pause this long running loop at
     // an arbitrary moment creating a safepoint for a GC.
-    class Interruptor {
+    class HEAP_EXPORT Interruptor {
     public:
         virtual ~Interruptor() { }
 
@@ -392,6 +406,24 @@ public:
     void addInterruptor(Interruptor*);
     void removeInterruptor(Interruptor*);
 
+    // CleanupTasks are executed when ThreadState performs
+    // cleanup before detaching.
+    class CleanupTask {
+    public:
+        virtual ~CleanupTask() { }
+
+        // Executed before the final GC.
+        virtual void preCleanup() { }
+
+        // Executed after the final GC. Thread heap is empty at this point.
+        virtual void postCleanup() { }
+    };
+
+    void addCleanupTask(PassOwnPtr<CleanupTask> cleanupTask)
+    {
+        m_cleanupTasks.append(cleanupTask);
+    }
+
     // Should only be called under protection of threadAttachMutex().
     const Vector<Interruptor*>& interruptors() const { return m_interruptors; }
 
@@ -422,6 +454,11 @@ public:
     // List of persistent roots allocated on the given thread.
     PersistentNode* roots() const { return m_persistents; }
 
+    // List of global persistent roots not owned by any particular thread.
+    // globalRootsMutex must be acquired before any modifications.
+    static PersistentNode* globalRoots();
+    static Mutex& globalRootsMutex();
+
     // Visit local thread stack and trace all pointers conservatively.
     void visitStack(Visitor*);
 
@@ -443,7 +480,7 @@ private:
     friend class SafePointBarrier;
 
     void enterSafePoint(StackState, void*);
-    void copyStackUntilSafePointScope();
+    NO_SANITIZE_ADDRESS void copyStackUntilSafePointScope();
     void clearSafePointScopeMarker()
     {
         m_safePointStackCopy.clear();
@@ -486,6 +523,9 @@ private:
     HeapContainsCache* m_heapContainsCache;
     HeapStats m_stats;
     HeapStats m_statsAfterLastGC;
+
+    Vector<OwnPtr<CleanupTask> > m_cleanupTasks;
+    bool m_isCleaningUp;
 };
 
 template<ThreadAffinity affinity> class ThreadStateFor;
@@ -505,6 +545,22 @@ public:
     static ThreadState* state() { return ThreadState::current(); }
 };
 
+// FIXME: Experiment if the threading affinity really matters for performance.
+// FIXME: Move these macros and other related structures to a separate file.
+USED_FROM_MULTIPLE_THREADS(Algorithm);
+USED_FROM_MULTIPLE_THREADS(Crypto);
+USED_FROM_MULTIPLE_THREADS(DeprecatedStorageQuota);
+USED_FROM_MULTIPLE_THREADS(Key);
+USED_FROM_MULTIPLE_THREADS(KeyPair);
+USED_FROM_MULTIPLE_THREADS(Notification);
+USED_FROM_MULTIPLE_THREADS(NotificationCenter);
+USED_FROM_MULTIPLE_THREADS(SubtleCrypto);
+USED_FROM_MULTIPLE_THREADS(TextDecoder);
+USED_FROM_MULTIPLE_THREADS(TextEncoder);
+USED_FROM_MULTIPLE_THREADS(WebKitNotification);
+USED_FROM_MULTIPLE_THREADS(WorkerCrypto);
+USED_FROM_MULTIPLE_THREADS(WorkerPerformance);
+
 }
 
 #endif // ThreadState_h