Upgrade Boehm GC to 7.2alpha4.
[cacao.git] / src / mm / boehm-gc / include / gc_inline.h
index da7e2e91f020e8d120506f42c5493cf1e6f1734b..312ed61bbdc707756d51f000a79ad0dd02adf0f8 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
  * Copyright (c) 1991-1995 by Xerox Corporation.  All rights reserved.
  * Copyright (c) 2005 Hewlett-Packard Development Company, L.P.
  * provided the above notices are retained, and a notice that the code was
  * modified is included with the above copyright notice.
  */
-/* USE OF THIS FILE IS NOT RECOMMENDED unless GC_all_interior_pointers */
-/* is not set, or the collector has been built with                    */
-/* -DDONT_ADD_BYTE_AT_END, or the specified size includes a pointerfree        */
-/* word at the end.  In the standard collector configuration,          */
-/* the final word of each object may not be scanned.                   */
-/* This interface is most useful for compilers that generate C.                */
-/* It is also used internally for thread-local allocation, in which    */
-/* case, the size is suitably adjusted by the caller.                  */
-/* Manual use is hereby discouraged.                                   */
+
+#ifndef GC_INLINE_H
+#define GC_INLINE_H
+
+/* WARNING:                                                             */
+/* Note that for these routines, it is the clients responsibility to    */
+/* add the extra byte at the end to deal with one-past-the-end pointers.*/
+/* In the standard collector configuration, the collector assumes that  */
+/* such a byte has been added, and hence does not trace the last word   */
+/* in the resulting object.                                             */
+/* This is not an issue if the collector is compiled with               */
+/* DONT_ADD_BYTE_AT_END, or if GC_all_interior_pointers is not set.     */
+/* This interface is most useful for compilers that generate C.         */
+/* It is also used internally for thread-local allocation.              */
+/* Manual use is hereby discouraged.                                    */
 
 #include "gc.h"
 #include "gc_tiny_fl.h"
 # define GC_EXPECT(expr, outcome) (expr)
 #endif /* __GNUC__ */
 
-/* The ultimately general inline allocation macro.  Allocate an object */
-/* of size bytes, putting the resulting pointer in result.  Tiny_fl is */
-/* a "tiny" free list array, which will be used first, if the size     */
-/* is appropriate.  If bytes is too large, we allocate with            */
-/* default_expr instead.  If we need to refill the free list, we use   */
-/* GC_generic_malloc_many with the indicated kind.                     */
-/* Tiny_fl should be an array of GC_TINY_FREELISTS void * pointers.    */
-/* If num_direct is nonzero, and the individual free list pointers     */
-/* are initialized to (void *)1, then we allocate numdirect granules   */
-/* directly using gmalloc before putting multiple objects into the     */
-/* tiny_fl entry.  If num_direct is zero, then the free lists may also */
-/* be initialized to (void *)0.                                                */
-/* We rely on much of this hopefully getting optimized away in the     */
-/* num_direct = 0 case.                                                        */
-/* Particularly if bytes is constant, this should generate a small     */
-/* amount of code.                                                     */
+#ifndef GC_ASSERT
+# define GC_ASSERT(expr) /* empty */
+#endif
+
+/* Store a pointer to a list of newly allocated objects of kind k and   */
+/* size lb in *result.  The caller must make sure that *result is       */
+/* traced even if objects are ptrfree.                                  */
+GC_API void GC_CALL GC_generic_malloc_many(size_t /* lb */, int /* k */,
+                                           void ** /* result */);
+
+/* The ultimately general inline allocation macro.  Allocate an object  */
+/* of size granules, putting the resulting pointer in result.  Tiny_fl  */
+/* is a "tiny" free list array, which will be used first, if the size   */
+/* is appropriate.  If granules is too large, we allocate with          */
+/* default_expr instead.  If we need to refill the free list, we use    */
+/* GC_generic_malloc_many with the indicated kind.                      */
+/* Tiny_fl should be an array of GC_TINY_FREELISTS void * pointers.     */
+/* If num_direct is nonzero, and the individual free list pointers      */
+/* are initialized to (void *)1, then we allocate numdirect granules    */
+/* directly using gmalloc before putting multiple objects into the      */
+/* tiny_fl entry.  If num_direct is zero, then the free lists may also  */
+/* be initialized to (void *)0.                                         */
+/* Note that we use the zeroth free list to hold objects 1 granule in   */
+/* size that are used to satisfy size 0 allocation requests.            */
+/* We rely on much of this hopefully getting optimized away in the      */
+/* num_direct = 0 case.                                                 */
+/* Particularly if granules is constant, this should generate a small   */
+/* amount of code.                                                      */
 # define GC_FAST_MALLOC_GRANS(result,granules,tiny_fl,num_direct,\
-                             kind,default_expr,init) \
+                              kind,default_expr,init) \
 { \
-    if (GC_EXPECT(granules >= GC_TINY_FREELISTS,0)) { \
-        result = default_expr; \
+    if (GC_EXPECT((granules) >= GC_TINY_FREELISTS,0)) { \
+        result = (default_expr); \
     } else { \
-       void **my_fl = tiny_fl + granules; \
+        void **my_fl = (tiny_fl) + (granules); \
         void *my_entry=*my_fl; \
-       void *next; \
+        void *next; \
  \
-       while (GC_EXPECT((GC_word)my_entry \
-                               <= num_direct + GC_TINY_FREELISTS + 1, 0)) { \
-           /* Entry contains counter or NULL */ \
-           if ((GC_word)my_entry - 1 < num_direct) { \
-               /* Small counter value, not NULL */ \
-                *my_fl = (ptr_t)my_entry + granules + 1; \
-                result = default_expr; \
-               goto out; \
+        while (GC_EXPECT((GC_word)my_entry \
+                        <= (num_direct) + GC_TINY_FREELISTS + 1, 0)) { \
+            /* Entry contains counter or NULL */ \
+            if ((GC_word)my_entry - 1 < (num_direct)) { \
+                /* Small counter value, not NULL */ \
+                *my_fl = (char *)my_entry + (granules) + 1; \
+                result = (default_expr); \
+                goto out; \
             } else { \
-               /* Large counter or NULL */ \
+                /* Large counter or NULL */ \
                 GC_generic_malloc_many(((granules) == 0? GC_GRANULE_BYTES : \
-                                         RAW_BYTES_FROM_INDEX(granules)), \
-                                      kind, my_fl); \
-               my_entry = *my_fl; \
+                                        GC_RAW_BYTES_FROM_INDEX(granules)), \
+                                       kind, my_fl); \
+                my_entry = *my_fl; \
                 if (my_entry == 0) { \
-                   result = GC_oom_fn(bytes); \
-                   goto out; \
-               } \
-           } \
+                    result = (*GC_get_oom_fn())((granules)*GC_GRANULE_BYTES); \
+                    goto out; \
+                } \
+            } \
         } \
         next = *(void **)(my_entry); \
         result = (void *)my_entry; \
         *my_fl = next; \
-       init; \
+        init; \
         PREFETCH_FOR_WRITE(next); \
-        GC_ASSERT(GC_size(result) >= bytes + EXTRA_BYTES); \
+        GC_ASSERT(GC_size(result) >= (granules)*GC_GRANULE_BYTES); \
         GC_ASSERT((kind) == PTRFREE || ((GC_word *)result)[1] == 0); \
       out: ; \
    } \
 }
 
 # define GC_WORDS_TO_WHOLE_GRANULES(n) \
-       GC_WORDS_TO_GRANULES((n) + GC_GRANULE_WORDS - 1)
+        GC_WORDS_TO_GRANULES((n) + GC_GRANULE_WORDS - 1)
 
-/* Allocate n words (NOT BYTES).  X is made to point to the result.    */
-/* This should really only be used if GC_all_interior_pointers is      */
-/* not set, or DONT_ADD_BYTE_AT_END is set.  See above.                        */
-/* The semantics changed in version 7.0; we no longer lock, and                */
-/* the caller is responsible for supplying a cleared tiny_fl           */
-/* free list array.  For single-threaded applications, this may be     */
-/* a global array.                                                     */
+/* Allocate n words (NOT BYTES).  X is made to point to the result.     */
+/* This should really only be used if GC_all_interior_pointers is       */
+/* not set, or DONT_ADD_BYTE_AT_END is set.  See above.                 */
+/* The semantics changed in version 7.0; we no longer lock, and         */
+/* the caller is responsible for supplying a cleared tiny_fl            */
+/* free list array.  For single-threaded applications, this may be      */
+/* a global array.                                                      */
 # define GC_MALLOC_WORDS(result,n,tiny_fl) \
-{      \
-    size_t grans = WORDS_TO_WHOLE_GRANULES(n); \
+{       \
+    size_t grans = GC_WORDS_TO_WHOLE_GRANULES(n); \
     GC_FAST_MALLOC_GRANS(result, grans, tiny_fl, 0, \
-                        NORMAL, GC_malloc(grans*GRANULE_BYTES), \
-                        *(void **)result = 0); \
+                         NORMAL, GC_malloc(grans*GC_GRANULE_BYTES), \
+                         *(void **)result = 0); \
 }
 
 # define GC_MALLOC_ATOMIC_WORDS(result,n,tiny_fl) \
-{      \
-    size_t grans = WORDS_TO_WHOLE_GRANULES(n); \
+{       \
+    size_t grans = GC_WORDS_TO_WHOLE_GRANULES(n); \
     GC_FAST_MALLOC_GRANS(result, grans, tiny_fl, 0, \
-                        PTRFREE, GC_malloc_atomic(grans*GRANULE_BYTES), \
-                        /* no initialization */); \
+                         PTRFREE, GC_malloc_atomic(grans*GC_GRANULE_BYTES), \
+                         (void)0 /* no initialization */); \
 }
 
-
 /* And once more for two word initialized objects: */
 # define GC_CONS(result, first, second, tiny_fl) \
-{      \
-    size_t grans = WORDS_TO_WHOLE_GRANULES(2); \
+{       \
+    size_t grans = GC_WORDS_TO_WHOLE_GRANULES(2); \
     GC_FAST_MALLOC_GRANS(result, grans, tiny_fl, 0, \
-                        NORMAL, GC_malloc(grans*GRANULE_BYTES), \
-                        *(void **)result = (void *)(first)); \
-    ((void **)(result))[1] = (void *)(second); \
+                         NORMAL, GC_malloc(grans*GC_GRANULE_BYTES), \
+                         *(void **)result = (void *)(first)); \
+    ((void **)(result))[1] = (void *)(second);  \
 }
+
+#endif /* !GC_INLINE_H */