Commit 9cdee4f4 authored by Benoît Lizé's avatar Benoît Lizé Committed by V8 LUCI CQ

[base/platform] Simplify fast TLS on macOS

Since the TLS offset is constant across all supported OS releases, we
no longer need to adjust it, nor to read it at runtime. This also aligns
the code in V8 with what is done in Chromium.

Change-Id: I0f3c54da39a776406083c897de888f06c61852b8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3599481Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Benoit Lize <lizeb@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80106}
parent 4680c2df
......@@ -1130,47 +1130,7 @@ static pthread_key_t LocalKeyToPthreadKey(Thread::LocalStorageKey local_key) {
#endif
}
#ifdef V8_FAST_TLS_SUPPORTED
static std::atomic<bool> tls_base_offset_initialized{false};
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, nullptr, 0) != 0) {
FATAL("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, nullptr, 10));
// 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 V8_HOST_ARCH_IA32
kMacTlsBaseOffset = 0x48;
#else
kMacTlsBaseOffset = 0x60;
#endif
} else {
// 11.x.x (Lion) changed the offset.
kMacTlsBaseOffset = 0;
}
tls_base_offset_initialized.store(true, std::memory_order_release);
}
#if defined(V8_FAST_TLS_SUPPORTED) && defined(DEBUG)
static void CheckFastTls(Thread::LocalStorageKey key) {
void* expected = reinterpret_cast<void*>(0x1234CAFE);
......@@ -1182,30 +1142,20 @@ static void CheckFastTls(Thread::LocalStorageKey key) {
Thread::SetThreadLocal(key, nullptr);
}
#endif // V8_FAST_TLS_SUPPORTED
#endif // defined(V8_FAST_TLS_SUPPORTED) && defined(DEBUG)
Thread::LocalStorageKey Thread::CreateThreadLocalKey() {
#ifdef V8_FAST_TLS_SUPPORTED
bool check_fast_tls = false;
if (!tls_base_offset_initialized.load(std::memory_order_acquire)) {
check_fast_tls = true;
InitializeTlsBaseOffset();
}
#endif
pthread_key_t key;
int result = pthread_key_create(&key, nullptr);
DCHECK_EQ(0, result);
USE(result);
LocalStorageKey local_key = PthreadKeyToLocalKey(key);
#ifdef V8_FAST_TLS_SUPPORTED
// If we just initialized fast TLS support, make sure it works.
if (check_fast_tls) CheckFastTls(local_key);
#if defined(V8_FAST_TLS_SUPPORTED) && defined(DEBUG)
CheckFastTls(local_key);
#endif
return local_key;
}
void Thread::DeleteThreadLocalKey(LocalStorageKey key) {
pthread_key_t pthread_key = LocalKeyToPthreadKey(key);
int result = pthread_key_delete(pthread_key);
......
......@@ -71,9 +71,7 @@ namespace base {
#define V8_FAST_TLS_SUPPORTED 1
V8_INLINE intptr_t InternalGetExistingThreadLocal(intptr_t index);
inline intptr_t InternalGetExistingThreadLocal(intptr_t index) {
V8_INLINE intptr_t InternalGetExistingThreadLocal(intptr_t index) {
const intptr_t kTibInlineTlsOffset = 0xE10;
const intptr_t kTibExtraTlsOffset = 0xF94;
const intptr_t kMaxInlineSlots = 64;
......@@ -91,6 +89,8 @@ inline intptr_t InternalGetExistingThreadLocal(intptr_t index) {
(index - kMaxInlineSlots));
}
// Not possible on ARM64, the register holding the base pointer is not stable
// across major releases.
#elif defined(__APPLE__) && (V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64)
// tvOS simulator does not use intptr_t as TLS key.
......@@ -98,20 +98,14 @@ inline intptr_t InternalGetExistingThreadLocal(intptr_t index) {
#define V8_FAST_TLS_SUPPORTED 1
extern V8_BASE_EXPORT intptr_t kMacTlsBaseOffset;
V8_INLINE intptr_t InternalGetExistingThreadLocal(intptr_t index);
inline intptr_t InternalGetExistingThreadLocal(intptr_t index) {
V8_INLINE intptr_t InternalGetExistingThreadLocal(intptr_t index) {
intptr_t result;
#if V8_HOST_ARCH_IA32
asm("movl %%gs:(%1,%2,4), %0;"
:"=r"(result) // Output must be a writable register.
:"r"(kMacTlsBaseOffset), "r"(index));
asm("movl %%gs:(,%1,4), %0;"
: "=r"(result) // Output must be a writable register.
: "r"(index));
#else
asm("movq %%gs:(%1,%2,8), %0;"
:"=r"(result)
:"r"(kMacTlsBaseOffset), "r"(index));
asm("movq %%gs:(,%1,8), %0;" : "=r"(result) : "r"(index));
#endif
return result;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment