From d13b34e98af1a59ef4b4c7ed9058227bc8f97314 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Thu, 17 Aug 2000 15:05:43 +0000 Subject: cxxabi.h (__cxa_vec_new2, [...]): Declare. * inc/cxxabi.h (__cxa_vec_new2, __cxa_vec_new3): Declare. (__cxa_vec_delete2, __cxa_vec_delete3): Declare. * vec.cc (__cxa_vec_new2, __cxa_vec_new3): Implement. (__cxa_vec_delete2, __cxa_vec_delete3): Implement. (__cxa_vec_new): Use __cxa_vec_new2. (__cxa_vec_delete): Use __cxa_vec_delete2. From-SVN: r35761 --- gcc/cp/ChangeLog | 9 +++++ gcc/cp/inc/cxxabi.h | 32 +++++++++++++++++ gcc/cp/vec.cc | 101 ++++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 135 insertions(+), 7 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 810fa52..e2248aa 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,14 @@ 2000-08-17 Nathan Sidwell + * inc/cxxabi.h (__cxa_vec_new2, __cxa_vec_new3): Declare. + (__cxa_vec_delete2, __cxa_vec_delete3): Declare. + * vec.cc (__cxa_vec_new2, __cxa_vec_new3): Implement. + (__cxa_vec_delete2, __cxa_vec_delete3): Implement. + (__cxa_vec_new): Use __cxa_vec_new2. + (__cxa_vec_delete): Use __cxa_vec_delete2. + +2000-08-17 Nathan Sidwell + * vec.cc (__cxa_vec_new): Set "C" linkage. (__cxa_vec_ctor): Likewise. (__cxa_vec_cctor): Likewise. diff --git a/gcc/cp/inc/cxxabi.h b/gcc/cp/inc/cxxabi.h index 2a7217f..908d7c4 100644 --- a/gcc/cp/inc/cxxabi.h +++ b/gcc/cp/inc/cxxabi.h @@ -437,6 +437,24 @@ void *__cxa_vec_new (__SIZE_TYPE__ __element_count, void (*__constructor) (void *), void (*__destructor) (void *)); +extern "C" +void *__cxa_vec_new2 (__SIZE_TYPE__ __element_count, + __SIZE_TYPE__ __element_size, + __SIZE_TYPE__ __padding_size, + void (*__constructor) (void *), + void (*__destructor) (void *), + void *(*__alloc) (__SIZE_TYPE__), + void (*__dealloc) (void *)); + +extern "C" +void *__cxa_vec_new3 (__SIZE_TYPE__ __element_count, + __SIZE_TYPE__ __element_size, + __SIZE_TYPE__ __padding_size, + void (*__constructor) (void *), + void (*__destructor) (void *), + void *(*__alloc) (__SIZE_TYPE__), + void (*__dealloc) (void *, __SIZE_TYPE__)); + /* construct array */ extern "C" void __cxa_vec_ctor (void *__array_address, @@ -467,6 +485,20 @@ void __cxa_vec_delete (void *__array_address, __SIZE_TYPE__ __padding_size, void (*__destructor) (void *)); +extern "C" +void __cxa_vec_delete2 (void *__array_address, + __SIZE_TYPE__ __element_size, + __SIZE_TYPE__ __padding_size, + void (*__destructor) (void *), + void (*__dealloc) (void *)); + +extern "C" +void __cxa_vec_delete3 (void *__array_address, + __SIZE_TYPE__ __element_size, + __SIZE_TYPE__ __padding_size, + void (*__destructor) (void *), + void (*__dealloc) (void *, __SIZE_TYPE__)); + /* demangling routines */ extern "C" diff --git a/gcc/cp/vec.cc b/gcc/cp/vec.cc index 8318597..966feb4 100644 --- a/gcc/cp/vec.cc +++ b/gcc/cp/vec.cc @@ -47,8 +47,22 @@ __cxa_vec_new (size_t element_count, void (*constructor) (void *), void (*destructor) (void *)) { + return __cxa_vec_new2 (element_count, element_size, padding_size, + constructor, destructor, + &operator new[], &operator delete []); +} + +extern "C" void * +__cxa_vec_new2 (size_t element_count, + size_t element_size, + size_t padding_size, + void (*constructor) (void *), + void (*destructor) (void *), + void *(*alloc) (size_t), + void (*dealloc) (void *)) +{ size_t size = element_count * element_size + padding_size; - char *base = static_cast (operator new[] (size)); + char *base = static_cast (alloc (size)); if (padding_size) { @@ -62,8 +76,39 @@ __cxa_vec_new (size_t element_count, } catch (...) { - // operator delete [] cannot throw, so no need to protect it - operator delete[] (base - padding_size); + __uncatch_exception (); + dealloc (base - padding_size); + throw; + } + return base; +} + +extern "C" void * +__cxa_vec_new3 (size_t element_count, + size_t element_size, + size_t padding_size, + void (*constructor) (void *), + void (*destructor) (void *), + void *(*alloc) (size_t), + void (*dealloc) (void *, size_t)) +{ + size_t size = element_count * element_size + padding_size; + char *base = static_cast (alloc (size)); + + if (padding_size) + { + base += padding_size; + reinterpret_cast (base)[-1] = element_count; + } + try + { + __cxa_vec_ctor (base, element_count, element_size, + constructor, destructor); + } + catch (...) + { + __uncatch_exception (); + dealloc (base - padding_size, size); throw; } return base; @@ -150,7 +195,7 @@ __cxa_vec_dtor (void *array_address, { if (unwinding) // [except.ctor]/3 If a destructor called during stack unwinding - // exists with an exception, terminate is called. + // exits with an exception, terminate is called. std::terminate (); __uncatch_exception (); __cxa_vec_dtor (array_address, ix, element_size, destructor); @@ -166,12 +211,54 @@ __cxa_vec_delete (void *array_address, size_t padding_size, void (*destructor) (void *)) { + __cxa_vec_delete2 (array_address, element_size, padding_size, + destructor, + &operator delete []); +} + +extern "C" void +__cxa_vec_delete2 (void *array_address, + size_t element_size, + size_t padding_size, + void (*destructor) (void *), + void (*dealloc) (void *)) +{ + char *base = static_cast (array_address); + + if (padding_size) + { + size_t element_count = reinterpret_cast (base)[-1]; + base -= padding_size; + try + { + __cxa_vec_dtor (array_address, element_count, element_size, + destructor); + } + catch (...) + { + __uncatch_exception (); + dealloc (base); + throw; + } + } + dealloc (base); +} + +extern "C" void +__cxa_vec_delete3 (void *array_address, + size_t element_size, + size_t padding_size, + void (*destructor) (void *), + void (*dealloc) (void *, size_t)) +{ char *base = static_cast (array_address); + size_t size = 0; if (padding_size) { size_t element_count = reinterpret_cast (base)[-1]; base -= padding_size; + size = element_count * element_size + padding_size; try { __cxa_vec_dtor (array_address, element_count, element_size, @@ -179,12 +266,12 @@ __cxa_vec_delete (void *array_address, } catch (...) { - // operator delete [] cannot throw, so no need to protect it - operator delete[] (base); + __uncatch_exception (); + dealloc (base, size); throw; } } - operator delete[] (base); + dealloc (base, size); } } // namespace __cxxabiv1 -- cgit v1.1