Update libcxxabi

llvm commit b2851aea80e5a8f0cfd6c3c5a56a6b00fb28c6b6
This commit is contained in:
Jakub Konka 2020-12-16 11:55:25 +01:00
parent f9a11fbfaf
commit 38bf94280b
11 changed files with 244 additions and 220 deletions

View File

@ -18,6 +18,19 @@
#define __has_attribute(_attribute_) 0
#endif
#if defined(__clang__)
# define _LIBCXXABI_COMPILER_CLANG
# ifndef __apple_build_version__
# define _LIBCXXABI_CLANG_VER (__clang_major__ * 100 + __clang_minor__)
# endif
#elif defined(__GNUC__)
# define _LIBCXXABI_COMPILER_GCC
#elif defined(_MSC_VER)
# define _LIBCXXABI_COMPILER_MSVC
#elif defined(__IBMCPP__)
# define _LIBCXXABI_COMPILER_IBM
#endif
#if defined(_WIN32)
#if defined(_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS)
#define _LIBCXXABI_HIDDEN
@ -53,7 +66,7 @@
#endif
#endif
#if defined(_WIN32)
#if defined(_LIBCXXABI_COMPILER_MSVC)
#define _LIBCXXABI_WEAK
#else
#define _LIBCXXABI_WEAK __attribute__((__weak__))
@ -72,7 +85,7 @@
#endif
// wasm32 follows the arm32 ABI convention of using 32-bit guard.
#if defined(__arm__) || defined(__wasm32__)
#if defined(__arm__) || defined(__wasm32__) || defined(__ARM64_ARCH_8_32__)
# define _LIBCXXABI_GUARD_ABI_ARM
#endif

View File

@ -21,6 +21,7 @@
#define _LIBCPPABI_VERSION 1002
#define _LIBCXXABI_NORETURN __attribute__((noreturn))
#define _LIBCXXABI_ALWAYS_COLD __attribute__((cold))
#ifdef __cplusplus
@ -78,13 +79,13 @@ extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_deleted_virtual(void);
// 3.3.2 One-time Construction API
#if defined(_LIBCXXABI_GUARD_ABI_ARM)
extern _LIBCXXABI_FUNC_VIS int __cxa_guard_acquire(uint32_t *);
extern _LIBCXXABI_FUNC_VIS void __cxa_guard_release(uint32_t *);
extern _LIBCXXABI_FUNC_VIS void __cxa_guard_abort(uint32_t *);
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD int __cxa_guard_acquire(uint32_t *);
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_release(uint32_t *);
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_abort(uint32_t *);
#else
extern _LIBCXXABI_FUNC_VIS int __cxa_guard_acquire(uint64_t *);
extern _LIBCXXABI_FUNC_VIS void __cxa_guard_release(uint64_t *);
extern _LIBCXXABI_FUNC_VIS void __cxa_guard_abort(uint64_t *);
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD int __cxa_guard_acquire(uint64_t *);
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_release(uint64_t *);
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_abort(uint64_t *);
#endif
// 3.3.3 Array Construction and Destruction API
@ -136,9 +137,9 @@ __cxa_vec_cctor(void *dest_array, void *src_array, size_t element_count,
void (*destructor)(void *));
// 3.3.5.3 Runtime API
extern _LIBCXXABI_FUNC_VIS int __cxa_atexit(void (*f)(void *), void *p,
void *d);
extern _LIBCXXABI_FUNC_VIS int __cxa_finalize(void *);
// These functions are part of the C++ ABI, but they are not defined in libc++abi:
// int __cxa_atexit(void (*)(void *), void *, void *);
// void __cxa_finalize(void *);
// 3.4 Demangler API
extern _LIBCXXABI_FUNC_VIS char *__cxa_demangle(const char *mangled_name,

View File

@ -54,6 +54,14 @@
#endif
#endif
#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wtautological-pointer-compare"
#elif defined(__GNUC__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Waddress"
#endif
// To make testing possible, this header is included from both cxa_guard.cpp
// and a number of tests.
//
@ -112,25 +120,25 @@ class AtomicInt {
public:
using MemoryOrder = std::__libcpp_atomic_order;
explicit AtomicInt(IntType *b) : b(b) {}
explicit AtomicInt(IntType *b) : b_(b) {}
AtomicInt(AtomicInt const&) = delete;
AtomicInt& operator=(AtomicInt const&) = delete;
IntType load(MemoryOrder ord) {
return std::__libcpp_atomic_load(b, ord);
return std::__libcpp_atomic_load(b_, ord);
}
void store(IntType val, MemoryOrder ord) {
std::__libcpp_atomic_store(b, val, ord);
std::__libcpp_atomic_store(b_, val, ord);
}
IntType exchange(IntType new_val, MemoryOrder ord) {
return std::__libcpp_atomic_exchange(b, new_val, ord);
return std::__libcpp_atomic_exchange(b_, new_val, ord);
}
bool compare_exchange(IntType *expected, IntType desired, MemoryOrder ord_success, MemoryOrder ord_failure) {
return std::__libcpp_atomic_compare_exchange(b, expected, desired, ord_success, ord_failure);
return std::__libcpp_atomic_compare_exchange(b_, expected, desired, ord_success, ord_failure);
}
private:
IntType *b;
IntType *b_;
};
//===----------------------------------------------------------------------===//
@ -154,14 +162,7 @@ constexpr uint32_t (*PlatformThreadID)() = nullptr;
constexpr bool PlatformSupportsThreadID() {
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-pointer-compare"
#endif
return +PlatformThreadID != nullptr;
#ifdef __clang__
#pragma clang diagnostic pop
#endif
}
//===----------------------------------------------------------------------===//
@ -375,18 +376,18 @@ private:
LockGuard& operator=(LockGuard const&) = delete;
explicit LockGuard(const char* calling_func)
: calling_func(calling_func) {
: calling_func_(calling_func) {
if (global_mutex.lock())
ABORT_WITH_MESSAGE("%s failed to acquire mutex", calling_func);
ABORT_WITH_MESSAGE("%s failed to acquire mutex", calling_func_);
}
~LockGuard() {
if (global_mutex.unlock())
ABORT_WITH_MESSAGE("%s failed to release mutex", calling_func);
ABORT_WITH_MESSAGE("%s failed to release mutex", calling_func_);
}
private:
const char* const calling_func;
const char* const calling_func_;
};
};
@ -411,14 +412,7 @@ constexpr void (*PlatformFutexWake)(int*) = nullptr;
#endif
constexpr bool PlatformSupportsFutex() {
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-pointer-compare"
#endif
return +PlatformFutexWait != nullptr;
#ifdef __clang__
#pragma clang diagnostic pop
#endif
}
/// InitByteFutex - Manages initialization using atomics and the futex syscall
@ -589,4 +583,10 @@ using SelectedImplementation =
} // end namespace
} // end namespace __cxxabiv1
#if defined(__clang__)
# pragma clang diagnostic pop
#elif defined(__GNUC__)
# pragma GCC diagnostic pop
#endif
#endif // LIBCXXABI_SRC_INCLUDE_CXA_GUARD_IMPL_H

View File

