aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Kosnik <bkoz@redhat.com>2003-06-13 05:45:57 +0000
committerBenjamin Kosnik <bkoz@gcc.gnu.org>2003-06-13 05:45:57 +0000
commitc37514ff623f1d8ea7cf9fa5a5af15ab70e4902b (patch)
treea84448145ae89976fcf054ca735ec55834288064
parent5482aaab6fd88069549d2312524917424b915a95 (diff)
downloadgcc-c37514ff623f1d8ea7cf9fa5a5af15ab70e4902b.zip
gcc-c37514ff623f1d8ea7cf9fa5a5af15ab70e4902b.tar.gz
gcc-c37514ff623f1d8ea7cf9fa5a5af15ab70e4902b.tar.bz2
allocator-inst.cc: Explicitly instantiate.
2003-06-12 Benjamin Kosnik <bkoz@redhat.com> * src/allocator-inst.cc: Explicitly instantiate. * include/ext/pool_allocator.h: Inhibit implicit instantiations. Tweaks. * config/linker-map.gnu: Add __pool_alloc bits. Tweaks. From-SVN: r67882
-rw-r--r--libstdc++-v3/ChangeLog7
-rw-r--r--libstdc++-v3/config/linker-map.gnu122
-rw-r--r--libstdc++-v3/include/ext/pool_allocator.h182
-rw-r--r--libstdc++-v3/src/allocator-inst.cc5
4 files changed, 181 insertions, 135 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 49d6ade..6397b28 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,10 @@
+2003-06-12 Benjamin Kosnik <bkoz@redhat.com>
+
+ * src/allocator-inst.cc: Explicitly instantiate.
+ * include/ext/pool_allocator.h: Inhibit implicit instantiations.
+ Tweaks.
+ * config/linker-map.gnu: Add __pool_alloc bits. Tweaks.
+
2003-06-11 Benjamin Kosnik <bkoz@redhat.com>
* acinclude.m4 (GLIBCPP_ENABLE_CSTDIO): Simplify.
diff --git a/libstdc++-v3/config/linker-map.gnu b/libstdc++-v3/config/linker-map.gnu
index 6723a05..2245cd2 100644
--- a/libstdc++-v3/config/linker-map.gnu
+++ b/libstdc++-v3/config/linker-map.gnu
@@ -55,12 +55,7 @@ GLIBCPP_3.4 {
std::__num_base::_S_format_float*;
std::__num_base::_S_format_int*;
std::__num_base::_S_atoms_in;
- std::__num_base::_S_atoms_out;
-
- # Needed only when generic cpu's atomicity.h is in use.
- __gnu_cxx::_Atomic_add_mutex;
- __gnu_cxx::_Atomic_add_mutex_once;
- __gnu_cxx::__gthread_atomic_add_mutex_once
+ std::__num_base::_S_atoms_out
};
# Names not in an 'extern' block are mangled names.
@@ -78,28 +73,7 @@ GLIBCPP_3.4 {
# bool has_facet
_ZSt9has_facet*;
- # operator new(size_t)
- _Znw[jm];
- # operator new(size_t, std::nothrow_t const&)
- _Znw[jm]RKSt9nothrow_t;
-
- # operator delete(void*)
- _ZdlPv;
- # operator delete(void*, std::nothrow_t const&)
- _ZdlPvRKSt9nothrow_t;
-
- # operator new[](size_t)
- _Zna[jm];
- # operator new[](size_t, std::nothrow_t const&)
- _Zna[jm]RKSt9nothrow_t;
-
- # operator delete[](void*)
- _ZdaPv;
- # operator delete[](void*, std::nothrow_t const&)
- _ZdaPvRKSt9nothrow_t;
-
- # vtable
- _ZTVN9__gnu_cxx*;
+ # virtual table
_ZTVNSt8ios_base7failureE;
_ZTVNSt6locale5facetE;
_ZTVS[a-z];
@@ -109,18 +83,15 @@ GLIBCPP_3.4 {
_ZTVSt23__codecvt_abstract_baseI[cw]c11__mbstate_tE;
_ZTVSt21__ctype_abstract_baseI[cw]E;
+ # VTT structure
_ZTTS[a-z];
_ZTTSt[0-9][A-Za-z]*;
_ZTTSt[0-9][0-9][A-Za-z]*;
- # typeinfo
- _ZTI[a-z];
+ # typeinfo structure
+ _ZTIS[a-z];
_ZTINSt8ios_base7failureE;
_ZTINSt6locale5facetE;
- _ZTIN9__gnu_cxx*;
- _ZTIP[a-z];
- _ZTIPK[a-z];
- _ZTIS[a-z];
_ZTISt[0-9][A-Za-z]*;
_ZTISt[0-9][0-9][A-Za-z]*;
_ZTISt11__timepunctI[cw]E;
@@ -128,12 +99,9 @@ GLIBCPP_3.4 {
_ZTISt21__ctype_abstract_baseI[cw]E;
_ZTISt23__codecvt_abstract_baseI[cw]c11__mbstate_tE;
- _ZTS[a-z];
+ # typeinfo name
_ZTSNSt8ios_base7failureE;
_ZTSNSt6locale5facetE;
- _ZTSN9__gnu_cxx*;
- _ZTSP[a-z];
- _ZTSPK[a-z];
_ZTSS[a-z];
_ZTSSt[0-9][A-Za-z]*;
_ZTSSt[0-9][0-9][A-Za-z]*;
@@ -143,12 +111,11 @@ GLIBCPP_3.4 {
_ZTSSt23__codecvt_abstract_baseI[cw]c11__mbstate_tE;
# function-scope static objects requires a guard variable.
- _ZGV*;
+ _ZGVNSt*;
# virtual function thunks
- _ZTh*;
- _ZTv*;
- _ZTc*;
+ _ZThn8_NS*;
+ _ZTv0_n12_NS*;
# std::__convert_to_v
_ZSt14__convert_to_v*;
@@ -187,6 +154,18 @@ GLIBCPP_3.4 {
__signbitf;
__signbitl;
+ # __gnu_cxx::__pool_alloc
+ _ZN9__gnu_cxx12__pool_allocILb1ELi0EE8allocateE[jm];
+ _ZN9__gnu_cxx12__pool_allocILb1ELi0EE10deallocateEPv[jm];
+
+ # __gnu_cxx::stdio_sync_filebuf
+ _ZTVN9__gnu_cxx18stdio_sync_filebufI[cw]St11char_traitsI[cw]EEE;
+
+ # Needed only when generic cpu's atomicity.h is in use.
+ _ZN9__gnu_cxx17_Atomic_add_mutexE;
+ _ZN9__gnu_cxx22_Atomic_add_mutex_onceE;
+ _ZN9__gnu_cxx31__gthread_atomic_add_mutex_onceEv;
+
local:
*;
};
@@ -227,15 +206,60 @@ CXXABI_1.3 {
__gxx_personality_sj0;
__dynamic_cast;
- # __gnu_cxx::_verbose_terminate_handler()
- _ZN9__gnu_cxx27__verbose_terminate_handlerEv;
+ # operator new(size_t)
+ _Znw[jm];
+ # operator new(size_t, std::nothrow_t const&)
+ _Znw[jm]RKSt9nothrow_t;
+
+ # operator delete(void*)
+ _ZdlPv;
+ # operator delete(void*, std::nothrow_t const&)
+ _ZdlPvRKSt9nothrow_t;
- # typeinfo
- _ZTIN10__cxxabi*;
- _ZTSN10__cxxabi*;
+ # operator new[](size_t)
+ _Zna[jm];
+ # operator new[](size_t, std::nothrow_t const&)
+ _Zna[jm]RKSt9nothrow_t;
- # vtable
- _ZTVN10__cxxabi*;
+ # operator delete[](void*)
+ _ZdaPv;
+ # operator delete[](void*, std::nothrow_t const&)
+ _ZdaPvRKSt9nothrow_t;
+
+ # virtual table
+ _ZTVN10__cxxabiv117__class_type_infoE;
+ _ZTVN10__cxxabiv120__si_class_type_infoE;
+ _ZTVN10__cxxabiv121__vmi_class_type_infoE;
+ _ZTVN10__cxxabiv123__fundamental_type_infoE;
+ _ZTVN10__cxxabiv117__array_type_infoE;
+ _ZTVN10__cxxabiv120__function_type_infoE;
+ _ZTVN10__cxxabiv116__enum_type_infoE;
+ _ZTVN10__cxxabiv117__pbase_type_infoE;
+ _ZTVN10__cxxabiv119__pointer_type_infoE;
+ _ZTVN10__cxxabiv129__pointer_to_member_type_infoE;
+
+ # typeinfo structure (and some names)
+ _ZTI[a-z];
+ _ZTIP[a-z];
+ _ZTIPK[a-z];
+ _ZTIN10__cxxabiv117__class_type_infoE;
+ _ZTIN10__cxxabiv120__si_class_type_infoE;
+ _ZTIN10__cxxabiv121__vmi_class_type_infoE;
+ _ZTIN10__cxxabiv123__fundamental_type_infoE;
+ _ZTIN10__cxxabiv117__array_type_infoE;
+ _ZTIN10__cxxabiv120__function_type_infoE;
+ _ZTIN10__cxxabiv116__enum_type_infoE;
+ _ZTIN10__cxxabiv117__pbase_type_infoE;
+ _ZTIN10__cxxabiv119__pointer_type_infoE;
+ _ZTIN10__cxxabiv129__pointer_to_member_type_infoE;
+
+ # typeinfo name
+ _ZTS[a-z];
+ _ZTSP[a-z];
+ _ZTSPK[a-z];
+
+ # __gnu_cxx::_verbose_terminate_handler()
+ _ZN9__gnu_cxx27__verbose_terminate_handlerEv;
local:
*;
diff --git a/libstdc++-v3/include/ext/pool_allocator.h b/libstdc++-v3/include/ext/pool_allocator.h
index 77d354f..2c6f87e 100644
--- a/libstdc++-v3/include/ext/pool_allocator.h
+++ b/libstdc++-v3/include/ext/pool_allocator.h
@@ -129,7 +129,7 @@ namespace __gnu_cxx
// Allocates a chunk for nobjs of size size. nobjs may be reduced
// if it is inconvenient to allocate the requested number.
static char*
- _S_chunk_alloc(size_t __size, int& __nobjs);
+ _S_chunk_alloc(size_t __n, int& __nobjs);
// It would be nice to use _STL_auto_lock here. But we need a
// test whether threads are in use.
@@ -143,70 +143,13 @@ namespace __gnu_cxx
public:
// __n must be > 0
static void*
- allocate(size_t __n)
- {
- void* __ret = 0;
-
- // If there is a race through here, assume answer from getenv
- // will resolve in same direction. Inspired by techniques
- // to efficiently support threading found in basic_string.h.
- if (_S_force_new == 0)
- {
- if (getenv("GLIBCPP_FORCE_NEW"))
- __atomic_add(&_S_force_new, 1);
- else
- __atomic_add(&_S_force_new, -1);
- }
-
- if ((__n > (size_t) _S_max_bytes) || (_S_force_new > 0))
- __ret = __new_alloc::allocate(__n);
- else
- {
- _Obj* volatile* __my_free_list = _S_free_list
- + _S_freelist_index(__n);
- // Acquire the lock here with a constructor call. This
- // ensures that it is released in exit or during stack
- // unwinding.
- _Lock __lock_instance;
- _Obj* __restrict__ __result = *__my_free_list;
- if (__builtin_expect(__result == 0, 0))
- __ret = _S_refill(_S_round_up(__n));
- else
- {
- *__my_free_list = __result -> _M_free_list_link;
- __ret = __result;
- }
- if (__builtin_expect(__ret == 0, 0))
- __throw_bad_alloc();
- }
- return __ret;
- }
+ allocate(size_t __n);
// __p may not be 0
static void
- deallocate(void* __p, size_t __n)
- {
- if ((__n > (size_t) _S_max_bytes) || (_S_force_new > 0))
- __new_alloc::deallocate(__p, __n);
- else
- {
- _Obj* volatile* __my_free_list = _S_free_list
- + _S_freelist_index(__n);
- _Obj* __q = (_Obj*)__p;
-
- // Acquire the lock here with a constructor call. This
- // ensures that it is released in exit or during stack
- // unwinding.
- _Lock __lock_instance;
- __q -> _M_free_list_link = *__my_free_list;
- *__my_free_list = __q;
- }
- }
+ deallocate(void* __p, size_t __n);
};
- template<bool __threads, int __inst> _Atomic_word
- __pool_alloc<__threads, __inst>::_S_force_new = 0;
-
template<bool __threads, int __inst>
inline bool
operator==(const __pool_alloc<__threads,__inst>&,
@@ -220,16 +163,15 @@ namespace __gnu_cxx
{ return false; }
- // We allocate memory in large chunks in order to avoid fragmenting the
- // heap too much. We assume that __size is properly aligned. We hold
+ // Allocate memory in large chunks in order to avoid fragmenting the
+ // heap too much. Assume that __n is properly aligned. We hold
// the allocation lock.
template<bool __threads, int __inst>
char*
- __pool_alloc<__threads, __inst>::
- _S_chunk_alloc(size_t __size, int& __nobjs)
+ __pool_alloc<__threads, __inst>::_S_chunk_alloc(size_t __n, int& __nobjs)
{
char* __result;
- size_t __total_bytes = __size * __nobjs;
+ size_t __total_bytes = __n * __nobjs;
size_t __bytes_left = _S_end_free - _S_start_free;
if (__bytes_left >= __total_bytes)
@@ -238,10 +180,10 @@ namespace __gnu_cxx
_S_start_free += __total_bytes;
return __result ;
}
- else if (__bytes_left >= __size)
+ else if (__bytes_left >= __n)
{
- __nobjs = (int)(__bytes_left/__size);
- __total_bytes = __size * __nobjs;
+ __nobjs = (int)(__bytes_left/__n);
+ __total_bytes = __n * __nobjs;
__result = _S_start_free;
_S_start_free += __total_bytes;
return __result;
@@ -253,32 +195,32 @@ namespace __gnu_cxx
// Try to make use of the left-over piece.
if (__bytes_left > 0)
{
- _Obj* volatile* __my_free_list =
+ _Obj* volatile* __free_list =
_S_free_list + _S_freelist_index(__bytes_left);
- ((_Obj*)(void*)_S_start_free) -> _M_free_list_link = *__my_free_list;
- *__my_free_list = (_Obj*)(void*)_S_start_free;
+ ((_Obj*)(void*)_S_start_free)->_M_free_list_link = *__free_list;
+ *__free_list = (_Obj*)(void*)_S_start_free;
}
_S_start_free = (char*) __new_alloc::allocate(__bytes_to_get);
if (_S_start_free == 0)
{
size_t __i;
- _Obj* volatile* __my_free_list;
+ _Obj* volatile* __free_list;
_Obj* __p;
// Try to make do with what we have. That can't hurt. We
// do not try smaller requests, since that tends to result
// in disaster on multi-process machines.
- __i = __size;
+ __i = __n;
for (; __i <= (size_t) _S_max_bytes; __i += (size_t) _S_align)
{
- __my_free_list = _S_free_list + _S_freelist_index(__i);
- __p = *__my_free_list;
+ __free_list = _S_free_list + _S_freelist_index(__i);
+ __p = *__free_list;
if (__p != 0)
{
- *__my_free_list = __p -> _M_free_list_link;
+ *__free_list = __p -> _M_free_list_link;
_S_start_free = (char*)__p;
_S_end_free = _S_start_free + __i;
- return _S_chunk_alloc(__size, __nobjs);
+ return _S_chunk_alloc(__n, __nobjs);
// Any leftover piece will eventually make it to the
// right free list.
}
@@ -290,11 +232,10 @@ namespace __gnu_cxx
}
_S_heap_size += __bytes_to_get;
_S_end_free = _S_start_free + __bytes_to_get;
- return _S_chunk_alloc(__size, __nobjs);
+ return _S_chunk_alloc(__n, __nobjs);
}
}
-
// Returns an object of size __n, and optionally adds to "size
// __n"'s free list. We assume that __n is properly aligned. We
// hold the allocation lock.
@@ -304,7 +245,7 @@ namespace __gnu_cxx
{
int __nobjs = 20;
char* __chunk = _S_chunk_alloc(__n, __nobjs);
- _Obj* volatile* __my_free_list;
+ _Obj* volatile* __free_list;
_Obj* __result;
_Obj* __current_obj;
_Obj* __next_obj;
@@ -312,11 +253,11 @@ namespace __gnu_cxx
if (1 == __nobjs)
return __chunk;
- __my_free_list = _S_free_list + _S_freelist_index(__n);
+ __free_list = _S_free_list + _S_freelist_index(__n);
// Build free list in chunk.
__result = (_Obj*)(void*)__chunk;
- *__my_free_list = __next_obj = (_Obj*)(void*)(__chunk + __n);
+ *__free_list = __next_obj = (_Obj*)(void*)(__chunk + __n);
for (__i = 1; ; __i++)
{
__current_obj = __next_obj;
@@ -332,10 +273,69 @@ namespace __gnu_cxx
return __result;
}
+ template<bool __threads, int __inst>
+ void*
+ __pool_alloc<__threads, __inst>::allocate(size_t __n)
+ {
+ void* __ret = 0;
+
+ // If there is a race through here, assume answer from getenv
+ // will resolve in same direction. Inspired by techniques
+ // to efficiently support threading found in basic_string.h.
+ if (_S_force_new == 0)
+ {
+ if (getenv("GLIBCPP_FORCE_NEW"))
+ __atomic_add(&_S_force_new, 1);
+ else
+ __atomic_add(&_S_force_new, -1);
+ }
+
+ if ((__n > (size_t) _S_max_bytes) || (_S_force_new > 0))
+ __ret = __new_alloc::allocate(__n);
+ else
+ {
+ _Obj* volatile* __free_list = _S_free_list + _S_freelist_index(__n);
+ // Acquire the lock here with a constructor call. This
+ // ensures that it is released in exit or during stack
+ // unwinding.
+ _Lock __lock_instance;
+ _Obj* __restrict__ __result = *__free_list;
+ if (__builtin_expect(__result == 0, 0))
+ __ret = _S_refill(_S_round_up(__n));
+ else
+ {
+ *__free_list = __result -> _M_free_list_link;
+ __ret = __result;
+ }
+ if (__builtin_expect(__ret == 0, 0))
+ __throw_bad_alloc();
+ }
+ return __ret;
+ }
+
+ template<bool __threads, int __inst>
+ void
+ __pool_alloc<__threads, __inst>::deallocate(void* __p, size_t __n)
+ {
+ if ((__n > (size_t) _S_max_bytes) || (_S_force_new > 0))
+ __new_alloc::deallocate(__p, __n);
+ else
+ {
+ _Obj* volatile* __free_list = _S_free_list + _S_freelist_index(__n);
+ _Obj* __q = (_Obj*)__p;
+
+ // Acquire the lock here with a constructor call. This
+ // ensures that it is released in exit or during stack
+ // unwinding.
+ _Lock __lock_instance;
+ __q -> _M_free_list_link = *__free_list;
+ *__free_list = __q;
+ }
+ }
template<bool __threads, int __inst>
- _STL_mutex_lock
- __pool_alloc<__threads, __inst>::_S_lock __STL_MUTEX_INITIALIZER;
+ typename __pool_alloc<__threads, __inst>::_Obj* volatile
+ __pool_alloc<__threads, __inst>::_S_free_list[_S_freelists];
template<bool __threads, int __inst>
char* __pool_alloc<__threads, __inst>::_S_start_free = 0;
@@ -347,8 +347,18 @@ namespace __gnu_cxx
size_t __pool_alloc<__threads, __inst>::_S_heap_size = 0;
template<bool __threads, int __inst>
- typename __pool_alloc<__threads, __inst>::_Obj* volatile
- __pool_alloc<__threads, __inst>::_S_free_list[_S_freelists];
+ _STL_mutex_lock
+ __pool_alloc<__threads, __inst>::_S_lock __STL_MUTEX_INITIALIZER;
+
+ template<bool __threads, int __inst> _Atomic_word
+ __pool_alloc<__threads, __inst>::_S_force_new = 0;
+
+ // Inhibit implicit instantiations for required instantiations,
+ // which are defined via explicit instantiations elsewhere.
+ // NB: This syntax is a GNU extension.
+#if _GLIBCPP_EXTERN_TEMPLATE
+ extern template class __pool_alloc<true, 0>;
+#endif
} // namespace __gnu_cxx
namespace std
diff --git a/libstdc++-v3/src/allocator-inst.cc b/libstdc++-v3/src/allocator-inst.cc
index da8aeda..24a7b41 100644
--- a/libstdc++-v3/src/allocator-inst.cc
+++ b/libstdc++-v3/src/allocator-inst.cc
@@ -39,3 +39,8 @@ namespace std
template class allocator<char>;
template class allocator<wchar_t>;
} // namespace std
+
+namespace __gnu_cxx
+{
+ template class __pool_alloc<true, 0>;
+} // namespace __gnu_cxx