Skip to content

[libc++abi] Always use thread_local for cxa_exception_storage #79868

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 1 addition & 63 deletions libcxxabi/src/cxa_exception_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@

#include "cxa_exception.h"

#include <__thread/support.h>

#if defined(_LIBCXXABI_HAS_NO_THREADS)

namespace __cxxabiv1 {
Expand All @@ -24,7 +22,7 @@ extern "C" {
} // extern "C"
} // namespace __cxxabiv1

#elif defined(HAS_THREAD_LOCAL)
#else

namespace __cxxabiv1 {
namespace {
Expand All @@ -40,64 +38,4 @@ extern "C" {
} // extern "C"
} // namespace __cxxabiv1

#else

#include "abort_message.h"
#include "fallback_malloc.h"

#if defined(__ELF__) && defined(_LIBCXXABI_LINK_PTHREAD_LIB)
#pragma comment(lib, "pthread")
#endif

// In general, we treat all threading errors as fatal.
// We cannot call std::terminate() because that will in turn
// call __cxa_get_globals() and cause infinite recursion.

namespace __cxxabiv1 {
namespace {
std::__libcpp_tls_key key_;
std::__libcpp_exec_once_flag flag_ = _LIBCPP_EXEC_ONCE_INITIALIZER;

void _LIBCPP_TLS_DESTRUCTOR_CC destruct_(void *p) {
__free_with_fallback(p);
if (0 != std::__libcpp_tls_set(key_, NULL))
abort_message("cannot zero out thread value for __cxa_get_globals()");
}

void construct_() {
if (0 != std::__libcpp_tls_create(&key_, destruct_))
abort_message("cannot create thread specific key for __cxa_get_globals()");
}
} // namespace

extern "C" {
__cxa_eh_globals *__cxa_get_globals() {
// Try to get the globals for this thread
__cxa_eh_globals *retVal = __cxa_get_globals_fast();

// If this is the first time we've been asked for these globals, create them
if (NULL == retVal) {
retVal = static_cast<__cxa_eh_globals*>(
__calloc_with_fallback(1, sizeof(__cxa_eh_globals)));
if (NULL == retVal)
abort_message("cannot allocate __cxa_eh_globals");
if (0 != std::__libcpp_tls_set(key_, retVal))
abort_message("std::__libcpp_tls_set failure in __cxa_get_globals()");
}
return retVal;
}

// Note that this implementation will reliably return NULL if not
// preceded by a call to __cxa_get_globals(). This is an extension
// to the Itanium ABI and is taken advantage of in several places in
// libc++abi.
__cxa_eh_globals *__cxa_get_globals_fast() {
// First time through, create the key.
if (0 != std::__libcpp_execute_once(&flag_, construct_))
abort_message("execute once failure in __cxa_get_globals_fast()");
return static_cast<__cxa_eh_globals*>(std::__libcpp_tls_get(key_));
}
} // extern "C"
} // namespace __cxxabiv1

#endif
11 changes: 0 additions & 11 deletions libcxxabi/src/fallback_malloc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,17 +271,6 @@ void* __aligned_malloc_with_fallback(size_t size) {
return fallback_malloc(size);
}

void* __calloc_with_fallback(size_t count, size_t size) {
void* ptr = ::calloc(count, size);
if (NULL != ptr)
return ptr;
// if calloc fails, fall back to emergency stash
ptr = fallback_malloc(size * count);
if (NULL != ptr)
::memset(ptr, 0, size * count);
return ptr;
}

void __aligned_free_with_fallback(void* ptr) {
if (is_fallback_ptr(ptr))
fallback_free(ptr);
Expand Down
3 changes: 0 additions & 3 deletions libcxxabi/src/fallback_malloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ namespace __cxxabiv1 {
// Allocate some memory from _somewhere_
_LIBCXXABI_HIDDEN void * __aligned_malloc_with_fallback(size_t size);

// Allocate and zero-initialize memory from _somewhere_
_LIBCXXABI_HIDDEN void * __calloc_with_fallback(size_t count, size_t size);

_LIBCXXABI_HIDDEN void __aligned_free_with_fallback(void *ptr);
_LIBCXXABI_HIDDEN void __free_with_fallback(void *ptr);

Expand Down
Loading