emitTLSLoad doesn't work on OSX with emulated TLS

- Provide a TLS solution that works on OSX with __emutls_*
Esse commit está contido em:
Sean Cannella
2013-07-08 00:22:35 -07:00
commit de Sara Golemon
commit ce9837db9a
2 arquivos alterados com 41 adições e 15 exclusões
+27 -11
Ver Arquivo
@@ -17,6 +17,11 @@
#define X64_UTIL_H_
#include "hphp/util/asm-x64.h"
#ifndef USE_GCC_FAST_TLS
#include <pthread.h>
#include "hphp/runtime/vm/jit/abi-x64.h"
#include "hphp/runtime/vm/jit/physreg.h"
#endif
#include "hphp/runtime/vm/jit/translator-inline.h"
namespace HPHP {
@@ -29,6 +34,8 @@ translator_not_reached(X64Assembler &a) {
}
}
#ifdef USE_GCC_FAST_TLS
/*
* TLS access: XXX we currently only support static-style TLS directly
* linked off of FS.
@@ -46,23 +53,32 @@ translator_not_reached(X64Assembler &a) {
*
* The virtual addresses of TLS data are not exposed to C/C++. To figure it
* out, we take a datum's linear address, and subtract it from the linear
* address where TLS starts. If you use the void* variant here, it's up to
* the programmer to ensure that it really is a TLS address.
* address where TLS starts.
*/
static inline void
emitTLSLoad(X64Assembler& a, const void* datum, RegNumber reg) {
uintptr_t virtualAddress = uintptr_t(datum) - tlsBase();
a. fs();
a. load_disp32_reg64(virtualAddress, reg);
}
//TODO(2525714) Will not work without USE_GCC_FAST_TLS being defined
template<typename T>
static inline void
emitTLSLoad(X64Assembler& a, const ThreadLocalNoCheck<T>& datum,
RegNumber reg) {
emitTLSLoad(a, &datum.m_node.m_p, reg);
uintptr_t virtualAddress = uintptr_t(&datum.m_node.m_p) - tlsBase();
a. fs();
a. load_disp32_reg64(virtualAddress, reg);
}
#else // USE_GCC_FAST_TLS
template<typename T>
static inline void
emitTLSLoad(X64Assembler& a, const ThreadLocalNoCheck<T>& datum,
RegNumber reg) {
PhysRegSaver(a, kGPCallerSaved); // we don't know for sure what's alive
a. emitImmReg(&datum.m_key, argNumToRegName[0]);
a. call((TCA)pthread_getspecific);
if (reg != reg::rax) {
a. mov_reg64_reg64(reg::rax, reg);
}
}
#endif // USE_GCC_FAST_TLS
} }
#endif
+14 -4
Ver Arquivo
@@ -31,12 +31,22 @@ namespace HPHP {
// Clang seems to have added this feature, or at the very least it is ignoring
// __thread keyword and compiling anyway
//
// On OSX, gcc does emulate TLS but in a manner that invalidates assumptions
// we have made about __thread and makes accessing thread-local variables in a
// JIT-friendly fashion difficult (as the compiler is doing a lot of magic that
// is not contractual or documented that we would need to duplicate in emitted
// code) so for now we're not going to use it. One possibility if we really
// want to do this is to generate functions that access variables of interest
// in ThreadLocal* (all of them are NoCheck right now) and use the bytes of
// gcc's compiled functions to find the values we would need to pass to
// __emutls_get_address.
//
// icc 13.0.0 appears to support it as well but we end up with
// assembler warnings of unknown importance about incorrect section
// types
#if !defined(NO_TLS) && \
((__llvm__ && __clang__) || \
#if !defined(NO_TLS) && !defined(__APPLE__) && \
((__llvm__ && __clang__) || \
__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 3) || \
__INTEL_COMPILER)
#define USE_GCC_FAST_TLS
@@ -65,7 +75,7 @@ inline void ThreadLocalCreateKey(pthread_key_t *key, void (*del)(void*)) {
/**
* A thread-local object is a "global" object within a thread. This is useful
* for writing apartment-threaded code, where nothing is actullay shared
* for writing apartment-threaded code, where nothing is actually shared
* between different threads (hence no locking) but those variables are not
* on stack in local scope. To use it, just do something like this,
*
@@ -426,7 +436,7 @@ public:
return *getNoCheck();
}
private:
public:
pthread_key_t m_key;
};