From 554fd8c5195424bdbcabf5de30fdc183aba391bd Mon Sep 17 00:00:00 2001 From: upstream source tree Date: Sun, 15 Mar 2015 20:14:05 -0400 Subject: obtained gcc-4.6.4.tar.bz2 from upstream website; verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository. --- libstdc++-v3/libsupc++/vec.cc | 516 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 516 insertions(+) create mode 100644 libstdc++-v3/libsupc++/vec.cc (limited to 'libstdc++-v3/libsupc++/vec.cc') diff --git a/libstdc++-v3/libsupc++/vec.cc b/libstdc++-v3/libsupc++/vec.cc new file mode 100644 index 000000000..700c5ef43 --- /dev/null +++ b/libstdc++-v3/libsupc++/vec.cc @@ -0,0 +1,516 @@ +// New abi Support -*- C++ -*- + +// Copyright (C) 2000, 2001, 2003, 2004, 2009, 2011 +// Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// GCC is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3, or (at your option) +// any later version. + +// GCC is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +// Written by Nathan Sidwell, Codesourcery LLC, + +#include +#include +#include +#include +#include "unwind-cxx.h" + +namespace __cxxabiv1 +{ + namespace + { + struct uncatch_exception + { + uncatch_exception(); + ~uncatch_exception () { __cxa_begin_catch (&p->unwindHeader); } + + __cxa_exception* p; + + private: + uncatch_exception& + operator=(const uncatch_exception&); + + uncatch_exception(const uncatch_exception&); + }; + + uncatch_exception::uncatch_exception() : p(0) + { + __cxa_eh_globals *globals = __cxa_get_globals_fast (); + + p = globals->caughtExceptions; + p->handlerCount -= 1; + globals->caughtExceptions = p->nextException; + globals->uncaughtExceptions += 1; + } + } + + // Allocate and construct array. + extern "C" void * + __cxa_vec_new(std::size_t element_count, + std::size_t element_size, + std::size_t padding_size, + __cxa_cdtor_type constructor, + __cxa_cdtor_type destructor) + { + return __cxa_vec_new2(element_count, element_size, padding_size, + constructor, destructor, + &operator new[], &operator delete []); + } + + extern "C" void * + __cxa_vec_new2(std::size_t element_count, + std::size_t element_size, + std::size_t padding_size, + __cxa_cdtor_type constructor, + __cxa_cdtor_type destructor, + void *(*alloc) (std::size_t), + void (*dealloc) (void *)) + { + std::size_t size = element_count * element_size + padding_size; + char *base = static_cast (alloc (size)); + if (!base) + return base; + + if (padding_size) + { + base += padding_size; + reinterpret_cast (base)[-1] = element_count; +#ifdef _GLIBCXX_ELTSIZE_IN_COOKIE + reinterpret_cast (base)[-2] = element_size; +#endif + } + __try + { + __cxa_vec_ctor(base, element_count, element_size, + constructor, destructor); + } + __catch(...) + { + { + uncatch_exception ue; + // Core issue 901 will probably be resolved such that a + // deleted operator delete means not freeing memory here. + if (dealloc) + dealloc(base - padding_size); + } + __throw_exception_again; + } + return base; + } + + extern "C" void * + __cxa_vec_new3(std::size_t element_count, + std::size_t element_size, + std::size_t padding_size, + __cxa_cdtor_type constructor, + __cxa_cdtor_type destructor, + void *(*alloc) (std::size_t), + void (*dealloc) (void *, std::size_t)) + { + std::size_t size = element_count * element_size + padding_size; + char *base = static_cast(alloc (size)); + if (!base) + return base; + + if (padding_size) + { + base += padding_size; + reinterpret_cast(base)[-1] = element_count; +#ifdef _GLIBCXX_ELTSIZE_IN_COOKIE + reinterpret_cast (base)[-2] = element_size; +#endif + } + __try + { + __cxa_vec_ctor(base, element_count, element_size, + constructor, destructor); + } + __catch(...) + { + { + uncatch_exception ue; + if (dealloc) + dealloc(base - padding_size, size); + } + __throw_exception_again; + } + return base; + } + + // Construct array. + extern "C" __cxa_vec_ctor_return_type + __cxa_vec_ctor(void *array_address, + std::size_t element_count, + std::size_t element_size, + __cxa_cdtor_type constructor, + __cxa_cdtor_type destructor) + { + std::size_t ix = 0; + char *ptr = static_cast(array_address); + + __try + { + if (constructor) + for (; ix != element_count; ix++, ptr += element_size) + constructor(ptr); + } + __catch(...) + { + { + uncatch_exception ue; + __cxa_vec_cleanup(array_address, ix, element_size, destructor); + } + __throw_exception_again; + } + _GLIBCXX_CXA_VEC_CTOR_RETURN (array_address); + } + + // Construct an array by copying. + extern "C" __cxa_vec_ctor_return_type + __cxa_vec_cctor(void *dest_array, + void *src_array, + std::size_t element_count, + std::size_t element_size, + __cxa_cdtor_return_type (*constructor) (void *, void *), + __cxa_cdtor_type destructor) + { + std::size_t ix = 0; + char *dest_ptr = static_cast(dest_array); + char *src_ptr = static_cast(src_array); + + __try + { + if (constructor) + for (; ix != element_count; + ix++, src_ptr += element_size, dest_ptr += element_size) + constructor(dest_ptr, src_ptr); + } + __catch(...) + { + { + uncatch_exception ue; + __cxa_vec_cleanup(dest_array, ix, element_size, destructor); + } + __throw_exception_again; + } + _GLIBCXX_CXA_VEC_CTOR_RETURN (dest_array); + } + + // Destruct array. + extern "C" void + __cxa_vec_dtor(void *array_address, + std::size_t element_count, + std::size_t element_size, + __cxa_cdtor_type destructor) + { + if (destructor) + { + char *ptr = static_cast(array_address); + std::size_t ix = element_count; + + ptr += element_count * element_size; + + __try + { + while (ix--) + { + ptr -= element_size; + destructor(ptr); + } + } + __catch(...) + { + { + uncatch_exception ue; + __cxa_vec_cleanup(array_address, ix, element_size, destructor); + } + __throw_exception_again; + } + } + } + + // Destruct array as a result of throwing an exception. + // [except.ctor]/3 If a destructor called during stack unwinding + // exits with an exception, terminate is called. + extern "C" void + __cxa_vec_cleanup(void *array_address, + std::size_t element_count, + std::size_t element_size, + __cxa_cdtor_type destructor) throw() + { + if (destructor) + { + char *ptr = static_cast (array_address); + std::size_t ix = element_count; + + ptr += element_count * element_size; + + __try + { + while (ix--) + { + ptr -= element_size; + destructor(ptr); + } + } + __catch(...) + { + std::terminate(); + } + } + } + + // Destruct and release array. + extern "C" void + __cxa_vec_delete(void *array_address, + std::size_t element_size, + std::size_t padding_size, + __cxa_cdtor_type destructor) + { + __cxa_vec_delete2(array_address, element_size, padding_size, + destructor, + &operator delete []); + } + + extern "C" void + __cxa_vec_delete2(void *array_address, + std::size_t element_size, + std::size_t padding_size, + __cxa_cdtor_type destructor, + void (*dealloc) (void *)) + { + if (!array_address) + return; + + char* base = static_cast(array_address); + + if (padding_size) + { + std::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 ue; + dealloc(base); + } + __throw_exception_again; + } + } + dealloc(base); + } + + extern "C" void + __cxa_vec_delete3(void *array_address, + std::size_t element_size, + std::size_t padding_size, + __cxa_cdtor_type destructor, + void (*dealloc) (void *, std::size_t)) + { + if (!array_address) + return; + + char* base = static_cast (array_address); + std::size_t size = 0; + + if (padding_size) + { + std::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, + destructor); + } + __catch(...) + { + { + uncatch_exception ue; + dealloc(base, size); + } + __throw_exception_again; + } + } + dealloc(base, size); + } +} // namespace __cxxabiv1 + +#if defined(__arm__) && defined(__ARM_EABI__) + +// The ARM C++ ABI requires that the library provide these additional +// helper functions. There are placed in this file, despite being +// architecture-specifier, so that the compiler can inline the __cxa +// functions into these functions as appropriate. + +namespace __aeabiv1 +{ + extern "C" void * + __aeabi_vec_ctor_nocookie_nodtor (void *array_address, + abi::__cxa_cdtor_type constructor, + std::size_t element_size, + std::size_t element_count) + { + return abi::__cxa_vec_ctor (array_address, element_count, element_size, + constructor, /*destructor=*/NULL); + } + + extern "C" void * + __aeabi_vec_ctor_cookie_nodtor (void *array_address, + abi::__cxa_cdtor_type constructor, + std::size_t element_size, + std::size_t element_count) + { + if (array_address == NULL) + return NULL; + + array_address = reinterpret_cast(array_address) + 2; + reinterpret_cast(array_address)[-2] = element_size; + reinterpret_cast(array_address)[-1] = element_count; + return abi::__cxa_vec_ctor (array_address, + element_count, element_size, + constructor, /*destructor=*/NULL); + } + + extern "C" void * + __aeabi_vec_cctor_nocookie_nodtor (void *dest_array, + void *src_array, + std::size_t element_size, + std::size_t element_count, + void *(*constructor) (void *, void *)) + { + return abi::__cxa_vec_cctor (dest_array, src_array, + element_count, element_size, + constructor, NULL); + } + + extern "C" void * + __aeabi_vec_new_cookie_noctor (std::size_t element_size, + std::size_t element_count) + { + return abi::__cxa_vec_new(element_count, element_size, + 2 * sizeof (std::size_t), + /*constructor=*/NULL, /*destructor=*/NULL); + } + + extern "C" void * + __aeabi_vec_new_nocookie (std::size_t element_size, + std::size_t element_count, + abi::__cxa_cdtor_type constructor) + { + return abi::__cxa_vec_new (element_count, element_size, 0, constructor, + NULL); + } + + extern "C" void * + __aeabi_vec_new_cookie_nodtor (std::size_t element_size, + std::size_t element_count, + abi::__cxa_cdtor_type constructor) + { + return abi::__cxa_vec_new(element_count, element_size, + 2 * sizeof (std::size_t), + constructor, NULL); + } + + extern "C" void * + __aeabi_vec_new_cookie(std::size_t element_size, + std::size_t element_count, + abi::__cxa_cdtor_type constructor, + abi::__cxa_cdtor_type destructor) + { + return abi::__cxa_vec_new (element_count, element_size, + 2 * sizeof (std::size_t), + constructor, destructor); + } + + + extern "C" void * + __aeabi_vec_dtor (void *array_address, + abi::__cxa_cdtor_type destructor, + std::size_t element_size, + std::size_t element_count) + { + abi::__cxa_vec_dtor (array_address, element_count, element_size, + destructor); + return reinterpret_cast (array_address) - 2; + } + + extern "C" void * + __aeabi_vec_dtor_cookie (void *array_address, + abi::__cxa_cdtor_type destructor) + { + if (!array_address) + return NULL; + + abi::__cxa_vec_dtor (array_address, + reinterpret_cast(array_address)[-1], + reinterpret_cast(array_address)[-2], + destructor); + return reinterpret_cast (array_address) - 2; + } + + + extern "C" void + __aeabi_vec_delete (void *array_address, + abi::__cxa_cdtor_type destructor) + { + if (!array_address) + return; + + abi::__cxa_vec_delete (array_address, + reinterpret_cast(array_address)[-2], + 2 * sizeof (std::size_t), + destructor); + } + + extern "C" void + __aeabi_vec_delete3 (void *array_address, + abi::__cxa_cdtor_type destructor, + void (*dealloc) (void *, std::size_t)) + { + if (!array_address) + return; + + abi::__cxa_vec_delete3 (array_address, + reinterpret_cast(array_address)[-2], + 2 * sizeof (std::size_t), + destructor, dealloc); + } + + extern "C" void + __aeabi_vec_delete3_nodtor (void *array_address, + void (*dealloc) (void *, std::size_t)) + { + if (!array_address) + return; + + abi::__cxa_vec_delete3 (array_address, + reinterpret_cast(array_address)[-2], + 2 * sizeof (std::size_t), + /*destructor=*/NULL, dealloc); + } +} // namespace __aeabiv1 + +#endif // defined(__arm__) && defined(__ARM_EABI__) -- cgit v1.2.3