diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /libstdc++-v3/libsupc++/vec.cc | |
download | cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2 cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
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.
Diffstat (limited to 'libstdc++-v3/libsupc++/vec.cc')
-rw-r--r-- | libstdc++-v3/libsupc++/vec.cc | 516 |
1 files changed, 516 insertions, 0 deletions
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 +// <http://www.gnu.org/licenses/>. + +// Written by Nathan Sidwell, Codesourcery LLC, <nathan@codesourcery.com> + +#include <cxxabi.h> +#include <new> +#include <exception> +#include <bits/exception_defines.h> +#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 <char *> (alloc (size)); + if (!base) + return base; + + if (padding_size) + { + base += padding_size; + reinterpret_cast <std::size_t *> (base)[-1] = element_count; +#ifdef _GLIBCXX_ELTSIZE_IN_COOKIE + reinterpret_cast <std::size_t *> (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<char *>(alloc (size)); + if (!base) + return base; + + if (padding_size) + { + base += padding_size; + reinterpret_cast<std::size_t *>(base)[-1] = element_count; +#ifdef _GLIBCXX_ELTSIZE_IN_COOKIE + reinterpret_cast <std::size_t *> (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<char *>(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<char *>(dest_array); + char *src_ptr = static_cast<char *>(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<char *>(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 <char *> (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<char *>(array_address); + + if (padding_size) + { + std::size_t element_count = reinterpret_cast<std::size_t *>(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 <char *> (array_address); + std::size_t size = 0; + + if (padding_size) + { + std::size_t element_count = reinterpret_cast<std::size_t *> (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<std::size_t *>(array_address) + 2; + reinterpret_cast<std::size_t *>(array_address)[-2] = element_size; + reinterpret_cast<std::size_t *>(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<std::size_t*> (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<std::size_t *>(array_address)[-1], + reinterpret_cast<std::size_t *>(array_address)[-2], + destructor); + return reinterpret_cast<std::size_t*> (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<std::size_t *>(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<std::size_t *>(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<std::size_t *>(array_address)[-2], + 2 * sizeof (std::size_t), + /*destructor=*/NULL, dealloc); + } +} // namespace __aeabiv1 + +#endif // defined(__arm__) && defined(__ARM_EABI__) |