]> granicus.if.org Git - gc/commitdiff
2009-06-12 Hans Boehm <Hans.Boehm@hp.com> (Really mostly George Talbot)
authorhboehm <hboehm>
Fri, 12 Jun 2009 18:28:03 +0000 (18:28 +0000)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 26 Jul 2011 17:06:45 +0000 (21:06 +0400)
* include/gc_allocator.h: Add gc_allocator_ignore_off_page.
* tests/test_cpp.cc: Add call to gc_allocator_ignore_off_page.

ChangeLog
include/gc_allocator.h
tests/test_cpp.cc

index 7cb2a7e0e0c54a626261c300d94999b9ae66b1bf..8783963cb6a34aaec65fa6a6b91ec9690e74df55 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2009-06-12  Hans Boehm <Hans.Boehm@hp.com> (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 <Hans.Boehm@hp.com>
        * win32_threads.c (GC_release_mark_lock): Correct misspelling of
        AO_load in assertion.
index 30772804f0e564d968a7f0c6d7b4bc9a8fbb0155..c33c24954fd7616bcd8ff4c019d3a7316705f52d 100644 (file)
@@ -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 <class GC_Tp>
-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<GC_true_type>(size_t n, GC_true_type) {
-    return GC_MALLOC_ATOMIC(n);
+inline void * GC_selective_alloc<GC_true_type>(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<T> class:
@@ -125,7 +129,7 @@ public:
     GC_type_traits<GC_Tp> traits;
     return static_cast<GC_Tp *>
            (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<GC_T1>&, const gc_allocator<GC_T2>&)
   return false;
 }
 
+
+/* Now the public gc_allocator_ignore_off_page<T> class:
+ */
+template <class GC_Tp>
+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 <class GC_Tp1> struct rebind {
+    typedef gc_allocator_ignore_off_page<GC_Tp1> 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 <class GC_Tp1>
+    gc_allocator_ignore_off_page(const gc_allocator_ignore_off_page<GC_Tp1>&)
+       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<GC_Tp> traits;
+    return static_cast<GC_Tp *>
+           (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<void> {
+  typedef size_t      size_type;
+  typedef ptrdiff_t   difference_type;
+  typedef void*       pointer;
+  typedef const void* const_pointer;
+  typedef void        value_type;
+
+  template <class GC_Tp1> struct rebind {
+    typedef gc_allocator_ignore_off_page<GC_Tp1> other;
+  };
+};
+
+template <class GC_T1, class GC_T2>
+inline bool operator==(const gc_allocator_ignore_off_page<GC_T1>&, const gc_allocator_ignore_off_page<GC_T2>&)
+{
+  return true;
+}
+
+template <class GC_T1, class GC_T2>
+inline bool operator!=(const gc_allocator_ignore_off_page<GC_T1>&, const gc_allocator_ignore_off_page<GC_T2>&)
+{
+  return false;
+}
+
 /*
  * And the public traceable_allocator class.
  */
index 9bf53de811ec88b9c7dd031178cad0d9705354fd..98cb28196f0eb26fa4648a575710769f0b75e390 100644 (file)
@@ -206,6 +206,7 @@ int APIENTRY WinMain(
     int i, iters, n;
 #   ifdef USE_STD_ALLOCATOR
       int *x = gc_allocator<int>().allocate(1);
+      int *xio = gc_allocator_ignore_off_page<int>().allocate(1);
       int **xptr = traceable_allocator<int *>().allocate(1);
 #   else 
 #     ifdef __GNUC__