@ -82,6 +82,7 @@
X(PostfixExpr) \
X(ConditionalExpr) \
X(MemberExpr) \
X(SubobjectExpr) \
X(EnclosingExpr) \
X(CastExpr) \
X(SizeofParamPackExpr) \
@ -91,6 +92,7 @@
X(PrefixExpr) \
X(FunctionParam) \
X(ConversionExpr) \
X(PointerToMemberConversionExpr) \
X(InitListExpr) \
X(FoldExpr) \
X(ThrowExpr) \
@ -1656,6 +1658,40 @@ public:
}
};
class SubobjectExpr : public Node {
const Node *Type;
const Node *SubExpr;
StringView Offset;
NodeArray UnionSelectors;
bool OnePastTheEnd;
public:
SubobjectExpr(const Node *Type_, const Node *SubExpr_, StringView Offset_,
NodeArray UnionSelectors_, bool OnePastTheEnd_)
: Node(KSubobjectExpr), Type(Type_), SubExpr(SubExpr_), Offset(Offset_),
UnionSelectors(UnionSelectors_), OnePastTheEnd(OnePastTheEnd_) {}
template<typename Fn> void match(Fn F) const {
F(Type, SubExpr, Offset, UnionSelectors, OnePastTheEnd);
}
void printLeft(OutputStream &S) const override {
SubExpr->print(S);
S += ".<";
Type->print(S);
S += " at offset ";
if (Offset.empty()) {
S += "0";
} else if (Offset[0] == 'n') {
S += "-";
S += Offset.dropFront();
} else {
S += Offset;
}
S += ">";
}
};
class EnclosingExpr : public Node {
const StringView Prefix;
const Node *Infix;
@ -1843,6 +1879,28 @@ public:
}
};
class PointerToMemberConversionExpr : public Node {
const Node *Type;
const Node *SubExpr;
StringView Offset;
public:
PointerToMemberConversionExpr(const Node *Type_, const Node *SubExpr_,
StringView Offset_)
: Node(KPointerToMemberConversionExpr), Type(Type_), SubExpr(SubExpr_),
Offset(Offset_) {}
template<typename Fn> void match(Fn F) const { F(Type, SubExpr, Offset); }
void printLeft(OutputStream &S) const override {
S += "(";
Type->print(S);
S += ")(";
SubExpr->print(S);
S += ")";
}
};
class InitListExpr : public Node {
const Node *Ty;
NodeArray Inits;
@ -2313,9 +2371,9 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
TemplateParamList Params;
public:
ScopedTemplateParamList(AbstractManglingParser *Parser)
: Parser(Parser),
OldNumTemplateParamLists(Parser->TemplateParams.size()) {
ScopedTemplateParamList(AbstractManglingParser *TheParser)
: Parser(TheParser),
OldNumTemplateParamLists(TheParser->TemplateParams.size()) {
Parser->TemplateParams.push_back(&Params);
}
~ScopedTemplateParamList() {
@ -2437,6 +2495,8 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
Node *parseConversionExpr();
Node *parseBracedExpr();
Node *parseFoldExpr();
Node *parsePointerToMemberConversionExpr();
Node *parseSubobjectExpr();
/// Parse the <type> production.
Node *parseType();
@ -4404,6 +4464,50 @@ Node *AbstractManglingParser<Derived, Alloc>::parseFoldExpr() {
return make<FoldExpr>(IsLeftFold, OperatorName, Pack, Init);
}
// <expression> ::= mc <parameter type> <expr> [<offset number>] E
//
// Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47
template <typename Derived, typename Alloc>
Node *AbstractManglingParser<Derived, Alloc>::parsePointerToMemberConversionExpr() {
Node *Ty = getDerived().parseType();
if (!Ty)
return nullptr;
Node *Expr = getDerived().parseExpr();
if (!Expr)
return nullptr;
StringView Offset = getDerived().parseNumber(true);
if (!consumeIf('E'))
return nullptr;
return make<PointerToMemberConversionExpr>(Ty, Expr, Offset);
}
// <expression> ::= so <referent type> <expr> [<offset number>] <union-selector>* [p] E
// <union-selector> ::= _ [<number>]
//
// Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47
template <typename Derived, typename Alloc>
Node *AbstractManglingParser<Derived, Alloc>::parseSubobjectExpr() {
Node *Ty = getDerived().parseType();
if (!Ty)
return nullptr;
Node *Expr = getDerived().parseExpr();
if (!Expr)
return nullptr;
StringView Offset = getDerived().parseNumber(true);
size_t SelectorsBegin = Names.size();
while (consumeIf('_')) {
Node *Selector = make<NameType>(parseNumber());
if (!Selector)
return nullptr;
Names.push_back(Selector);
}
bool OnePastTheEnd = consumeIf('p');
if (!consumeIf('E'))
return nullptr;
return make<SubobjectExpr>(
Ty, Expr, Offset, popTrailingNodeArray(SelectorsBegin), OnePastTheEnd);
}
// <expression> ::= <unary operator-name> <expression>
// ::= <binary operator-name> <expression> <expression>
// ::= <ternary operator-name> <expression> <expression> <expression>
@ -4661,6 +4765,9 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
return nullptr;
case 'm':
switch (First[1]) {
case 'c':
First += 2;
return parsePointerToMemberConversionExpr();
case 'i':
First += 2;
return getDerived().parseBinaryExpr("-");
@ -4808,6 +4915,9 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
return Ex;
return make<CastExpr>("static_cast", T, Ex);
}
case 'o':
First += 2;
return parseSubobjectExpr();
case 'p': {
First += 2;
Node *Child = getDerived().parseExpr();
@ -4975,6 +5085,16 @@ Node *AbstractManglingParser<Derived, Alloc>::parseSpecialName() {
switch (look()) {
case 'T':
switch (look(1)) {
// TA <template-arg> # template parameter object
//
// Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/63
case 'A': {
First += 2;
Node *Arg = getDerived().parseTemplateArg();
if (Arg == nullptr)
return nullptr;
return make<SpecialName>("template parameter object for ", Arg);
}
// TV <type> # virtual table
case 'V': {
First += 2;
@ -5103,7 +5223,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseEncoding() {
decltype(TemplateParams) OldParams;
public:
SaveTemplateParams(AbstractManglingParser *Parser) : Parser(Parser) {
SaveTemplateParams(AbstractManglingParser *TheParser) : Parser(TheParser) {
OldParams = std::move(Parser->TemplateParams);
Parser->TemplateParams.clear();
}
@ -5203,7 +5323,12 @@ struct FloatData<long double>
#else
static const size_t mangled_size = 20; // May need to be adjusted to 16 or 24 on other platforms
#endif
static const size_t max_demangled_size = 40;
// `-0x1.ffffffffffffffffffffffffffffp+16383` + 'L' + '\0' == 42 bytes.
// 28 'f's * 4 bits == 112 bits, which is the number of mantissa bits.
// Negatives are one character longer than positives.
// `0x1.` and `p` are constant, and exponents `+16383` and `-16382` are the
// same length. 1 sign bit, 112 mantissa bits, and 15 exponent bits == 128.
static const size_t max_demangled_size = 42;
static constexpr const char *spec = "%LaL";
};

View File

@ -52,7 +52,7 @@ class OutputStream {
char *TempPtr = std::end(Temp);
while (N) {
*--TempPtr = '0' + char(N % 10);
*--TempPtr = char('0' + N % 10);
N /= 10;
}

View File

@ -6,9 +6,6 @@
//
//===----------------------------------------------------------------------===//
// Define _LIBCPP_BUILDING_LIBRARY to ensure _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
// is only defined when libc aligned allocation is not available.
#define _LIBCPP_BUILDING_LIBRARY
#include "fallback_malloc.h"
#include <__threading_support>
@ -20,6 +17,7 @@
#include <stdlib.h> // for malloc, calloc, free
#include <string.h> // for memset
#include <new> // for std::__libcpp_aligned_{alloc,free}
// A small, simple heap manager based (loosely) on
// the startup heap manager from FreeBSD, optimized for space.
@ -144,29 +142,26 @@ void fallback_free(void* ptr) {
mutexor mtx(&heap_mutex);
#ifdef DEBUG_FALLBACK_MALLOC
std::cout << "Freeing item at " << offset_from_node(cp) << " of size "
<< cp->len << std::endl;
std::printf("Freeing item at %d of size %d\n", offset_from_node(cp), cp->len);
#endif
for (p = freelist, prev = 0; p && p != list_end;
prev = p, p = node_from_offset(p->next_node)) {
#ifdef DEBUG_FALLBACK_MALLOC
std::cout << " p, cp, after (p), after(cp) " << offset_from_node(p) << ' '
<< offset_from_node(cp) << ' ' << offset_from_node(after(p))
<< ' ' << offset_from_node(after(cp)) << std::endl;
std::printf(" p=%d, cp=%d, after(p)=%d, after(cp)=%d\n",
offset_from_node(p), offset_from_node(cp),
offset_from_node(after(p)), offset_from_node(after(cp)));
#endif
if (after(p) == cp) {
#ifdef DEBUG_FALLBACK_MALLOC
std::cout << " Appending onto chunk at " << offset_from_node(p)
<< std::endl;
std::printf(" Appending onto chunk at %d\n", offset_from_node(p));
#endif
p->len = static_cast<heap_size>(
p->len + cp->len); // make the free heap_node larger
return;
} else if (after(cp) == p) { // there's a free heap_node right after
#ifdef DEBUG_FALLBACK_MALLOC
std::cout << " Appending free chunk at " << offset_from_node(p)
<< std::endl;
std::printf(" Appending free chunk at %d\n", offset_from_node(p));
#endif
cp->len = static_cast<heap_size>(cp->len + p->len);
if (prev == 0) {
@ -179,8 +174,7 @@ void fallback_free(void* ptr) {
}
// Nothing to merge with, add it to the start of the free list
#ifdef DEBUG_FALLBACK_MALLOC
std::cout << " Making new free list entry " << offset_from_node(cp)
<< std::endl;
std::printf(" Making new free list entry %d\n", offset_from_node(cp));
#endif
cp->next_node = offset_from_node(freelist);
freelist = cp;
@ -195,11 +189,11 @@ size_t print_free_list() {
for (p = freelist, prev = 0; p && p != list_end;
prev = p, p = node_from_offset(p->next_node)) {
std::cout << (prev == 0 ? "" : " ") << "Offset: " << offset_from_node(p)
<< "\tsize: " << p->len << " Next: " << p->next_node << std::endl;
std::printf("%sOffset: %d\tsize: %d Next: %d\n",
(prev == 0 ? "" : " "), offset_from_node(p), p->len, p->next_node);
total_free += p->len;
}
std::cout << "Total Free space: " << total_free << std::endl;
std::printf("Total Free space: %d\n", total_free);
return total_free;
}
#endif
@ -211,7 +205,7 @@ struct __attribute__((aligned)) __aligned_type {};
void* __aligned_malloc_with_fallback(size_t size) {
#if defined(_WIN32)
if (void* dest = _aligned_malloc(size, alignof(__aligned_type)))
if (void* dest = std::__libcpp_aligned_alloc(alignof(__aligned_type), size))
return dest;
#elif defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
if (void* dest = ::malloc(size))
@ -219,8 +213,7 @@ void* __aligned_malloc_with_fallback(size_t size) {
#else
if (size == 0)
size = 1;
void* dest;
if (::posix_memalign(&dest, __alignof(__aligned_type), size) == 0)
if (void* dest = std::__libcpp_aligned_alloc(__alignof(__aligned_type), size))
return dest;
#endif
return fallback_malloc(size);
@ -241,10 +234,10 @@ void __aligned_free_with_fallback(void* ptr) {
if (is_fallback_ptr(ptr))
fallback_free(ptr);
else {
#if defined(_WIN32)
::_aligned_free(ptr);
#else
#if defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
::free(ptr);
#else
std::__libcpp_aligned_free(ptr);
#endif
}
}

View File

@ -1,131 +0,0 @@
//===------------------------ __refstring ---------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
// FIXME: This file is copied from libcxx/src/include/refstring.h. Instead of
// duplicating the file in libc++abi we should require that the libc++ sources
// are available when building libc++abi.
#ifndef _LIBCPPABI_REFSTRING_H
#define _LIBCPPABI_REFSTRING_H
#include <__config>
#include <stdexcept>
#include <cstddef>
#include <cstring>
#ifdef __APPLE__
#include <dlfcn.h>
#include <mach-o/dyld.h>
#endif
#include "atomic_support.h"
_LIBCPP_BEGIN_NAMESPACE_STD
namespace __refstring_imp { namespace {
typedef int count_t;
struct _Rep_base {
std::size_t len;
std::size_t cap;
count_t count;
};
inline _Rep_base* rep_from_data(const char *data_) noexcept {
char *data = const_cast<char *>(data_);
return reinterpret_cast<_Rep_base *>(data - sizeof(_Rep_base));
}
inline char * data_from_rep(_Rep_base *rep) noexcept {
char *data = reinterpret_cast<char *>(rep);
return data + sizeof(*rep);
}
#if defined(__APPLE__)
inline
const char* compute_gcc_empty_string_storage() _NOEXCEPT
{
void* handle = dlopen("/usr/lib/libstdc++.6.dylib", RTLD_NOLOAD);
if (handle == nullptr)
return nullptr;
void* sym = dlsym(handle, "_ZNSs4_Rep20_S_empty_rep_storageE");
if (sym == nullptr)
return nullptr;
return data_from_rep(reinterpret_cast<_Rep_base *>(sym));
}
inline
const char*
get_gcc_empty_string_storage() _NOEXCEPT
{
static const char* p = compute_gcc_empty_string_storage();
return p;
}
#endif
}} // namespace __refstring_imp
using namespace __refstring_imp;
inline
__libcpp_refstring::__libcpp_refstring(const char* msg) {
std::size_t len = strlen(msg);
_Rep_base* rep = static_cast<_Rep_base *>(::operator new(sizeof(*rep) + len + 1));
rep->len = len;
rep->cap = len;
rep->count = 0;
char *data = data_from_rep(rep);
std::memcpy(data, msg, len + 1);
__imp_ = data;
}
inline
__libcpp_refstring::__libcpp_refstring(const __libcpp_refstring &s) _NOEXCEPT
: __imp_(s.__imp_)
{
if (__uses_refcount())
__libcpp_atomic_add(&rep_from_data(__imp_)->count, 1);
}
inline
__libcpp_refstring& __libcpp_refstring::operator=(__libcpp_refstring const& s) _NOEXCEPT {
bool adjust_old_count = __uses_refcount();
struct _Rep_base *old_rep = rep_from_data(__imp_);
__imp_ = s.__imp_;
if (__uses_refcount())
__libcpp_atomic_add(&rep_from_data(__imp_)->count, 1);
if (adjust_old_count)
{
if (__libcpp_atomic_add(&old_rep->count, count_t(-1)) < 0)
{
::operator delete(old_rep);
}
}
return *this;
}
inline
__libcpp_refstring::~__libcpp_refstring() {
if (__uses_refcount()) {
_Rep_base* rep = rep_from_data(__imp_);
if (__libcpp_atomic_add(&rep->count, count_t(-1)) < 0) {
::operator delete(rep);
}
}
}
inline
bool __libcpp_refstring::__uses_refcount() const {
#ifdef __APPLE__
return __imp_ != get_gcc_empty_string_storage();
#else
return true;
#endif
}
_LIBCPP_END_NAMESPACE_STD
#endif //_LIBCPPABI_REFSTRING_H

View File

@ -61,6 +61,16 @@ is_equal(const std::type_info* x, const std::type_info* y, bool use_strcmp)
return x == y || strcmp(x->name(), y->name()) == 0;
}
static inline ptrdiff_t update_offset_to_base(const char* vtable,
ptrdiff_t offset_to_base) {
#if __has_feature(cxx_abi_relative_vtable)
// VTable components are 32 bits in the relative vtables ABI.
return *reinterpret_cast<const int32_t*>(vtable + offset_to_base);
#else
return *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base);
#endif
}
namespace __cxxabiv1
{
@ -297,7 +307,7 @@ __base_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info,
if (__offset_flags & __virtual_mask)
{
const char* vtable = *static_cast<const char*const*>(adjustedPtr);
offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base);
offset_to_base = update_offset_to_base(vtable, offset_to_base);
}
}
__base_type->has_unambiguous_public_base(
@ -615,10 +625,26 @@ __dynamic_cast(const void *static_ptr, const __class_type_info *static_type,
// Possible future optimization: Take advantage of src2dst_offset
// Get (dynamic_ptr, dynamic_type) from static_ptr
#if __has_feature(cxx_abi_relative_vtable)
// The vtable address will point to the first virtual function, which is 8
// bytes after the start of the vtable (4 for the offset from top + 4 for the typeinfo component).
const int32_t* vtable =
*reinterpret_cast<const int32_t* const*>(static_ptr);
int32_t offset_to_derived = vtable[-2];
const void* dynamic_ptr = static_cast<const char*>(static_ptr) + offset_to_derived;
// The typeinfo component is now a relative offset to a proxy.
int32_t offset_to_ti_proxy = vtable[-1];
const uint8_t* ptr_to_ti_proxy =
reinterpret_cast<const uint8_t*>(vtable) + offset_to_ti_proxy;
const __class_type_info* dynamic_type =
*(reinterpret_cast<const __class_type_info* const*>(ptr_to_ti_proxy));
#else
void **vtable = *static_cast<void ** const *>(static_ptr);
ptrdiff_t offset_to_derived = reinterpret_cast<ptrdiff_t>(vtable[-2]);
const void* dynamic_ptr = static_cast<const char*>(static_ptr) + offset_to_derived;
const __class_type_info* dynamic_type = static_cast<const __class_type_info*>(vtable[-1]);
#endif
// Initialize answer to nullptr. This will be changed from the search
// results if a non-null answer is found. Regardless, this is what will
@ -641,6 +667,7 @@ __dynamic_cast(const void *static_ptr, const __class_type_info *static_type,
{
// We get here only if there is some kind of visibility problem
// in client code.
static_assert(std::atomic<size_t>::is_always_lock_free, "");
static std::atomic<size_t> error_count(0);
size_t error_count_snapshot = error_count.fetch_add(1, std::memory_order_relaxed);
if ((error_count_snapshot & (error_count_snapshot-1)) == 0)
@ -667,6 +694,7 @@ __dynamic_cast(const void *static_ptr, const __class_type_info *static_type,
if (info.path_dst_ptr_to_static_ptr == unknown &&
info.path_dynamic_ptr_to_static_ptr == unknown)
{
static_assert(std::atomic<size_t>::is_always_lock_free, "");
static std::atomic<size_t> error_count(0);
size_t error_count_snapshot = error_count.fetch_add(1, std::memory_order_relaxed);
if ((error_count_snapshot & (error_count_snapshot-1)) == 0)
@ -1265,7 +1293,7 @@ __base_class_type_info::search_above_dst(__dynamic_cast_info* info,
if (__offset_flags & __virtual_mask)
{
const char* vtable = *static_cast<const char*const*>(current_ptr);
offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base);
offset_to_base = update_offset_to_base(vtable, offset_to_base);
}
__base_type->search_above_dst(info, dst_ptr,
static_cast<const char*>(current_ptr) + offset_to_base,
@ -1285,7 +1313,7 @@ __base_class_type_info::search_below_dst(__dynamic_cast_info* info,
if (__offset_flags & __virtual_mask)
{
const char* vtable = *static_cast<const char*const*>(current_ptr);
offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base);
offset_to_base = update_offset_to_base(vtable, offset_to_base);
}
__base_type->search_below_dst(info,
static_cast<const char*>(current_ptr) + offset_to_base,

View File

@ -6,7 +6,6 @@
//
//===----------------------------------------------------------------------===//
#define _LIBCPP_BUILDING_LIBRARY
#include <new>
#include <exception>

View File

@ -8,7 +8,6 @@
// This file implements the new and delete operators.
//===----------------------------------------------------------------------===//
#define _LIBCPP_BUILDING_LIBRARY
#include "__cxxabi_config.h"
#include <new>
#include <cstdlib>
@ -28,7 +27,7 @@ operator new(std::size_t size) _THROW_BAD_ALLOC
if (size == 0)
size = 1;
void* p;
while ((p = ::malloc(size)) == 0)
while ((p = ::malloc(size)) == nullptr)
{
// If malloc fails and there is a new_handler,
// call it to try free up memory.
@ -49,7 +48,7 @@ _LIBCXXABI_WEAK
void*
operator new(size_t size, const std::nothrow_t&) _NOEXCEPT
{
void* p = 0;
void* p = nullptr;
#ifndef _LIBCXXABI_NO_EXCEPTIONS
try
{
@ -75,7 +74,7 @@ _LIBCXXABI_WEAK
void*
operator new[](size_t size, const std::nothrow_t&) _NOEXCEPT
{
void* p = 0;
void* p = nullptr;
#ifndef _LIBCXXABI_NO_EXCEPTIONS
try
{
@ -143,15 +142,16 @@ operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
size = 1;
if (static_cast<size_t>(alignment) < sizeof(void*))
alignment = std::align_val_t(sizeof(void*));
// Try allocating memory. If allocation fails and there is a new_handler,
// call it to try free up memory, and try again until it succeeds, or until
// the new_handler decides to terminate.
//
// If allocation fails and there is no new_handler, we throw bad_alloc
// (or return nullptr if exceptions are disabled).
void* p;
#if defined(_LIBCPP_WIN32API)
while ((p = _aligned_malloc(size, static_cast<size_t>(alignment))) == nullptr)
#else
while (::posix_memalign(&p, static_cast<size_t>(alignment), size) != 0)
#endif
while ((p = std::__libcpp_aligned_alloc(static_cast<std::size_t>(alignment), size)) == nullptr)
{
// If posix_memalign fails and there is a new_handler,
// call it to try free up memory.
std::new_handler nh = std::get_new_handler();
if (nh)
nh();
@ -159,7 +159,6 @@ operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
#ifndef _LIBCXXABI_NO_EXCEPTIONS
throw std::bad_alloc();
#else
p = nullptr; // posix_memalign doesn't initialize 'p' on failure
break;
#endif
}
@ -171,7 +170,7 @@ _LIBCXXABI_WEAK
void*
operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
{
void* p = 0;
void* p = nullptr;
#ifndef _LIBCXXABI_NO_EXCEPTIONS
try
{
@ -197,7 +196,7 @@ _LIBCXXABI_WEAK
void*
operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
{
void* p = 0;
void* p = nullptr;
#ifndef _LIBCXXABI_NO_EXCEPTIONS
try
{
@ -216,12 +215,9 @@ _LIBCXXABI_WEAK
void
operator delete(void* ptr, std::align_val_t) _NOEXCEPT
{
if (ptr)
#if defined(_LIBCPP_WIN32API)
::_aligned_free(ptr);
#else
::free(ptr);
#endif
if (ptr) {
std::__libcpp_aligned_free(ptr);
}
}
_LIBCXXABI_WEAK

View File

@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
#include "include/refstring.h"
#include "../../libcxx/src/include/refstring.h"
#include "stdexcept"
#include "new"
#include <cstdlib>