[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/+/3599481
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Commit-Queue: Benoit Lize <lizeb@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80106}
This commit is contained in:
Benoît Lizé 2022-04-22 11:05:15 +02:00 committed by V8 LUCI CQ
parent 4680c2df37
commit 9cdee4f418
2 changed files with 12 additions and 68 deletions

View File

@ -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);

View File

@ -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;
}