Revision: 7488
Author:   [email protected]
Date:     Sun Apr  3 22:46:51 2011
Log:      Fix fast TLS support on Mac.

Review URL: http://codereview.chromium.org/6706018
http://code.google.com/p/v8/source/detail?r=7488

Modified:
 /branches/bleeding_edge/src/platform-macos.cc
 /branches/bleeding_edge/src/platform-tls-mac.h

=======================================
--- /branches/bleeding_edge/src/platform-macos.cc       Mon Mar 21 10:40:40 2011
+++ /branches/bleeding_edge/src/platform-macos.cc       Sun Apr  3 22:46:51 2011
@@ -48,8 +48,10 @@
 #include <sys/time.h>
 #include <sys/resource.h>
 #include <sys/types.h>
+#include <sys/sysctl.h>
 #include <stdarg.h>
 #include <stdlib.h>
+#include <string.h>
 #include <errno.h>

 #undef MAP_TYPE
@@ -505,14 +507,81 @@
 void Thread::Join() {
   pthread_join(thread_handle_data()->thread_, NULL);
 }
+
+
+#ifdef V8_FAST_TLS_SUPPORTED
+
+static Atomic32 tls_base_offset_initialized = 0;
+intptr_t kMacTlsBaseOffset = 0;
+
+// It's safe to do the initialization more that once, but it has to be
+// done at least once.
+static void InitializeTlsBaseOffset() {
+  const size_t kBufferSize = 128;
+  char buffer[kBufferSize];
+  size_t buffer_size = kBufferSize;
+  int ctl_name[] = { CTL_KERN , KERN_OSRELEASE };
+  if (sysctl(ctl_name, 2, buffer, &buffer_size, NULL, 0) != 0) {
+    V8_Fatal(__FILE__, __LINE__, "V8 failed to get kernel version");
+  }
+  // The buffer now contains a string of the form XX.YY.ZZ, where
+  // XX is the major kernel version component.
+  // Make sure the buffer is 0-terminated.
+  buffer[kBufferSize - 1] = '\0';
+  char* period_pos = strchr(buffer, '.');
+  *period_pos = '\0';
+  int kernel_version_major =
+      static_cast<int>(strtol(buffer, NULL, 10));  // NOLINT
+  // The constants below are taken from pthreads.s from the XNU kernel
+  // sources archive at www.opensource.apple.com.
+  if (kernel_version_major < 11) {
+    // 8.x.x (Tiger), 9.x.x (Leopard), 10.x.x (Snow Leopard) have the
+    // same offsets.
+#if defined(V8_HOST_ARCH_IA32)
+    kMacTlsBaseOffset = 0x48;
+#else
+    kMacTlsBaseOffset = 0x60;
+#endif
+  } else {
+    // 11.x.x (Lion) changed the offset.
+    kMacTlsBaseOffset = 0;
+  }
+
+  Release_Store(&tls_base_offset_initialized, 1);
+}
+
+static void CheckFastTls(Thread::LocalStorageKey key) {
+  void* expected = reinterpret_cast<void*>(0x1234CAFE);
+  Thread::SetThreadLocal(key, expected);
+  void* actual = Thread::GetExistingThreadLocal(key);
+  if (expected != actual) {
+    V8_Fatal(__FILE__, __LINE__,
+             "V8 failed to initialize fast TLS on current kernel");
+  }
+  Thread::SetThreadLocal(key, NULL);
+}
+
+#endif  // V8_FAST_TLS_SUPPORTED


 Thread::LocalStorageKey Thread::CreateThreadLocalKey() {
+#ifdef V8_FAST_TLS_SUPPORTED
+  bool check_fast_tls = false;
+  if (tls_base_offset_initialized == 0) {
+    check_fast_tls = true;
+    InitializeTlsBaseOffset();
+  }
+#endif
   pthread_key_t key;
   int result = pthread_key_create(&key, NULL);
   USE(result);
   ASSERT(result == 0);
-  return static_cast<LocalStorageKey>(key);
+  LocalStorageKey typed_key = static_cast<LocalStorageKey>(key);
+#ifdef V8_FAST_TLS_SUPPORTED
+  // If we just initialized fast TLS support, make sure it works.
+  if (check_fast_tls) CheckFastTls(typed_key);
+#endif
+  return typed_key;
 }


=======================================
--- /branches/bleeding_edge/src/platform-tls-mac.h      Sun Mar 27 11:40:48 2011
+++ /branches/bleeding_edge/src/platform-tls-mac.h      Sun Apr  3 22:46:51 2011
@@ -37,20 +37,20 @@

 #define V8_FAST_TLS_SUPPORTED 1

+extern intptr_t kMacTlsBaseOffset;
+
 INLINE(intptr_t InternalGetExistingThreadLocal(intptr_t index));

 inline intptr_t InternalGetExistingThreadLocal(intptr_t index) {
-  // The constants below are taken from pthreads.s from the XNU kernel
-  // sources archive at www.opensource.apple.com.
   intptr_t result;
 #if defined(V8_HOST_ARCH_IA32)
-  asm("movl %%gs:0x48(,%1,4), %0;"
+  asm("movl %%gs:(%1,%2,4), %0;"
       :"=r"(result)  // Output must be a writable register.
-      :"0"(index));  // Input is the same as output.
+      :"r"(kMacTlsBaseOffset), "r"(index));
 #else
-  asm("movq %%gs:0x60(,%1,8), %0;"
+  asm("movq %%gs:(%1,%2,8), %0;"
       :"=r"(result)
-      :"0"(index));
+      :"r"(kMacTlsBaseOffset), "r"(index));
 #endif
   return result;
 }

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to