Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/external/bsd/libc++/dist/libcxxrt/src Import libcxxrt revisi...
details: https://anonhg.NetBSD.org/src/rev/70b1572f46cf
branches: trunk
changeset: 795991:70b1572f46cf
user: joerg <joerg%NetBSD.org@localhost>
date: Thu May 15 23:56:01 2014 +0000
description:
Import libcxxrt revision 4eb349088dda15d2de9a8c7b144c3f2d5f390269.
Restore support for 32bit architectures without 64bit CAS.
Support DWARF exception handling on ARM.
diffstat:
external/bsd/libc++/dist/libcxxrt/src/cxxabi.h | 2 +-
external/bsd/libc++/dist/libcxxrt/src/exception.cc | 30 ++++--
external/bsd/libc++/dist/libcxxrt/src/guard.cc | 99 +++++++++++++++------
external/bsd/libc++/dist/libcxxrt/src/unwind.h | 2 +-
4 files changed, 92 insertions(+), 41 deletions(-)
diffs (299 lines):
diff -r 0c2a15e7fc22 -r 70b1572f46cf external/bsd/libc++/dist/libcxxrt/src/cxxabi.h
--- a/external/bsd/libc++/dist/libcxxrt/src/cxxabi.h Thu May 15 23:53:10 2014 +0000
+++ b/external/bsd/libc++/dist/libcxxrt/src/cxxabi.h Thu May 15 23:56:01 2014 +0000
@@ -110,7 +110,7 @@
* handler count reaches 0 (which it doesn't with the top bit set).
*/
int handlerCount;
-#ifdef __arm__
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
/**
* The ARM EH ABI requires the unwind library to keep track of exceptions
* during cleanups. These support nesting, so we need to keep a list of
diff -r 0c2a15e7fc22 -r 70b1572f46cf external/bsd/libc++/dist/libcxxrt/src/exception.cc
--- a/external/bsd/libc++/dist/libcxxrt/src/exception.cc Thu May 15 23:53:10 2014 +0000
+++ b/external/bsd/libc++/dist/libcxxrt/src/exception.cc Thu May 15 23:56:01 2014 +0000
@@ -71,7 +71,7 @@
int selector,
dw_eh_ptr_t landingPad)
{
-#ifdef __arm__
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
// On ARM, we store the saved exception in the generic part of the structure
ucb->barrier_cache.sp = _Unwind_GetGR(context, 13);
ucb->barrier_cache.bitpattern[1] = static_cast<uint32_t>(selector);
@@ -95,7 +95,7 @@
unsigned long *selector,
dw_eh_ptr_t *landingPad)
{
-#ifdef __arm__
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
*selector = ucb->barrier_cache.bitpattern[1];
*landingPad = reinterpret_cast<dw_eh_ptr_t>(ucb->barrier_cache.bitpattern[3]);
return 1;
@@ -113,7 +113,7 @@
static inline _Unwind_Reason_Code continueUnwinding(struct _Unwind_Exception *ex,
struct _Unwind_Context *context)
{
-#ifdef __arm__
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
if (__gnu_unwind_frame(ex, context) != _URC_OK) { return _URC_FAILURE; }
#endif
return _URC_CONTINUE_UNWIND;
@@ -204,7 +204,7 @@
terminate_handler terminateHandler;
__cxa_exception *nextException;
int handlerCount;
-#ifdef __arm__
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
_Unwind_Exception *nextCleanup;
int cleanupCount;
#endif
@@ -654,7 +654,7 @@
{
Dl_info myinfo;
int mylookup =
- dladdr(reinterpret_cast<const void *>(__cxa_current_exception_type), &myinfo);
+ dladdr(reinterpret_cast<void *>(__cxa_current_exception_type), &myinfo);
void *ip = reinterpret_cast<void*>(_Unwind_GetIP(context));
Dl_info info;
if (dladdr(ip, &info) != 0)
@@ -673,6 +673,11 @@
* If the failure happened by falling off the end of the stack without finding
* a handler, prints a back trace before aborting.
*/
+#if __GNUC__ > 3 && __GNUC_MINOR__ > 2
+extern "C" void *__cxa_begin_catch(void *e) throw();
+#else
+extern "C" void *__cxa_begin_catch(void *e);
+#endif
static void report_failure(_Unwind_Reason_Code err, __cxa_exception *thrown_exception)
{
switch (err)
@@ -681,12 +686,14 @@
case _URC_FATAL_PHASE1_ERROR:
fprintf(stderr, "Fatal error during phase 1 unwinding\n");
break;
-#ifndef __arm__
+#if !defined(__arm__) || defined(__ARM_DWARF_EH__)
case _URC_FATAL_PHASE2_ERROR:
fprintf(stderr, "Fatal error during phase 2 unwinding\n");
break;
#endif
case _URC_END_OF_STACK:
+ __cxa_begin_catch (&(thrown_exception->unwindHeader));
+ std::terminate();
fprintf(stderr, "Terminating due to uncaught exception %p",
static_cast<void*>(thrown_exception));
thrown_exception = realExceptionFromException(thrown_exception);
@@ -716,6 +723,9 @@
// Print a back trace if no handler is found.
// TODO: Make this optional
_Unwind_Backtrace(trace, 0);
+
+ // Just abort. No need to call std::terminate for the second time
+ abort();
break;
}
std::terminate();
@@ -972,7 +982,7 @@
{
bool matched = false;
*selector = filter;
-#ifdef __arm__
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
filter++;
std::type_info *handler_type = get_type_info_entry(context, lsda, filter--);
while (handler_type)
@@ -1017,7 +1027,7 @@
static void pushCleanupException(_Unwind_Exception *exceptionObject,
__cxa_exception *ex)
{
-#ifdef __arm__
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
__cxa_thread_info *info = thread_info_fast();
if (ex)
{
@@ -1062,7 +1072,7 @@
realEx = realExceptionFromException(ex);
}
-#ifdef __arm__
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
unsigned char *lsda_addr =
static_cast<unsigned char*>(_Unwind_GetLanguageSpecificData(context));
#else
@@ -1486,7 +1496,7 @@
return ATOMIC_LOAD(&terminateHandler);
}
}
-#ifdef __arm__
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
extern "C" _Unwind_Exception *__cxa_get_cleanup(void)
{
__cxa_thread_info *info = thread_info_fast();
diff -r 0c2a15e7fc22 -r 70b1572f46cf external/bsd/libc++/dist/libcxxrt/src/guard.cc
--- a/external/bsd/libc++/dist/libcxxrt/src/guard.cc Thu May 15 23:53:10 2014 +0000
+++ b/external/bsd/libc++/dist/libcxxrt/src/guard.cc Thu May 15 23:56:01 2014 +0000
@@ -70,10 +70,14 @@
#ifdef __arm__
// ARM ABI - 32-bit guards.
typedef uint32_t guard_t;
+typedef uint32_t guard_lock_t;
static const uint32_t LOCKED = static_cast<guard_t>(1) << 31;
static const uint32_t INITIALISED = 1;
-#else
+#define LOCK_PART(guard) (guard)
+#define INIT_PART(guard) (guard)
+#elif defined(_LP64)
typedef uint64_t guard_t;
+typedef uint64_t guard_lock_t;
# if defined(__LITTLE_ENDIAN__)
static const guard_t LOCKED = static_cast<guard_t>(1) << 63;
static const guard_t INITIALISED = 1;
@@ -81,7 +85,30 @@
static const guard_t LOCKED = 1;
static const guard_t INITIALISED = static_cast<guard_t>(1) << 56;
# endif
+#define LOCK_PART(guard) (guard)
+#define INIT_PART(guard) (guard)
+#else
+# if defined(__LITTLE_ENDIAN__)
+typedef struct {
+ uint32_t init_half;
+ uint32_t lock_half;
+} guard_t;
+typedef uint32_t guard_lock_t;
+static const uint32_t LOCKED = static_cast<guard_lock_t>(1) << 31;
+static const uint32_t INITIALISED = 1;
+# else
+typedef struct {
+ uint32_t init_half;
+ uint32_t lock_half;
+} guard_t;
+static_assert(sizeof(guard_t) == sizeof(uint64_t), "");
+static const uint32_t LOCKED = 1;
+static const uint32_t INITIALISED = static_cast<guard_lock_t>(1) << 24;
+# endif
+#define LOCK_PART(guard) (&(guard)->lock_half)
+#define INIT_PART(guard) (&(guard)->init_half)
#endif
+static const guard_lock_t INITIAL = 0;
/**
* Acquires a lock on a guard, returning 0 if the object has already been
@@ -90,42 +117,49 @@
*/
extern "C" int __cxa_guard_acquire(volatile guard_t *guard_object)
{
+ guard_lock_t old;
// Not an atomic read, doesn't establish a happens-before relationship, but
// if one is already established and we end up seeing an initialised state
// then it's a fast path, otherwise we'll do something more expensive than
// this test anyway...
- if ((INITIALISED == *guard_object)) { return 0; }
+ if (INITIALISED == *INIT_PART(guard_object))
+ return 0;
// Spin trying to do the initialisation
- while (1)
+ for (;;)
{
// Loop trying to move the value of the guard from 0 (not
// locked, not initialised) to the locked-uninitialised
// position.
- switch (__sync_val_compare_and_swap(guard_object, 0, LOCKED))
- {
- // If the old value was 0, we succeeded, so continue
- // initialising
- case 0:
+ old = __sync_val_compare_and_swap(LOCK_PART(guard_object),
+ INITIAL, LOCKED);
+ if (old == INITIAL) {
+ // Lock obtained. If lock and init bit are
+ // in separate words, check for init race.
+ if (INIT_PART(guard_object) == LOCK_PART(guard_object))
+ return 1;
+ if (INITIALISED != *INIT_PART(guard_object))
return 1;
- // If this was already initialised, return and let the caller skip
- // initialising it again.
- case INITIALISED:
- return 0;
- // If it is locked by another thread, relinquish the CPU and try
- // again later.
- case LOCKED:
- case LOCKED | INITIALISED:
- sched_yield();
- break;
- // If it is some other value, then something has gone badly wrong.
- // Give up.
- default:
- fprintf(stderr, "Invalid state detected attempting to lock static initialiser.\n");
- abort();
+
+ // No need for a memory barrier here,
+ // see first comment.
+ *LOCK_PART(guard_object) = INITIAL;
+ return 0;
}
+ // If lock and init bit are in the same word, check again
+ // if we are done.
+ if (INIT_PART(guard_object) == LOCK_PART(guard_object) &&
+ old == INITIALISED)
+ return 0;
+
+ assert(old == LOCKED);
+ // Another thread holds the lock.
+ // If lock and init bit are in different words, check
+ // if we are done before yielding and looping.
+ if (INIT_PART(guard_object) != LOCK_PART(guard_object) &&
+ INITIALISED == *INIT_PART(guard_object))
+ return 0;
+ sched_yield();
}
- //__builtin_unreachable();
- return 0;
}
/**
@@ -135,7 +169,8 @@
extern "C" void __cxa_guard_abort(volatile guard_t *guard_object)
{
__attribute__((unused))
- bool reset = __sync_bool_compare_and_swap(guard_object, LOCKED, 0);
+ bool reset = __sync_bool_compare_and_swap(LOCK_PART(guard_object),
+ LOCKED, INITIAL);
assert(reset);
}
/**
@@ -144,9 +179,15 @@
*/
extern "C" void __cxa_guard_release(volatile guard_t *guard_object)
{
+ guard_lock_t old;
+ if (INIT_PART(guard_object) == LOCK_PART(guard_object))
+ old = LOCKED;
+ else
+ old = INITIAL;
__attribute__((unused))
- bool reset = __sync_bool_compare_and_swap(guard_object, LOCKED, INITIALISED);
+ bool reset = __sync_bool_compare_and_swap(INIT_PART(guard_object),
+ old, INITIALISED);
assert(reset);
+ if (INIT_PART(guard_object) != LOCK_PART(guard_object))
+ *LOCK_PART(guard_object) = INITIAL;
}
-
-
diff -r 0c2a15e7fc22 -r 70b1572f46cf external/bsd/libc++/dist/libcxxrt/src/unwind.h
--- a/external/bsd/libc++/dist/libcxxrt/src/unwind.h Thu May 15 23:53:10 2014 +0000
+++ b/external/bsd/libc++/dist/libcxxrt/src/unwind.h Thu May 15 23:56:01 2014 +0000
@@ -27,7 +27,7 @@
extern "C" {
#endif
-#ifdef __arm__
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
#include "unwind-arm.h"
#else
#include "unwind-itanium.h"
Home |
Main Index |
Thread Index |
Old Index