[libcxx-commits] [libcxxabi] bc91104 - Revert "[libcxxabi] Always use thread_local for cxa_exception_storage"
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Nov 24 05:32:47 PST 2022
Author: Louis Dionne
Date: 2022-11-24T08:32:10-05:00
New Revision: bc91104e85b7a233a8966998f387b2222f350f6e
URL: https://github.com/llvm/llvm-project/commit/bc91104e85b7a233a8966998f387b2222f350f6e
DIFF: https://github.com/llvm/llvm-project/commit/bc91104e85b7a233a8966998f387b2222f350f6e.diff
LOG: Revert "[libcxxabi] Always use thread_local for cxa_exception_storage"
This reverts commit 8271aa5335668a1dc62168a4e90b4554bd3a0ca7 since it
broke some downstream builds. See https://reviews.llvm.org/D138461 for
details.
Added:
Modified:
libcxxabi/src/cxa_exception_storage.cpp
libcxxabi/src/fallback_malloc.cpp
libcxxabi/src/fallback_malloc.h
Removed:
################################################################################
diff --git a/libcxxabi/src/cxa_exception_storage.cpp b/libcxxabi/src/cxa_exception_storage.cpp
index 1abf6143e59f7..3a3233a1b9272 100644
--- a/libcxxabi/src/cxa_exception_storage.cpp
+++ b/libcxxabi/src/cxa_exception_storage.cpp
@@ -12,18 +12,21 @@
#include "cxa_exception.h"
-namespace __cxxabiv1 {
+#include <__threading_support>
#if defined(_LIBCXXABI_HAS_NO_THREADS)
+namespace __cxxabiv1 {
extern "C" {
static __cxa_eh_globals eh_globals;
__cxa_eh_globals *__cxa_get_globals() { return &eh_globals; }
__cxa_eh_globals *__cxa_get_globals_fast() { return &eh_globals; }
} // extern "C"
+} // namespace __cxxabiv1
-#else
+#elif defined(HAS_THREAD_LOCAL)
+namespace __cxxabiv1 {
namespace {
__cxa_eh_globals *__globals() {
static thread_local __cxa_eh_globals eh_globals;
@@ -35,7 +38,66 @@ extern "C" {
__cxa_eh_globals *__cxa_get_globals() { return __globals(); }
__cxa_eh_globals *__cxa_get_globals_fast() { return __globals(); }
} // 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
diff --git a/libcxxabi/src/fallback_malloc.cpp b/libcxxabi/src/fallback_malloc.cpp
index 759bb58f7c308..591efbefc8a52 100644
--- a/libcxxabi/src/fallback_malloc.cpp
+++ b/libcxxabi/src/fallback_malloc.cpp
@@ -270,6 +270,17 @@ 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);
diff --git a/libcxxabi/src/fallback_malloc.h b/libcxxabi/src/fallback_malloc.h
index 528014b3456d8..816e691ed2313 100644
--- a/libcxxabi/src/fallback_malloc.h
+++ b/libcxxabi/src/fallback_malloc.h
@@ -17,6 +17,9 @@ 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);
More information about the libcxx-commits
mailing list