From f353c00dcba3b5afd07ced717e7fb4adce5edb2b Mon Sep 17 00:00:00 2001 From: hboehm Date: Fri, 12 Jun 2009 18:28:03 +0000 Subject: [PATCH] 2009-06-12 Hans Boehm (Really mostly George Talbot) * include/gc_allocator.h: Add gc_allocator_ignore_off_page. * tests/test_cpp.cc: Add call to gc_allocator_ignore_off_page. --- ChangeLog | 4 ++ include/gc_allocator.h | 96 ++++++++++++++++++++++++++++++++++++++---- tests/test_cpp.cc | 1 + 3 files changed, 93 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7cb2a7e0..8783963c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2009-06-12 Hans Boehm (Really mostly George Talbot) + * include/gc_allocator.h: Add gc_allocator_ignore_off_page. + * tests/test_cpp.cc: Add call to gc_allocator_ignore_off_page. + 2009-06-11 Hans Boehm * win32_threads.c (GC_release_mark_lock): Correct misspelling of AO_load in assertion. diff --git a/include/gc_allocator.h b/include/gc_allocator.h index 30772804..c33c2495 100644 --- a/include/gc_allocator.h +++ b/include/gc_allocator.h @@ -33,6 +33,8 @@ * * This code was derived from an earlier version of the GNU C++ standard * library, which itself was derived from the SGI STL implementation. + * + * Ignore-off-page allocator: George T. Talbot */ #ifndef GC_ALLOCATOR_H @@ -49,7 +51,7 @@ #endif /* First some helpers to allow us to dispatch on whether or not a type - * is known to be pointer-free. + * is known to be pointerfree. * These are private, except that the client may invoke the * GC_DECLARE_PTRFREE macro. */ @@ -79,16 +81,18 @@ GC_DECLARE_PTRFREE(double); GC_DECLARE_PTRFREE(long double); /* The client may want to add others. */ -// In the following GC_Tp is GC_true_type if we are allocating a -// pointer-free object. +// In the following GC_Tp is GC_true_type iff we are allocating a +// pointerfree object. template -inline void * GC_selective_alloc(size_t n, GC_Tp) { - return GC_MALLOC(n); +inline void * GC_selective_alloc(size_t n, GC_Tp, bool ignore_off_page) { + return ignore_off_page?GC_MALLOC_IGNORE_OFF_PAGE(n):GC_MALLOC(n); } template <> -inline void * GC_selective_alloc(size_t n, GC_true_type) { - return GC_MALLOC_ATOMIC(n); +inline void * GC_selective_alloc(size_t n, GC_true_type, + bool ignore_off_page) { + return ignore_off_page? GC_MALLOC_ATOMIC_IGNORE_OFF_PAGE(n) + : GC_MALLOC_ATOMIC(n); } /* Now the public gc_allocator class: @@ -125,7 +129,7 @@ public: GC_type_traits traits; return static_cast (GC_selective_alloc(GC_n * sizeof(GC_Tp), - traits.GC_is_ptr_free)); + traits.GC_is_ptr_free, false)); } // __p is not permitted to be a null pointer. @@ -165,6 +169,82 @@ inline bool operator!=(const gc_allocator&, const gc_allocator&) return false; } + +/* Now the public gc_allocator_ignore_off_page class: + */ +template +class gc_allocator_ignore_off_page { +public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef GC_Tp* pointer; + typedef const GC_Tp* const_pointer; + typedef GC_Tp& reference; + typedef const GC_Tp& const_reference; + typedef GC_Tp value_type; + + template struct rebind { + typedef gc_allocator_ignore_off_page other; + }; + + gc_allocator_ignore_off_page() {} + gc_allocator_ignore_off_page(const gc_allocator_ignore_off_page&) throw() {} +# if !(GC_NO_MEMBER_TEMPLATES || 0 < _MSC_VER && _MSC_VER <= 1200) + // MSVC++ 6.0 do not support member templates + template + gc_allocator_ignore_off_page(const gc_allocator_ignore_off_page&) + throw() {} +# endif + ~gc_allocator_ignore_off_page() throw() {} + + pointer address(reference GC_x) const { return &GC_x; } + const_pointer address(const_reference GC_x) const { return &GC_x; } + + // GC_n is permitted to be 0. The C++ standard says nothing about what + // the return value is when GC_n == 0. + GC_Tp* allocate(size_type GC_n, const void* = 0) { + GC_type_traits traits; + return static_cast + (GC_selective_alloc(GC_n * sizeof(GC_Tp), + traits.GC_is_ptr_free, true)); + } + + // __p is not permitted to be a null pointer. + void deallocate(pointer __p, size_type GC_ATTR_UNUSED GC_n) + { GC_FREE(__p); } + + size_type max_size() const throw() + { return size_t(-1) / sizeof(GC_Tp); } + + void construct(pointer __p, const GC_Tp& __val) { new(__p) GC_Tp(__val); } + void destroy(pointer __p) { __p->~GC_Tp(); } +}; + +template<> +class gc_allocator_ignore_off_page { + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + + template struct rebind { + typedef gc_allocator_ignore_off_page other; + }; +}; + +template +inline bool operator==(const gc_allocator_ignore_off_page&, const gc_allocator_ignore_off_page&) +{ + return true; +} + +template +inline bool operator!=(const gc_allocator_ignore_off_page&, const gc_allocator_ignore_off_page&) +{ + return false; +} + /* * And the public traceable_allocator class. */ diff --git a/tests/test_cpp.cc b/tests/test_cpp.cc index 9bf53de8..98cb2819 100644 --- a/tests/test_cpp.cc +++ b/tests/test_cpp.cc @@ -206,6 +206,7 @@ int APIENTRY WinMain( int i, iters, n; # ifdef USE_STD_ALLOCATOR int *x = gc_allocator().allocate(1); + int *xio = gc_allocator_ignore_off_page().allocate(1); int **xptr = traceable_allocator().allocate(1); # else # ifdef __GNUC__ -- 2.40.0