Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP2:GA
cross-ppc-gcc48-icecream-backend.1215
gcc48-bnc889990.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File gcc48-bnc889990.patch of Package cross-ppc-gcc48-icecream-backend.1215
r220201 | rguenth | 2015-01-28 10:53:39 +0100 (Wed, 28 Jan 2015) | 9 lines 2015-01-28 Richard Biener <rguenther@suse.de> PR libstdc++/64798 * libsupc++/eh_alloc.cc (struct allocated_entry): Align data member. (pool::allocate): Adjust allocation size and alignment to that change. (pool::free): Adjust pointer offsetting. r219988 | rguenth | 2015-01-22 10:21:48 +0100 (Thu, 22 Jan 2015) | 20 lines 2015-01-22 Richard Biener <rguenther@suse.de> PR libstdc++/64535 * libsupc++/eh_alloc.cc: Include new. (bitmask_type): Remove. (one_buffer): Likewise. (emergency_buffer): Likewise. (emergency_used): Likewise. (dependents_buffer): Likewise. (dependents_used): Likewise. (class pool): New custom fixed-size arena, variable size object allocator. (emergency_pool): New global. (__cxxabiv1::__cxa_allocate_exception): Use new emergency_pool. (__cxxabiv1::__cxa_free_exception): Likewise. (__cxxabiv1::__cxa_allocate_dependent_exception): Likewise. (__cxxabiv1::__cxa_free_dependent_exception): Likewise. * g++.old-deja/g++.eh/badalloc1.C: Adjust. *** gcc-4_8-branch/libstdc++-v3/libsupc++/eh_alloc.cc Mon Feb 3 10:38:52 2014 --- trunk/libstdc++-v3/libsupc++/eh_alloc.cc Wed Jan 28 12:37:44 2015 *************** *** 1,5 **** // -*- C++ -*- Allocate exception objects. ! // Copyright (C) 2001-2013 Free Software Foundation, Inc. // // This file is part of GCC. // --- 1,5 ---- // -*- C++ -*- Allocate exception objects. ! // Copyright (C) 2001-2015 Free Software Foundation, Inc. // // This file is part of GCC. // *************** *** 34,39 **** --- 34,40 ---- #include <exception> #include "unwind-cxx.h" #include <ext/concurrence.h> + #include <new> #if _GLIBCXX_HOSTED using std::free; *************** *** 72,133 **** # define EMERGENCY_OBJ_COUNT 4 #endif - #if INT_MAX == 32767 || EMERGENCY_OBJ_COUNT <= 32 - typedef unsigned int bitmask_type; - #else - #if defined (_GLIBCXX_LLP64) - typedef unsigned long long bitmask_type; - #else - typedef unsigned long bitmask_type; - #endif - #endif ! typedef char one_buffer[EMERGENCY_OBJ_SIZE] __attribute__((aligned)); ! static one_buffer emergency_buffer[EMERGENCY_OBJ_COUNT]; ! static bitmask_type emergency_used; ! static __cxa_dependent_exception dependents_buffer[EMERGENCY_OBJ_COUNT]; ! static bitmask_type dependents_used; ! namespace ! { ! // A single mutex controlling emergency allocations. ! __gnu_cxx::__mutex emergency_mutex; ! } ! extern "C" void * ! __cxxabiv1::__cxa_allocate_exception(std::size_t thrown_size) _GLIBCXX_NOTHROW ! { ! void *ret; ! thrown_size += sizeof (__cxa_refcounted_exception); ! ret = malloc (thrown_size); ! if (! ret) { __gnu_cxx::__scoped_lock sentry(emergency_mutex); ! bitmask_type used = emergency_used; ! unsigned int which = 0; ! ! if (thrown_size > EMERGENCY_OBJ_SIZE) ! goto failed; ! while (used & 1) { ! used >>= 1; ! if (++which >= EMERGENCY_OBJ_COUNT) ! goto failed; } ! emergency_used |= (bitmask_type)1 << which; ! ret = &emergency_buffer[which][0]; ! failed:; ! if (!ret) ! std::terminate (); ! } memset (ret, 0, sizeof (__cxa_refcounted_exception)); --- 73,262 ---- # define EMERGENCY_OBJ_COUNT 4 #endif + namespace + { + // A fixed-size heap, variable size object allocator + class pool + { + public: + pool(); ! void *allocate (std::size_t); ! void free (void *); ! bool in_pool (void *); ! private: ! struct free_entry { ! std::size_t size; ! free_entry *next; ! }; ! struct allocated_entry { ! std::size_t size; ! char data[] __attribute__((aligned)); ! }; ! ! // A single mutex controlling emergency allocations. ! __gnu_cxx::__mutex emergency_mutex; ! ! // The free-list ! free_entry *first_free_entry; ! // The arena itself - we need to keep track of these only ! // to implement in_pool. ! char *arena; ! std::size_t arena_size; ! }; ! pool::pool() ! { ! // Allocate the arena - we could add a GLIBCXX_EH_ARENA_SIZE environment ! // to make this tunable. ! arena_size = (EMERGENCY_OBJ_SIZE * EMERGENCY_OBJ_COUNT ! + EMERGENCY_OBJ_COUNT * sizeof (__cxa_dependent_exception)); ! arena = (char *)malloc (arena_size); ! if (!arena) ! { ! // If the allocation failed go without an emergency pool. ! arena_size = 0; ! first_free_entry = NULL; ! return; ! } ! // Populate the free-list with a single entry covering the whole arena ! first_free_entry = reinterpret_cast <free_entry *> (arena); ! new (first_free_entry) free_entry; ! first_free_entry->size = arena_size; ! first_free_entry->next = NULL; ! } ! void *pool::allocate (std::size_t size) { __gnu_cxx::__scoped_lock sentry(emergency_mutex); + // We need an additional size_t member plus the padding to + // ensure proper alignment of data. + size += offsetof (allocated_entry, data); + // And we need to at least hand out objects of the size of + // a freelist entry. + if (size < sizeof (free_entry)) + size = sizeof (free_entry); + // And we need to align objects we hand out to the maximum + // alignment required on the target (this really aligns the + // tail which will become a new freelist entry). + size = ((size + __alignof__ (allocated_entry::data) - 1) + & ~(__alignof__ (allocated_entry::data) - 1)); + // Search for an entry of proper size on the freelist. + free_entry **e; + for (e = &first_free_entry; + *e && (*e)->size < size; + e = &(*e)->next) + ; + if (!*e) + return NULL; + allocated_entry *x; + if ((*e)->size - size >= sizeof (free_entry)) + { + // Slit block if it is too large. + free_entry *f = reinterpret_cast <free_entry *> + (reinterpret_cast <char *> (*e) + size); + std::size_t sz = (*e)->size; + free_entry *next = (*e)->next; + new (f) free_entry; + f->next = next; + f->size = sz - size; + x = reinterpret_cast <allocated_entry *> (*e); + new (x) allocated_entry; + x->size = size; + *e = f; + } + else + { + // Exact size match or too small overhead for a free entry. + std::size_t sz = (*e)->size; + free_entry *next = (*e)->next; + x = reinterpret_cast <allocated_entry *> (*e); + new (x) allocated_entry; + x->size = sz; + *e = next; + } + return &x->data; + } ! void pool::free (void *data) ! { ! __gnu_cxx::__scoped_lock sentry(emergency_mutex); ! allocated_entry *e = reinterpret_cast <allocated_entry *> ! (reinterpret_cast <char *> (data) - offsetof (allocated_entry, data)); ! std::size_t sz = e->size; ! if (!first_free_entry) ! { ! // If the free list is empty just put the entry there. ! free_entry *f = reinterpret_cast <free_entry *> (e); ! new (f) free_entry; ! f->size = sz; ! f->next = NULL; ! first_free_entry = f; ! } ! else if (reinterpret_cast <char *> (e) + sz ! == reinterpret_cast <char *> (first_free_entry)) ! { ! // Check if we can merge with the first free entry being right ! // after us. ! free_entry *f = reinterpret_cast <free_entry *> (e); ! new (f) free_entry; ! f->size = sz + first_free_entry->size; ! f->next = first_free_entry->next; ! first_free_entry = f; ! } ! else { ! // Else search for a free item we can merge with at its end. ! free_entry **fe; ! for (fe = &first_free_entry; ! (*fe)->next ! && (reinterpret_cast <char *> ((*fe)->next) ! > reinterpret_cast <char *> (e) + sz); ! fe = &(*fe)->next) ! ; ! if (reinterpret_cast <char *> (*fe) + (*fe)->size ! == reinterpret_cast <char *> (e)) ! /* Merge with the freelist entry. */ ! (*fe)->size += sz; ! else ! { ! // Else put it after it which keeps the freelist sorted. ! free_entry *f = reinterpret_cast <free_entry *> (e); ! new (f) free_entry; ! f->size = sz; ! f->next = (*fe)->next; ! (*fe)->next = f; ! } } + } ! bool pool::in_pool (void *ptr) ! { ! char *p = reinterpret_cast <char *> (ptr); ! return (p > arena ! && p < arena + arena_size); ! } ! pool emergency_pool; ! } ! extern "C" void * ! __cxxabiv1::__cxa_allocate_exception(std::size_t thrown_size) _GLIBCXX_NOTHROW ! { ! void *ret; ! ! thrown_size += sizeof (__cxa_refcounted_exception); ! ret = malloc (thrown_size); ! ! if (!ret) ! ret = emergency_pool.allocate (thrown_size); ! ! if (!ret) ! std::terminate (); memset (ret, 0, sizeof (__cxa_refcounted_exception)); *************** *** 138,156 **** extern "C" void __cxxabiv1::__cxa_free_exception(void *vptr) _GLIBCXX_NOTHROW { ! char *base = (char *) emergency_buffer; ! char *ptr = (char *) vptr; ! if (ptr >= base ! && ptr < base + sizeof (emergency_buffer)) ! { ! const unsigned int which ! = (unsigned) (ptr - base) / EMERGENCY_OBJ_SIZE; ! ! __gnu_cxx::__scoped_lock sentry(emergency_mutex); ! emergency_used &= ~((bitmask_type)1 << which); ! } else ! free (ptr - sizeof (__cxa_refcounted_exception)); } --- 267,277 ---- extern "C" void __cxxabiv1::__cxa_free_exception(void *vptr) _GLIBCXX_NOTHROW { ! char *ptr = (char *) vptr - sizeof (__cxa_refcounted_exception); ! if (emergency_pool.in_pool (ptr)) ! emergency_pool.free (ptr); else ! free (ptr); } *************** *** 163,189 **** (malloc (sizeof (__cxa_dependent_exception))); if (!ret) ! { ! __gnu_cxx::__scoped_lock sentry(emergency_mutex); ! ! bitmask_type used = dependents_used; ! unsigned int which = 0; ! ! while (used & 1) ! { ! used >>= 1; ! if (++which >= EMERGENCY_OBJ_COUNT) ! goto failed; ! } ! dependents_used |= (bitmask_type)1 << which; ! ret = &dependents_buffer[which]; ! ! failed:; ! ! if (!ret) ! std::terminate (); ! } memset (ret, 0, sizeof (__cxa_dependent_exception)); --- 284,294 ---- (malloc (sizeof (__cxa_dependent_exception))); if (!ret) ! ret = static_cast <__cxa_dependent_exception*> ! (emergency_pool.allocate (sizeof (__cxa_dependent_exception))); ! if (!ret) ! std::terminate (); memset (ret, 0, sizeof (__cxa_dependent_exception)); *************** *** 195,211 **** __cxxabiv1::__cxa_free_dependent_exception (__cxa_dependent_exception *vptr) _GLIBCXX_NOTHROW { ! char *base = (char *) dependents_buffer; ! char *ptr = (char *) vptr; ! if (ptr >= base ! && ptr < base + sizeof (dependents_buffer)) ! { ! const unsigned int which ! = (unsigned) (ptr - base) / sizeof (__cxa_dependent_exception); ! ! __gnu_cxx::__scoped_lock sentry(emergency_mutex); ! dependents_used &= ~((bitmask_type)1 << which); ! } else free (vptr); } --- 300,307 ---- __cxxabiv1::__cxa_free_dependent_exception (__cxa_dependent_exception *vptr) _GLIBCXX_NOTHROW { ! if (emergency_pool.in_pool (vptr)) ! emergency_pool.free (vptr); else free (vptr); } *** gcc-4_8-branch/gcc/testsuite/g++.old-deja/g++.eh/badalloc1.C Mon Mar 18 09:44:40 2013 --- trunk/gcc/testsuite/g++.old-deja/g++.eh/badalloc1.C Thu Jan 22 10:58:02 2015 *************** *** 3,9 **** // itself call malloc(), and will fail if there is no more // memory available. // { dg-do run { xfail { { xstormy16-*-* *-*-darwin[3-7]* } || vxworks_rtp } } } ! // Copyright (C) 2000, 2002, 2003, 2010, 2012 Free Software Foundation, Inc. // Contributed by Nathan Sidwell 6 June 2000 <nathan@codesourcery.com> // Check we can throw a bad_alloc exception when malloc dies. --- 3,9 ---- // itself call malloc(), and will fail if there is no more // memory available. // { dg-do run { xfail { { xstormy16-*-* *-*-darwin[3-7]* } || vxworks_rtp } } } ! // Copyright (C) 2000, 2002, 2003, 2010, 2012, 2014 Free Software Foundation, Inc. // Contributed by Nathan Sidwell 6 June 2000 <nathan@codesourcery.com> // Check we can throw a bad_alloc exception when malloc dies. *************** *** 12,29 **** extern "C" void abort(); extern "C" void *memcpy(void *, const void *, size_t); // Assume that STACK_SIZE defined implies a system that does not have a // large data space either, and additionally that we're not linking against // a shared libstdc++ (which requires quite a bit more initialization space). #ifdef STACK_SIZE ! const int arena_size = 256; #else #if defined(__FreeBSD__) || defined(__sun__) || defined(__hpux__) // FreeBSD, Solaris and HP-UX require even more space at initialization time. // FreeBSD 5 now requires over 131072 bytes. ! const int arena_size = 262144; #else ! const int arena_size = 32768; #endif #endif --- 12,35 ---- extern "C" void abort(); extern "C" void *memcpy(void *, const void *, size_t); + // libstdc++ requires a large initialization time allocation for the + // emergency EH allocation pool. Add that to the arena size. + // Assume that STACK_SIZE defined implies a system that does not have a // large data space either, and additionally that we're not linking against // a shared libstdc++ (which requires quite a bit more initialization space). #ifdef STACK_SIZE ! const int arena_size = 256 + 8 * 128; #else #if defined(__FreeBSD__) || defined(__sun__) || defined(__hpux__) // FreeBSD, Solaris and HP-UX require even more space at initialization time. // FreeBSD 5 now requires over 131072 bytes. ! const int arena_size = 262144 + 72 * 1024; #else ! // Because pointers make up the bulk of our exception-initialization ! // allocations, we scale by the pointer size from the original ! // 32-bit-systems-based estimate. ! const int arena_size = 32768 * ((sizeof (void *) + 3)/4) + 72 * 1024; #endif #endif
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor