[libc++abi] Implement __cxa_init_primary_exception and use it to optimize std::make_exception_ptr (#65534)

This patch implements __cxa_init_primary_exception, an extension to the 
Itanium C++ ABI. This extension is already present in both libsupc++ and 
libcxxrt. This patch also starts making use of this function in 
std::make_exception_ptr: instead of going through a full throw/catch 
cycle, we are now able to initialize an exception directly, thus making 
std::make_exception_ptr around 30x faster.
This commit is contained in:
itrofimow 2024-01-22 19:12:41 +04:00 committed by GitHub
parent 6ba62f4f25
commit 51e91b64d0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 171 additions and 34 deletions

View File

@ -202,6 +202,7 @@ set(BENCHMARK_TESTS
allocation.bench.cpp
deque.bench.cpp
deque_iterator.bench.cpp
exception_ptr.bench.cpp
filesystem.bench.cpp
format_to_n.bench.cpp
format_to.bench.cpp

View File

@ -0,0 +1,19 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include <benchmark/benchmark.h>
#include <exception>
void bm_make_exception_ptr(benchmark::State& state) {
for (auto _ : state) {
benchmark::DoNotOptimize(std::make_exception_ptr(42));
}
}
BENCHMARK(bm_make_exception_ptr)->ThreadRange(1, 8);
BENCHMARK_MAIN();

View File

@ -563,6 +563,7 @@ We can now run CMake:
$ cmake -G Ninja -S runtimes -B build \
-DLLVM_ENABLE_RUNTIMES="libcxx" \
-DLIBCXX_CXX_ABI=libstdc++ \
-DLIBCXXABI_USE_LLVM_UNWINDER=OFF \
-DLIBCXX_CXX_ABI_INCLUDE_PATHS="/usr/include/c++/4.7/;/usr/include/c++/4.7/x86_64-linux-gnu/"
$ ninja -C build install-cxx
@ -589,6 +590,8 @@ We can now run CMake like:
$ cmake -G Ninja -S runtimes -B build \
-DLLVM_ENABLE_RUNTIMES="libcxx" \
-DLIBCXX_CXX_ABI=libcxxrt \
-DLIBCXX_ENABLE_NEW_DELETE_DEFINITIONS=ON \
-DLIBCXXABI_USE_LLVM_UNWINDER=OFF \
-DLIBCXX_CXX_ABI_INCLUDE_PATHS=path/to/libcxxrt-sources/src
$ ninja -C build install-cxx

View File

@ -101,6 +101,12 @@
# define _LIBCPP_AVAILABILITY_HAS_BAD_ANY_CAST 1
# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST
// These macros controls the availability of __cxa_init_primary_exception
// in the built library, which std::make_exception_ptr might use
// (see libcxx/include/__exception/exception_ptr.h).
# define _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION 1
# define _LIBCPP_AVAILABILITY_INIT_PRIMARY_EXCEPTION
// These macros control the availability of all parts of <filesystem> that
// depend on something in the dylib.
# define _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY 1
@ -136,9 +142,9 @@
# define _LIBCPP_AVAILABILITY_HAS_TZDB 1
# define _LIBCPP_AVAILABILITY_TZDB
// This controls the availability of C++23 <print>, which
// has a dependency on the built library (it needs access to
// the underlying buffer types of std::cout, std::cerr, and std::clog.
// This controls the availability of C++23 <print>, which
// has a dependency on the built library (it needs access to
// the underlying buffer types of std::cout, std::cerr, and std::clog.
# define _LIBCPP_AVAILABILITY_HAS_PRINT 1
# define _LIBCPP_AVAILABILITY_PRINT
@ -167,6 +173,10 @@
# define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
// TODO: Update once this is released
# define _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION 0
# define _LIBCPP_AVAILABILITY_INIT_PRIMARY_EXCEPTION __attribute__((unavailable))
// <filesystem>
// clang-format off
# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101500) || \
@ -303,4 +313,13 @@
# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS
#endif
// Define availability attributes that depend on both
// _LIBCPP_HAS_NO_EXCEPTIONS and _LIBCPP_HAS_NO_RTTI.
#if defined(_LIBCPP_HAS_NO_EXCEPTIONS) || defined(_LIBCPP_HAS_NO_RTTI)
# undef _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION
# undef _LIBCPP_AVAILABILITY_INIT_PRIMARY_EXCEPTION
# define _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION 0
# define _LIBCPP_AVAILABILITY_INIT_PRIMARY_EXCEPTION
#endif
#endif // _LIBCPP___AVAILABILITY

View File

@ -9,16 +9,44 @@
#ifndef _LIBCPP___EXCEPTION_EXCEPTION_PTR_H
#define _LIBCPP___EXCEPTION_EXCEPTION_PTR_H
#include <__availability>
#include <__config>
#include <__exception/operations.h>
#include <__memory/addressof.h>
#include <__memory/construct_at.h>
#include <__type_traits/decay.h>
#include <cstddef>
#include <cstdlib>
#include <new>
#include <typeinfo>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#ifndef _LIBCPP_ABI_MICROSOFT
namespace __cxxabiv1 {
extern "C" {
_LIBCPP_OVERRIDABLE_FUNC_VIS void* __cxa_allocate_exception(size_t) throw();
_LIBCPP_OVERRIDABLE_FUNC_VIS void __cxa_free_exception(void*) throw();
struct __cxa_exception;
_LIBCPP_OVERRIDABLE_FUNC_VIS __cxa_exception* __cxa_init_primary_exception(
void*,
std::type_info*,
void(
# if defined(_WIN32)
__thiscall
# endif
*)(void*)) throw();
}
} // namespace __cxxabiv1
#endif
namespace std { // purposefully not using versioning namespace
#ifndef _LIBCPP_ABI_MICROSOFT
@ -26,6 +54,11 @@ namespace std { // purposefully not using versioning namespace
class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
void* __ptr_;
static exception_ptr __from_native_exception_pointer(void*) _NOEXCEPT;
template <class _Ep>
friend _LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep) _NOEXCEPT;
public:
_LIBCPP_HIDE_FROM_ABI exception_ptr() _NOEXCEPT : __ptr_() {}
_LIBCPP_HIDE_FROM_ABI exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {}
@ -51,11 +84,28 @@ public:
template <class _Ep>
_LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep __e) _NOEXCEPT {
# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
# if _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION && __cplusplus >= 201103L
using _Ep2 = __decay_t<_Ep>;
void* __ex = __cxxabiv1::__cxa_allocate_exception(sizeof(_Ep));
(void)__cxxabiv1::__cxa_init_primary_exception(__ex, const_cast<std::type_info*>(&typeid(_Ep)), [](void* __p) {
std::__destroy_at(static_cast<_Ep2*>(__p));
});
try {
::new (__ex) _Ep2(__e);
return exception_ptr::__from_native_exception_pointer(__ex);
} catch (...) {
__cxxabiv1::__cxa_free_exception(__ex);
return current_exception();
}
# else
try {
throw __e;
} catch (...) {
return current_exception();
}
# endif
# else
((void)__e);
std::abort();

View File

@ -362,7 +362,6 @@ _LIBCPP_END_NAMESPACE_STD
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
# include <cstdlib>
# include <exception>
# include <type_traits>
#endif

View File

@ -372,7 +372,6 @@ _LIBCPP_END_NAMESPACE_STD
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
# include <cstdlib>
# include <exception>
# include <type_traits>
#endif

View File

@ -300,6 +300,7 @@
{'is_defined': False, 'name': '___cxa_guard_acquire', 'type': 'U'}
{'is_defined': False, 'name': '___cxa_guard_release', 'type': 'U'}
{'is_defined': False, 'name': '___cxa_increment_exception_refcount', 'type': 'U'}
{'is_defined': False, 'name': '___cxa_init_primary_exception', 'type': 'U'}
{'is_defined': False, 'name': '___cxa_pure_virtual', 'type': 'U'}
{'is_defined': False, 'name': '___cxa_rethrow', 'type': 'U'}
{'is_defined': False, 'name': '___cxa_rethrow_primary_exception', 'type': 'U'}
@ -811,6 +812,7 @@
{'is_defined': True, 'name': '__ZNSt13bad_exceptionD0Ev', 'type': 'I'}
{'is_defined': True, 'name': '__ZNSt13bad_exceptionD1Ev', 'type': 'I'}
{'is_defined': True, 'name': '__ZNSt13bad_exceptionD2Ev', 'type': 'I'}
{'is_defined': True, 'name': '__ZNSt13exception_ptr31__from_native_exception_pointerEPv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt13exception_ptrC1ERKS_', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt13exception_ptrC2ERKS_', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt13exception_ptrD1Ev', 'type': 'FUNC'}
@ -2509,6 +2511,7 @@
{'is_defined': True, 'name': '___cxa_guard_abort', 'type': 'I'}
{'is_defined': True, 'name': '___cxa_guard_acquire', 'type': 'I'}
{'is_defined': True, 'name': '___cxa_guard_release', 'type': 'I'}
{'is_defined': True, 'name': '___cxa_init_primary_exception', 'type': 'I'}
{'is_defined': True, 'name': '___cxa_pure_virtual', 'type': 'I'}
{'is_defined': True, 'name': '___cxa_rethrow', 'type': 'I'}
{'is_defined': True, 'name': '___cxa_throw', 'type': 'I'}

View File

@ -493,6 +493,7 @@
{'is_defined': True, 'name': '_ZNSt13bad_exceptionD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13bad_exceptionD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13bad_exceptionD2Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptr31__from_native_exception_pointerEPv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptrC1ERKS_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptrC2ERKS_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptrD1Ev', 'type': 'FUNC'}
@ -2311,6 +2312,7 @@
{'is_defined': True, 'name': '__cxa_guard_acquire', 'type': 'FUNC'}
{'is_defined': True, 'name': '__cxa_guard_release', 'type': 'FUNC'}
{'is_defined': True, 'name': '__cxa_increment_exception_refcount', 'type': 'FUNC'}
{'is_defined': True, 'name': '__cxa_init_primary_exception', 'type': 'FUNC'}
{'is_defined': True, 'name': '__cxa_new_handler', 'size': 4, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__cxa_pure_virtual', 'type': 'FUNC'}
{'is_defined': True, 'name': '__cxa_rethrow', 'type': 'FUNC'}

View File

@ -249,6 +249,7 @@
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt12experimental19bad_optional_accessD0Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt12experimental19bad_optional_accessD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt12experimental19bad_optional_accessD2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt13exception_ptr31__from_native_exception_pointerEPv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt13exception_ptrC1ERKS_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt13exception_ptrC2ERKS_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt13exception_ptrD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@ -1111,6 +1112,7 @@
{'import_export': 'IMP', 'is_defined': False, 'name': '__cxa_guard_acquire', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'IMP', 'is_defined': False, 'name': '__cxa_guard_release', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'IMP', 'is_defined': False, 'name': '__cxa_increment_exception_refcount', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'IMP', 'is_defined': False, 'name': '__cxa_init_primary_exception', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'IMP', 'is_defined': False, 'name': '__cxa_pure_virtual', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'IMP', 'is_defined': False, 'name': '__cxa_rethrow', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'IMP', 'is_defined': False, 'name': '__cxa_rethrow_primary_exception', 'storage_mapping_class': 'DS', 'type': 'FUNC'}

View File

@ -249,6 +249,7 @@
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt12experimental19bad_optional_accessD0Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt12experimental19bad_optional_accessD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt12experimental19bad_optional_accessD2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt13exception_ptr31__from_native_exception_pointerEPv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt13exception_ptrC1ERKS_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt13exception_ptrC2ERKS_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt13exception_ptrD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@ -1111,6 +1112,7 @@
{'import_export': 'IMP', 'is_defined': False, 'name': '__cxa_guard_acquire', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'IMP', 'is_defined': False, 'name': '__cxa_guard_release', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'IMP', 'is_defined': False, 'name': '__cxa_increment_exception_refcount', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'IMP', 'is_defined': False, 'name': '__cxa_init_primary_exception', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'IMP', 'is_defined': False, 'name': '__cxa_pure_virtual', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'IMP', 'is_defined': False, 'name': '__cxa_rethrow', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'IMP', 'is_defined': False, 'name': '__cxa_rethrow_primary_exception', 'storage_mapping_class': 'DS', 'type': 'FUNC'}

View File

@ -300,6 +300,7 @@
{'is_defined': False, 'name': '___cxa_guard_acquire', 'type': 'U'}
{'is_defined': False, 'name': '___cxa_guard_release', 'type': 'U'}
{'is_defined': False, 'name': '___cxa_increment_exception_refcount', 'type': 'U'}
{'is_defined': False, 'name': '___cxa_init_primary_exception', 'type': 'U'}
{'is_defined': False, 'name': '___cxa_pure_virtual', 'type': 'U'}
{'is_defined': False, 'name': '___cxa_rethrow', 'type': 'U'}
{'is_defined': False, 'name': '___cxa_rethrow_primary_exception', 'type': 'U'}
@ -811,6 +812,7 @@
{'is_defined': True, 'name': '__ZNSt13bad_exceptionD0Ev', 'type': 'I'}
{'is_defined': True, 'name': '__ZNSt13bad_exceptionD1Ev', 'type': 'I'}
{'is_defined': True, 'name': '__ZNSt13bad_exceptionD2Ev', 'type': 'I'}
{'is_defined': True, 'name': '__ZNSt13exception_ptr31__from_native_exception_pointerEPv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt13exception_ptrC1ERKS_', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt13exception_ptrC2ERKS_', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt13exception_ptrD1Ev', 'type': 'FUNC'}
@ -2543,6 +2545,7 @@
{'is_defined': True, 'name': '___cxa_guard_abort', 'type': 'I'}
{'is_defined': True, 'name': '___cxa_guard_acquire', 'type': 'I'}
{'is_defined': True, 'name': '___cxa_guard_release', 'type': 'I'}
{'is_defined': True, 'name': '___cxa_init_primary_exception', 'type': 'I'}
{'is_defined': True, 'name': '___cxa_pure_virtual', 'type': 'I'}
{'is_defined': True, 'name': '___cxa_rethrow', 'type': 'I'}
{'is_defined': True, 'name': '___cxa_throw', 'type': 'I'}

View File

@ -493,6 +493,7 @@
{'is_defined': True, 'name': '_ZNSt13bad_exceptionD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13bad_exceptionD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13bad_exceptionD2Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptr31__from_native_exception_pointerEPv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptrC1ERKS_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptrC2ERKS_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptrD1Ev', 'type': 'FUNC'}
@ -2305,6 +2306,7 @@
{'is_defined': True, 'name': '__cxa_guard_acquire', 'type': 'FUNC'}
{'is_defined': True, 'name': '__cxa_guard_release', 'type': 'FUNC'}
{'is_defined': True, 'name': '__cxa_increment_exception_refcount', 'type': 'FUNC'}
{'is_defined': True, 'name': '__cxa_init_primary_exception', 'type': 'FUNC'}
{'is_defined': True, 'name': '__cxa_new_handler', 'size': 8, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__cxa_pure_virtual', 'type': 'FUNC'}
{'is_defined': True, 'name': '__cxa_rethrow', 'type': 'FUNC'}

View File

@ -56,6 +56,7 @@
{'is_defined': False, 'name': '__cxa_guard_acquire', 'type': 'FUNC'}
{'is_defined': False, 'name': '__cxa_guard_release', 'type': 'FUNC'}
{'is_defined': False, 'name': '__cxa_increment_exception_refcount', 'type': 'FUNC'}
{'is_defined': False, 'name': '__cxa_init_primary_exception', 'type': 'FUNC'}
{'is_defined': False, 'name': '__cxa_pure_virtual', 'type': 'FUNC'}
{'is_defined': False, 'name': '__cxa_rethrow', 'type': 'FUNC'}
{'is_defined': False, 'name': '__cxa_rethrow_primary_exception', 'type': 'FUNC'}
@ -523,6 +524,7 @@
{'is_defined': True, 'name': '_ZNSt12experimental19bad_optional_accessD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt12experimental19bad_optional_accessD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt12experimental19bad_optional_accessD2Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptr31__from_native_exception_pointerEPv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptrC1ERKS_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptrC2ERKS_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptrD1Ev', 'type': 'FUNC'}

View File

@ -54,6 +54,7 @@
{'is_defined': False, 'name': '__cxa_guard_acquire', 'type': 'FUNC'}
{'is_defined': False, 'name': '__cxa_guard_release', 'type': 'FUNC'}
{'is_defined': False, 'name': '__cxa_increment_exception_refcount', 'type': 'FUNC'}
{'is_defined': False, 'name': '__cxa_init_primary_exception', 'type': 'FUNC'}
{'is_defined': False, 'name': '__cxa_pure_virtual', 'type': 'FUNC'}
{'is_defined': False, 'name': '__cxa_rethrow', 'type': 'FUNC'}
{'is_defined': False, 'name': '__cxa_rethrow_primary_exception', 'type': 'FUNC'}
@ -521,6 +522,7 @@
{'is_defined': True, 'name': '_ZNSt12experimental19bad_optional_accessD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt12experimental19bad_optional_accessD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt12experimental19bad_optional_accessD2Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptr31__from_native_exception_pointerEPv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptrC1ERKS_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptrC2ERKS_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptrD1Ev', 'type': 'FUNC'}

View File

@ -493,6 +493,7 @@
{'is_defined': True, 'name': '_ZNSt12experimental19bad_optional_accessD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt12experimental19bad_optional_accessD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt12experimental19bad_optional_accessD2Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptr31__from_native_exception_pointerEPv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptrC1ERKS_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptrC2ERKS_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptrD1Ev', 'type': 'FUNC'}
@ -1999,4 +2000,4 @@
{'is_defined': True, 'name': '_ZTv0_n24_NSt3__114basic_iostreamIcNS_11char_traitsIcEEED0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZTv0_n24_NSt3__114basic_iostreamIcNS_11char_traitsIcEEED1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZTv0_n24_NSt3__19strstreamD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZTv0_n24_NSt3__19strstreamD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZTv0_n24_NSt3__19strstreamD1Ev', 'type': 'FUNC'}

View File

@ -28,6 +28,14 @@ exception_ptr& exception_ptr::operator=(const exception_ptr& other) noexcept {
return *this;
}
exception_ptr exception_ptr::__from_native_exception_pointer(void* __e) noexcept {
exception_ptr ptr;
ptr.__ptr_ = __e;
__cxa_increment_exception_refcount(ptr.__ptr_);
return ptr;
}
nested_exception::nested_exception() noexcept : __ptr_(current_exception()) {}
nested_exception::~nested_exception() noexcept {}

View File

@ -23,6 +23,7 @@ namespace __exception_ptr {
struct exception_ptr {
void* __ptr_;
explicit exception_ptr(void*) noexcept;
exception_ptr(const exception_ptr&) noexcept;
exception_ptr& operator=(const exception_ptr&) noexcept;
~exception_ptr() noexcept;
@ -45,6 +46,13 @@ exception_ptr& exception_ptr::operator=(const exception_ptr& other) noexcept {
return *this;
}
exception_ptr exception_ptr::__from_native_exception_pointer(void* __e) noexcept {
exception_ptr ptr{};
new (reinterpret_cast<void*>(&ptr)) __exception_ptr::exception_ptr(__e);
return ptr;
}
nested_exception::nested_exception() noexcept : __ptr_(current_exception()) {}
_LIBCPP_NORETURN void nested_exception::rethrow_nested() const {

View File

@ -221,7 +221,9 @@ deque typeinfo
deque version
exception cstddef
exception cstdlib
exception new
exception type_traits
exception typeinfo
exception version
execution cstddef
execution version
@ -536,7 +538,6 @@ mutex typeinfo
mutex version
new cstddef
new cstdlib
new exception
new type_traits
new version
numbers concepts
@ -643,7 +644,6 @@ ranges initializer_list
ranges iosfwd
ranges iterator
ranges limits
ranges new
ranges optional
ranges span
ranges tuple
@ -875,7 +875,6 @@ typeindex version
typeinfo cstddef
typeinfo cstdint
typeinfo cstdlib
typeinfo exception
typeinfo type_traits
unordered_map algorithm
unordered_map bit

1 algorithm atomic
221 deque version
222 exception cstddef
223 exception cstdlib
224 exception new
225 exception type_traits
226 exception typeinfo
227 exception version
228 execution cstddef
229 execution version
538 mutex version
539 new cstddef
540 new cstdlib
new exception
541 new type_traits
542 new version
543 numbers concepts
644 ranges iosfwd
645 ranges iterator
646 ranges limits
ranges new
647 ranges optional
648 ranges span
649 ranges tuple
875 typeinfo cstddef
876 typeinfo cstdint
877 typeinfo cstdlib
typeinfo exception
878 typeinfo type_traits
879 unordered_map algorithm
880 unordered_map bit

View File

@ -222,7 +222,9 @@ deque typeinfo
deque version
exception cstddef
exception cstdlib
exception new
exception type_traits
exception typeinfo
exception version
execution cstddef
execution version
@ -541,7 +543,6 @@ mutex typeinfo
mutex version
new cstddef
new cstdlib
new exception
new type_traits
new version
numbers concepts
@ -648,7 +649,6 @@ ranges initializer_list
ranges iosfwd
ranges iterator
ranges limits
ranges new
ranges optional
ranges span
ranges tuple
@ -881,7 +881,6 @@ typeindex version
typeinfo cstddef
typeinfo cstdint
typeinfo cstdlib
typeinfo exception
typeinfo type_traits
unordered_map algorithm
unordered_map bit

1 algorithm atomic
222 deque version
223 exception cstddef
224 exception cstdlib
225 exception new
226 exception type_traits
227 exception typeinfo
228 exception version
229 execution cstddef
230 execution version
543 mutex version
544 new cstddef
545 new cstdlib
new exception
546 new type_traits
547 new version
548 numbers concepts
649 ranges iosfwd
650 ranges iterator
651 ranges limits
ranges new
652 ranges optional
653 ranges span
654 ranges tuple
881 typeinfo cstddef
882 typeinfo cstdint
883 typeinfo cstdlib
typeinfo exception
884 typeinfo type_traits
885 unordered_map algorithm
886 unordered_map bit

View File

@ -222,7 +222,9 @@ deque typeinfo
deque version
exception cstddef
exception cstdlib
exception new
exception type_traits
exception typeinfo
exception version
execution cstddef
execution version
@ -543,7 +545,6 @@ mutex typeinfo
mutex version
new cstddef
new cstdlib
new exception
new type_traits
new version
numbers concepts
@ -650,7 +651,6 @@ ranges initializer_list
ranges iosfwd
ranges iterator
ranges limits
ranges new
ranges optional
ranges span
ranges tuple
@ -883,7 +883,6 @@ typeindex version
typeinfo cstddef
typeinfo cstdint
typeinfo cstdlib
typeinfo exception
typeinfo type_traits
unordered_map algorithm
unordered_map bit

1 algorithm atomic
222 deque version
223 exception cstddef
224 exception cstdlib
225 exception new
226 exception type_traits
227 exception typeinfo
228 exception version
229 execution cstddef
230 execution version
545 mutex version
546 new cstddef
547 new cstdlib
new exception
548 new type_traits
549 new version
550 numbers concepts
651 ranges iosfwd
652 ranges iterator
653 ranges limits
ranges new
654 ranges optional
655 ranges span
656 ranges tuple
883 typeinfo cstddef
884 typeinfo cstdint
885 typeinfo cstdlib
typeinfo exception
886 typeinfo type_traits
887 unordered_map algorithm
888 unordered_map bit

View File

@ -222,7 +222,9 @@ deque typeinfo
deque version
exception cstddef
exception cstdlib
exception new
exception type_traits
exception typeinfo
exception version
execution cstddef
execution version
@ -543,7 +545,6 @@ mutex typeinfo
mutex version
new cstddef
new cstdlib
new exception
new type_traits
new version
numbers concepts
@ -650,7 +651,6 @@ ranges initializer_list
ranges iosfwd
ranges iterator
ranges limits
ranges new
ranges optional
ranges span
ranges tuple
@ -883,7 +883,6 @@ typeindex version
typeinfo cstddef
typeinfo cstdint
typeinfo cstdlib
typeinfo exception
typeinfo type_traits
unordered_map algorithm
unordered_map bit

1 algorithm atomic
222 deque version
223 exception cstddef
224 exception cstdlib
225 exception new
226 exception type_traits
227 exception typeinfo
228 exception version
229 execution cstddef
230 execution version
545 mutex version
546 new cstddef
547 new cstdlib
new exception
548 new type_traits
549 new version
550 numbers concepts
651 ranges iosfwd
652 ranges iterator
653 ranges limits
ranges new
654 ranges optional
655 ranges span
656 ranges tuple
883 typeinfo cstddef
884 typeinfo cstdint
885 typeinfo cstdlib
typeinfo exception
886 typeinfo type_traits
887 unordered_map algorithm
888 unordered_map bit

View File

@ -228,7 +228,9 @@ deque typeinfo
deque version
exception cstddef
exception cstdlib
exception new
exception type_traits
exception typeinfo
exception version
execution cstddef
execution version
@ -548,7 +550,6 @@ mutex typeinfo
mutex version
new cstddef
new cstdlib
new exception
new type_traits
new version
numbers concepts
@ -655,7 +656,6 @@ ranges initializer_list
ranges iosfwd
ranges iterator
ranges limits
ranges new
ranges optional
ranges span
ranges tuple
@ -887,7 +887,6 @@ typeindex version
typeinfo cstddef
typeinfo cstdint
typeinfo cstdlib
typeinfo exception
typeinfo type_traits
unordered_map algorithm
unordered_map bit

1 algorithm atomic
228 deque version
229 exception cstddef
230 exception cstdlib
231 exception new
232 exception type_traits
233 exception typeinfo
234 exception version
235 execution cstddef
236 execution version
550 mutex version
551 new cstddef
552 new cstdlib
new exception
553 new type_traits
554 new version
555 numbers concepts
656 ranges iosfwd
657 ranges iterator
658 ranges limits
ranges new
659 ranges optional
660 ranges span
661 ranges tuple
887 typeinfo cstddef
888 typeinfo cstdint
889 typeinfo cstdlib
typeinfo exception
890 typeinfo type_traits
891 unordered_map algorithm
892 unordered_map bit

View File

@ -153,6 +153,8 @@ deque tuple
deque version
exception cstddef
exception cstdlib
exception new
exception typeinfo
exception version
execution cstddef
execution version

1 algorithm climits
153 deque version
154 exception cstddef
155 exception cstdlib
156 exception new
157 exception typeinfo
158 exception version
159 execution cstddef
160 execution version

View File

@ -153,6 +153,8 @@ deque tuple
deque version
exception cstddef
exception cstdlib
exception new
exception typeinfo
exception version
execution cstddef
execution version

1 algorithm climits
153 deque version
154 exception cstddef
155 exception cstdlib
156 exception new
157 exception typeinfo
158 exception version
159 execution cstddef
160 execution version

View File

@ -36,6 +36,9 @@ class type_info; // forward declaration
// runtime routines use C calling conventions, but are in __cxxabiv1 namespace
namespace __cxxabiv1 {
struct __cxa_exception;
extern "C" {
// 2.4.2 Allocating the Exception Object
@ -43,6 +46,9 @@ extern _LIBCXXABI_FUNC_VIS void *
__cxa_allocate_exception(size_t thrown_size) throw();
extern _LIBCXXABI_FUNC_VIS void
__cxa_free_exception(void *thrown_exception) throw();
// This function is an LLVM extension, which mirrors the same extension in libsupc++ and libcxxrt
extern _LIBCXXABI_FUNC_VIS __cxa_exception*
__cxa_init_primary_exception(void* object, std::type_info* tinfo, void(_LIBCXXABI_DTOR_FUNC* dest)(void*)) throw();
// 2.4.3 Throwing the Exception Object
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void

View File

@ -7,5 +7,6 @@ ___cxa_end_catch
___cxa_free_dependent_exception
___cxa_free_exception
___cxa_get_exception_ptr
___cxa_init_primary_exception
___cxa_rethrow
___cxa_throw

View File

@ -206,6 +206,19 @@ void __cxa_free_exception(void *thrown_object) throw() {
__aligned_free_with_fallback((void *)raw_buffer);
}
__cxa_exception* __cxa_init_primary_exception(void* object, std::type_info* tinfo,
void(_LIBCXXABI_DTOR_FUNC* dest)(void*)) throw() {
__cxa_exception* exception_header = cxa_exception_from_thrown_object(object);
exception_header->referenceCount = 0;
exception_header->unexpectedHandler = std::get_unexpected();
exception_header->terminateHandler = std::get_terminate();
exception_header->exceptionType = tinfo;
exception_header->exceptionDestructor = dest;
setOurExceptionClass(&exception_header->unwindHeader);
exception_header->unwindHeader.exception_cleanup = exception_cleanup_func;
return exception_header;
}
// This function shall allocate a __cxa_dependent_exception and
// return a pointer to it. (Really to the object, not past its' end).
@ -260,22 +273,15 @@ __cxa_throw(void *thrown_object, std::type_info *tinfo, void *(_LIBCXXABI_DTOR_F
#else
__cxa_throw(void *thrown_object, std::type_info *tinfo, void (_LIBCXXABI_DTOR_FUNC *dest)(void *)) {
#endif
__cxa_eh_globals *globals = __cxa_get_globals();
__cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object);
__cxa_eh_globals* globals = __cxa_get_globals();
globals->uncaughtExceptions += 1; // Not atomically, since globals are thread-local
exception_header->unexpectedHandler = std::get_unexpected();
exception_header->terminateHandler = std::get_terminate();
exception_header->exceptionType = tinfo;
exception_header->exceptionDestructor = dest;
setOurExceptionClass(&exception_header->unwindHeader);
exception_header->referenceCount = 1; // This is a newly allocated exception, no need for thread safety.
globals->uncaughtExceptions += 1; // Not atomically, since globals are thread-local
exception_header->unwindHeader.exception_cleanup = exception_cleanup_func;
__cxa_exception* exception_header = __cxa_init_primary_exception(thrown_object, tinfo, dest);
exception_header->referenceCount = 1; // This is a newly allocated exception, no need for thread safety.
#if __has_feature(address_sanitizer)
// Inform the ASan runtime that now might be a good time to clean stuff up.
__asan_handle_no_return();
// Inform the ASan runtime that now might be a good time to clean stuff up.
__asan_handle_no_return();
#endif
#ifdef __USING_SJLJ_EXCEPTIONS__