From 793537d21f8aa46458a5733d96816ba8bddeef50 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Tue, 12 Jun 2012 00:21:31 +0000 Subject: [PATCH] For llvm::sys::ThreadLocalImpl instead of malloc'ing the platform-specific thread local data, embed them in the class using a uint64_t and make sure we get compiler errors if there's a platform where this is not big enough. This makes ThreadLocal more safe for using it in conjunction with CrashRecoveryContext. Related to crash in rdar://11434201. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@158342 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Support/ThreadLocal.h | 8 +++++++- lib/Support/ThreadLocal.cpp | 11 +++++------ lib/Support/Windows/ThreadLocal.inc | 13 ++++++------- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/include/llvm/Support/ThreadLocal.h b/include/llvm/Support/ThreadLocal.h index 15350a7afff..1a0a00fd515 100644 --- a/include/llvm/Support/ThreadLocal.h +++ b/include/llvm/Support/ThreadLocal.h @@ -15,6 +15,7 @@ #define LLVM_SYSTEM_THREAD_LOCAL_H #include "llvm/Support/Threading.h" +#include "llvm/Support/DataTypes.h" #include namespace llvm { @@ -22,7 +23,12 @@ namespace llvm { // ThreadLocalImpl - Common base class of all ThreadLocal instantiations. // YOU SHOULD NEVER USE THIS DIRECTLY. class ThreadLocalImpl { - void* data; + typedef uint64_t ThreadLocalDataTy; + /// \brief Platform-specific thread local data. + /// + /// This is embedded in the class and we avoid malloc'ing/free'ing it, + /// to make this class more safe for use along with CrashRecoveryContext. + ThreadLocalDataTy data; public: ThreadLocalImpl(); virtual ~ThreadLocalImpl(); diff --git a/lib/Support/ThreadLocal.cpp b/lib/Support/ThreadLocal.cpp index 08b12b658be..1030a2b97db 100644 --- a/lib/Support/ThreadLocal.cpp +++ b/lib/Support/ThreadLocal.cpp @@ -41,30 +41,29 @@ namespace llvm { using namespace sys; ThreadLocalImpl::ThreadLocalImpl() : data(0) { - pthread_key_t* key = new pthread_key_t; + typedef int SIZE_TOO_BIG[sizeof(pthread_key_t) <= sizeof(data) ? 1 : -1]; + pthread_key_t* key = reinterpret_cast(&data); int errorcode = pthread_key_create(key, NULL); assert(errorcode == 0); (void) errorcode; - data = (void*)key; } ThreadLocalImpl::~ThreadLocalImpl() { - pthread_key_t* key = static_cast(data); + pthread_key_t* key = reinterpret_cast(&data); int errorcode = pthread_key_delete(*key); assert(errorcode == 0); (void) errorcode; - delete key; } void ThreadLocalImpl::setInstance(const void* d) { - pthread_key_t* key = static_cast(data); + pthread_key_t* key = reinterpret_cast(&data); int errorcode = pthread_setspecific(*key, d); assert(errorcode == 0); (void) errorcode; } const void* ThreadLocalImpl::getInstance() { - pthread_key_t* key = static_cast(data); + pthread_key_t* key = reinterpret_cast(&data); return pthread_getspecific(*key); } diff --git a/lib/Support/Windows/ThreadLocal.inc b/lib/Support/Windows/ThreadLocal.inc index 512462d8900..99c6f4f63b3 100644 --- a/lib/Support/Windows/ThreadLocal.inc +++ b/lib/Support/Windows/ThreadLocal.inc @@ -22,26 +22,25 @@ namespace llvm { using namespace sys; -ThreadLocalImpl::ThreadLocalImpl() { - DWORD* tls = new DWORD; +ThreadLocalImpl::ThreadLocalImpl() : data(0) { + typedef int SIZE_TOO_BIG[sizeof(DWORD) <= sizeof(data) ? 1 : -1]; + DWORD* tls = reinterpret_cast(&data); *tls = TlsAlloc(); assert(*tls != TLS_OUT_OF_INDEXES); - data = tls; } ThreadLocalImpl::~ThreadLocalImpl() { - DWORD* tls = static_cast(data); + DWORD* tls = reinterpret_cast(&data); TlsFree(*tls); - delete tls; } const void* ThreadLocalImpl::getInstance() { - DWORD* tls = static_cast(data); + DWORD* tls = reinterpret_cast(&data); return TlsGetValue(*tls); } void ThreadLocalImpl::setInstance(const void* d){ - DWORD* tls = static_cast(data); + DWORD* tls = reinterpret_cast(&data); int errorcode = TlsSetValue(*tls, const_cast(d)); assert(errorcode != 0); (void)errorcode;