Make bmalloc::PerThread work without C++ thread local storage
authordbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 14 Aug 2014 05:00:22 +0000 (05:00 +0000)
committerdbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 14 Aug 2014 05:00:22 +0000 (05:00 +0000)
https://bugs.webkit.org/show_bug.cgi?id=135895

Reviewed by Geoffrey Garen.

Implement support for building bmalloc without C++ thread local storage.

* bmalloc/BPlatform.h: Remove macro define BPLATFORM_IOS_SIMULATOR. Added macro function
BCOMPILER_SUPPORTS() and macro define BCOMPILER_SUPPORTS_CXX_THREAD_LOCAL that can be used
to determine whether the compiler supports C++ thread local storage.
* bmalloc/PerThread.h:
(bmalloc::PerThreadStorage::get): Modified to call pthread_getspecific() when building
without C++ thread local storage.
(bmalloc::PerThreadStorage::initSharedKeyIfNeeded): Added.
(bmalloc::PerThreadStorage::init): Moved logic to initialize shared Pthread key from here to
PerThreadStorage::initSharedKeyIfNeeded().
(bmalloc::PerThread<T>::getFastCase): Modified to call PerThreadStorage::initSharedKeyIfNeeded()
before querying PerThreadStorage::get() when building without C++ thread local storage so as to
ensure that the shared key has been initialized.
(_pthread_setspecific_direct): Deleted.
(_pthread_getspecific_direct): Deleted.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@172576 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/bmalloc/ChangeLog
Source/bmalloc/bmalloc/BPlatform.h
Source/bmalloc/bmalloc/PerThread.h

index 04257c7..3bca8ce 100644 (file)
@@ -1,5 +1,29 @@
 2014-08-13  Daniel Bates  <dabates@apple.com>
 
+        Make bmalloc::PerThread work without C++ thread local storage
+        https://bugs.webkit.org/show_bug.cgi?id=135895
+
+        Reviewed by Geoffrey Garen.
+
+        Implement support for building bmalloc without C++ thread local storage.
+
+        * bmalloc/BPlatform.h: Remove macro define BPLATFORM_IOS_SIMULATOR. Added macro function
+        BCOMPILER_SUPPORTS() and macro define BCOMPILER_SUPPORTS_CXX_THREAD_LOCAL that can be used
+        to determine whether the compiler supports C++ thread local storage.
+        * bmalloc/PerThread.h:
+        (bmalloc::PerThreadStorage::get): Modified to call pthread_getspecific() when building
+        without C++ thread local storage.
+        (bmalloc::PerThreadStorage::initSharedKeyIfNeeded): Added.
+        (bmalloc::PerThreadStorage::init): Moved logic to initialize shared Pthread key from here to
+        PerThreadStorage::initSharedKeyIfNeeded().
+        (bmalloc::PerThread<T>::getFastCase): Modified to call PerThreadStorage::initSharedKeyIfNeeded()
+        before querying PerThreadStorage::get() when building without C++ thread local storage so as to
+        ensure that the shared key has been initialized.
+        (_pthread_setspecific_direct): Deleted.
+        (_pthread_getspecific_direct): Deleted.
+
+2014-08-13  Daniel Bates  <dabates@apple.com>
+
         [iOS] Make JavaScriptCore and bmalloc build with the public SDK
         https://bugs.webkit.org/show_bug.cgi?id=135848
 
index 746aa61..e387259 100644 (file)
@@ -38,8 +38,7 @@
 #define BPLATFORM_IOS 1
 #endif
 
-#if defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR
-#define BPLATFORM_IOS_SIMULATOR 1
-#endif
+#define BCOMPILER_SUPPORTS(COMPILER_FEATURE) (defined BCOMPILER_SUPPORTS_##COMPILER_FEATURE && BCOMPILER_SUPPORTS_##COMPILER_FEATURE)
+#define BCOMPILER_SUPPORTS_CXX_THREAD_LOCAL (defined(__has_feature) && __has_feature(cxx_thread_local))
 
 #endif // BPlatform_h
index 789f9f5..59fd51c 100644 (file)
 #include <pthread.h>
 #if defined(__has_include) && __has_include(<System/pthread_machdep.h>)
 #include <System/pthread_machdep.h>
-#elif BPLATFORM(IOS_SIMULATOR)
-// FIXME: We shouldn't hardcode this constant as it can become out-of-date with the macro define of the same
-// name in System/pthread_machdep.h. Instead, we should make PerThread work without C++ thread local storage.
-// See <https://bugs.webkit.org/show_bug.cgi?id=135895> for more details.
-const pthread_key_t __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY0 = 90;
-
-INLINE int _pthread_setspecific_direct(pthread_key_t key, const void* value) { return pthread_setspecific(key, value); }
-INLINE void* _pthread_getspecific_direct(pthread_key_t key) { return pthread_getspecific(key); }
-extern "C" int pthread_key_init_np(int, void (*destructor)(void*));
 #endif
 
 namespace bmalloc {
@@ -63,7 +54,7 @@ class Cache;
 
 template<typename T> struct PerThreadStorage;
 
-#if (defined(__has_include) && __has_include(<System/pthread_machdep.h>)) || BPLATFORM(IOS_SIMULATOR)
+#if defined(__has_include) && __has_include(<System/pthread_machdep.h>)
 // For now, we only support PerThread<Cache>. We can expand to other types by
 // using more keys.
 
@@ -80,30 +71,52 @@ template<> struct PerThreadStorage<Cache> {
 #else
 
 template<typename T> struct PerThreadStorage {
+#if BCOMPILER_SUPPORTS(CXX_THREAD_LOCAL)
     static __thread void* object;
+#endif
     static pthread_key_t key;
     static std::once_flag onceFlag;
 
-    static void* get() { return object; }
-    static void init(void* object, void (*destructor)(void*))
+    static void* get()
+    {
+#if BCOMPILER_SUPPORTS(CXX_THREAD_LOCAL)
+        return object;
+#else
+        return pthread_getspecific(key);
+#endif
+    }
+
+    static void initSharedKeyIfNeeded(void (*destructor)(void*))
     {
         std::call_once(onceFlag, [destructor]() {
             pthread_key_create(&key, destructor);
         });
+    }
+
+    static void init(void* object, void (*destructor)(void*))
+    {
+        initSharedKeyIfNeeded(destructor);
         pthread_setspecific(key, object);
+#if BCOMPILER_SUPPORTS(CXX_THREAD_LOCAL)
         PerThreadStorage<Cache>::object = object;
+#endif
     }
 };
 
+#if BCOMPILER_SUPPORTS(CXX_THREAD_LOCAL)
 template<typename T> __thread void* PerThreadStorage<T>::object;
+#endif
 template<typename T> pthread_key_t PerThreadStorage<T>::key;
 template<typename T> std::once_flag PerThreadStorage<T>::onceFlag;
 
-#endif // (defined(__has_include) && __has_include(<System/pthread_machdep.h>)) || BPLATFORM(IOS_SIMULATOR)
+#endif // defined(__has_include) && __has_include(<System/pthread_machdep.h>)
 
 template<typename T>
 INLINE T* PerThread<T>::getFastCase()
 {
+#if (!defined(__has_include) || !__has_include(<System/pthread_machdep.h>)) && !BCOMPILER_SUPPORTS(CXX_THREAD_LOCAL)
+    initSharedKeyIfNeeded(destructor);
+#endif
     return static_cast<T*>(PerThreadStorage<T>::get());
 }