Upgrade Boehm GC to 7.2alpha4.
[cacao.git] / src / mm / boehm-gc / include / gc_allocator.h
index 4f3117b3bd4c9e4adf7e82f53d932fbba3e40fa9..086fac4b3db3a8cbb0ac88cc9a5871ba39cb55de 100644 (file)
  * This implements standard-conforming allocators that interact with
  * the garbage collector.  Gc_alloctor<T> allocates garbage-collectable
  * objects of type T.  Traceable_allocator<T> allocates objects that
- * are not temselves garbage collected, but are scanned by the
+ * are not themselves garbage collected, but are scanned by the
  * collector for pointers to collectable objects.  Traceable_alloc
  * should be used for explicitly managed STL containers that may
  * point to collectable objects.
  *
  * 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
 #include <new> // for placement new
 
 #if defined(__GNUC__)
-#  define GC_ATTR_UNUSED __attribute__((unused))
+#  define GC_ATTR_UNUSED __attribute__((__unused__))
 #else
 #  define GC_ATTR_UNUSED
 #endif
 
 /* First some helpers to allow us to dispatch on whether or not a type
- * is known to be pointerfree.
+ * is known to be pointer-free.
  * These are private, except that the client may invoke the
  * GC_DECLARE_PTRFREE macro.
  */
@@ -77,18 +79,20 @@ GC_DECLARE_PTRFREE(unsigned long);
 GC_DECLARE_PTRFREE(float);
 GC_DECLARE_PTRFREE(double);
 GC_DECLARE_PTRFREE(long double);
-/* The client may want to add others.  */
+/* The client may want to add others.   */
 
-// In the following GC_Tp is GC_true_type iff we are allocating a
-// pointerfree object.
+// In the following GC_Tp is GC_true_type if we are allocating a
+// pointer-free 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:
@@ -124,8 +128,8 @@ public:
   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));
+            (GC_selective_alloc(GC_n * sizeof(GC_Tp),
+                                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.
  */
@@ -192,7 +272,7 @@ public:
 # if !(GC_NO_MEMBER_TEMPLATES || 0 < _MSC_VER && _MSC_VER <= 1200)
   // MSVC++ 6.0 do not support member templates
   template <class GC_Tp1> traceable_allocator
-         (const traceable_allocator<GC_Tp1>&) throw() {}
+          (const traceable_allocator<GC_Tp1>&) throw() {}
 # endif
   ~traceable_allocator() throw() {}