]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - runtime/JSLock.h
JavaScriptCore-7600.1.4.11.8.tar.gz
[apple/javascriptcore.git] / runtime / JSLock.h
index 8336a3a77be9147efa4bf73614aefa4c1b7182f9..f4a34eb6eb136fa47af1564064f25d8628df907c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2005, 2008, 2009, 2014 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
 #ifndef JSLock_h
 #define JSLock_h
 
+#include <mutex>
+#include <thread>
 #include <wtf/Assertions.h>
 #include <wtf/Noncopyable.h>
 #include <wtf/RefPtr.h>
-#include <wtf/TCSpinLock.h>
-#include <wtf/Threading.h>
+#include <wtf/ThreadSafeRefCounted.h>
+#include <wtf/WTFThreadData.h>
 
 namespace JSC {
 
@@ -49,32 +51,38 @@ namespace JSC {
     // thread acquired it to begin with.
 
     class ExecState;
-    class JSGlobalData;
+    class VM;
 
     // This class is used to protect the initialization of the legacy single 
-    // shared JSGlobalData.
+    // shared VM.
     class GlobalJSLock {
         WTF_MAKE_NONCOPYABLE(GlobalJSLock);
     public:
         JS_EXPORT_PRIVATE GlobalJSLock();
         JS_EXPORT_PRIVATE ~GlobalJSLock();
+
+        static void initialize();
+    private:
+        static std::mutex* s_sharedInstanceMutex;
     };
 
     class JSLockHolder {
     public:
-        JS_EXPORT_PRIVATE JSLockHolder(JSGlobalData*);
-        JS_EXPORT_PRIVATE JSLockHolder(JSGlobalData&);
+        JS_EXPORT_PRIVATE JSLockHolder(VM*);
+        JS_EXPORT_PRIVATE JSLockHolder(VM&);
         JS_EXPORT_PRIVATE JSLockHolder(ExecState*);
 
         JS_EXPORT_PRIVATE ~JSLockHolder();
     private:
-        RefPtr<JSGlobalData> m_globalData;
+        void init();
+
+        RefPtr<VM> m_vm;
     };
 
-    class JSLock {
+    class JSLock : public ThreadSafeRefCounted<JSLock> {
         WTF_MAKE_NONCOPYABLE(JSLock);
     public:
-        JSLock();
+        JSLock(VM*);
         JS_EXPORT_PRIVATE ~JSLock();
 
         JS_EXPORT_PRIVATE void lock();
@@ -82,36 +90,56 @@ namespace JSC {
 
         static void lock(ExecState*);
         static void unlock(ExecState*);
-        static void lock(JSGlobalData&);
-        static void unlock(JSGlobalData&);
-
+        static void lock(VM&);
+        static void unlock(VM&);
+
+        VM* vm() { return m_vm; }
+
+        bool hasExclusiveThread() const { return m_hasExclusiveThread; }
+        std::thread::id exclusiveThread() const
+        {
+            ASSERT(m_hasExclusiveThread);
+            return m_ownerThreadID;
+        }
+        JS_EXPORT_PRIVATE void setExclusiveThread(std::thread::id);
         JS_EXPORT_PRIVATE bool currentThreadIsHoldingLock();
 
-        unsigned dropAllLocks();
-        unsigned dropAllLocksUnconditionally();
-        void grabAllLocks(unsigned lockCount);
-
-        SpinLock m_spinLock;
-        Mutex m_lock;
-        ThreadIdentifier m_ownerThread;
-        intptr_t m_lockCount;
-        unsigned m_lockDropDepth;
+        void willDestroyVM(VM*);
 
         class DropAllLocks {
             WTF_MAKE_NONCOPYABLE(DropAllLocks);
         public:
-            // This is a hack to allow Mobile Safari to always release the locks since 
-            // hey depend on the behavior that DropAllLocks does indeed always drop all 
-            // locks, which isn't always the case with the default behavior.
-            enum AlwaysDropLocksTag { DontAlwaysDropLocks = 0, AlwaysDropLocks };
-            JS_EXPORT_PRIVATE DropAllLocks(ExecState* exec, AlwaysDropLocksTag alwaysDropLocks = DontAlwaysDropLocks);
-            JS_EXPORT_PRIVATE DropAllLocks(JSGlobalData*, AlwaysDropLocksTag alwaysDropLocks = DontAlwaysDropLocks);
+            JS_EXPORT_PRIVATE DropAllLocks(ExecState*);
+            JS_EXPORT_PRIVATE DropAllLocks(VM*);
+            JS_EXPORT_PRIVATE DropAllLocks(VM&);
             JS_EXPORT_PRIVATE ~DropAllLocks();
             
+            void setDropDepth(unsigned depth) { m_dropDepth = depth; }
+            unsigned dropDepth() const { return m_dropDepth; }
+
         private:
-            intptr_t m_lockCount;
-            RefPtr<JSGlobalData> m_globalData;
+            intptr_t m_droppedLockCount;
+            RefPtr<VM> m_vm;
+            unsigned m_dropDepth;
         };
+
+    private:
+        void lock(intptr_t lockCount);
+        void unlock(intptr_t unlockCount);
+
+        void didAcquireLock();
+        void willReleaseLock();
+
+        unsigned dropAllLocks(DropAllLocks*);
+        void grabAllLocks(DropAllLocks*, unsigned lockCount);
+
+        std::mutex m_lock;
+        std::thread::id m_ownerThreadID;
+        intptr_t m_lockCount;
+        unsigned m_lockDropDepth;
+        bool m_hasExclusiveThread;
+        VM* m_vm;
+        AtomicStringTable* m_entryAtomicStringTable; 
     };
 
 } // namespace