Upgrade Boehm GC to 7.2alpha4.
[cacao.git] / src / mm / boehm-gc / gcj_mlc.c
index 6441ca2e9d849021fc5543d6dc38477ab8d18865..6077a03d5f4928c5763cb05d2b9ea629ed8dd0ed 100644 (file)
@@ -12,7 +12,6 @@
  * modified is included with the above copyright notice.
  *
  */
-/* Boehm, July 31, 1995 5:02 pm PDT */
 
 #include "private/gc_pmark.h"  /* includes gc_priv.h */
 
 #include "gc_gcj.h"
 #include "private/dbg_mlc.h"
 
-GC_bool GC_gcj_malloc_initialized = FALSE;
+GC_INNER GC_bool GC_gcj_malloc_initialized = FALSE;
 
-int GC_gcj_kind;       /* Object kind for objects with descriptors     */
-                       /* in "vtable".                                 */
-int GC_gcj_debug_kind; /* The kind of objects that is always marked    */
-                       /* with a mark proc call.                       */
+int GC_gcj_kind = 0;    /* Object kind for objects with descriptors     */
+                        /* in "vtable".                                 */
+int GC_gcj_debug_kind = 0;
+                        /* The kind of objects that is always marked    */
+                        /* with a mark proc call.                       */
 
-ptr_t * GC_gcjobjfreelist;
-ptr_t * GC_gcjdebugobjfreelist;
+GC_INNER ptr_t * GC_gcjobjfreelist = NULL;
+
+STATIC ptr_t * GC_gcjdebugobjfreelist = NULL;
+
+/*ARGSUSED*/
+STATIC struct GC_ms_entry * GC_gcj_fake_mark_proc(word * addr,
+                                        struct GC_ms_entry *mark_stack_ptr,
+                                        struct GC_ms_entry *mark_stack_limit,
+                                        word env)
+{
+    ABORT("No client gcj mark proc is specified");
+    return mark_stack_ptr;
+}
 
 /* Caller does not hold allocation lock. */
 GC_API void GC_CALL GC_init_gcj_malloc(int mp_index,
-                               void * /* really GC_mark_proc */mp)
+                                       void * /* really GC_mark_proc */mp)
 {
     GC_bool ignore_gcj_info;
     DCL_LOCK_STATE;
 
-    GC_init(); /* In case it's not already done.       */
+    if (mp == 0)        /* In case GC_DS_PROC is unused.        */
+      mp = (void *)(word)GC_gcj_fake_mark_proc;
+
+    GC_init();  /* In case it's not already done.       */
     LOCK();
     if (GC_gcj_malloc_initialized) {
       UNLOCK();
       return;
     }
     GC_gcj_malloc_initialized = TRUE;
-    ignore_gcj_info = (0 != GETENV("GC_IGNORE_GCJ_INFO"));
+#   ifdef GC_IGNORE_GCJ_INFO
+      /* This is useful for debugging on platforms with missing getenv(). */
+      ignore_gcj_info = 1;
+#   else
+      ignore_gcj_info = (0 != GETENV("GC_IGNORE_GCJ_INFO"));
+#   endif
     if (GC_print_stats && ignore_gcj_info) {
         GC_log_printf("Gcj-style type information is disabled!\n");
     }
     GC_ASSERT(GC_mark_procs[mp_index] == (GC_mark_proc)0); /* unused */
     GC_mark_procs[mp_index] = (GC_mark_proc)(word)mp;
     if ((unsigned)mp_index >= GC_n_mark_procs)
-       ABORT("GC_init_gcj_malloc: bad index");
+        ABORT("GC_init_gcj_malloc: bad index");
     /* Set up object kind gcj-style indirect descriptor. */
       GC_gcjobjfreelist = (ptr_t *)GC_new_free_list_inner();
       if (ignore_gcj_info) {
-       /* Use a simple length-based descriptor, thus forcing a fully   */
-       /* conservative scan.                                           */
-       GC_gcj_kind = GC_new_kind_inner((void **)GC_gcjobjfreelist,
-                                       (0 | GC_DS_LENGTH),
-                                       TRUE, TRUE);
+        /* Use a simple length-based descriptor, thus forcing a fully   */
+        /* conservative scan.                                           */
+        GC_gcj_kind = GC_new_kind_inner((void **)GC_gcjobjfreelist,
+                                        (0 | GC_DS_LENGTH),
+                                        TRUE, TRUE);
       } else {
-       GC_gcj_kind = GC_new_kind_inner(
-                       (void **)GC_gcjobjfreelist,
-                       (((word)(-(signed_word)MARK_DESCR_OFFSET
-                                - GC_INDIR_PER_OBJ_BIAS))
-                        | GC_DS_PER_OBJECT),
-                       FALSE, TRUE);
+        GC_gcj_kind = GC_new_kind_inner(
+                        (void **)GC_gcjobjfreelist,
+                        (((word)(-(signed_word)MARK_DESCR_OFFSET
+                                 - GC_INDIR_PER_OBJ_BIAS))
+                         | GC_DS_PER_OBJECT),
+                        FALSE, TRUE);
       }
-    /* Set up object kind for objects that require mark proc call.     */
+    /* Set up object kind for objects that require mark proc call.      */
       if (ignore_gcj_info) {
-       GC_gcj_debug_kind = GC_gcj_kind;
+        GC_gcj_debug_kind = GC_gcj_kind;
         GC_gcjdebugobjfreelist = GC_gcjobjfreelist;
       } else {
         GC_gcjdebugobjfreelist = (ptr_t *)GC_new_free_list_inner();
-       GC_gcj_debug_kind = GC_new_kind_inner(
-                               (void **)GC_gcjdebugobjfreelist,
-                               GC_MAKE_PROC(mp_index,
-                                            1 /* allocated with debug info */),
-                               FALSE, TRUE);
+        GC_gcj_debug_kind = GC_new_kind_inner(
+                                (void **)GC_gcjdebugobjfreelist,
+                                GC_MAKE_PROC(mp_index,
+                                             1 /* allocated with debug info */),
+                                FALSE, TRUE);
       }
     UNLOCK();
 }
 
-void * GC_clear_stack(void *);
+#define GENERAL_MALLOC_INNER(lb,k) \
+    GC_clear_stack(GC_generic_malloc_inner(lb, k))
 
-#define GENERAL_MALLOC(lb,k) \
-    GC_clear_stack(GC_generic_malloc_inner((word)lb, k))
-    
-#define GENERAL_MALLOC_IOP(lb,k) \
+#define GENERAL_MALLOC_INNER_IOP(lb,k) \
     GC_clear_stack(GC_generic_malloc_inner_ignore_off_page(lb, k))
 
-/* We need a mechanism to release the lock and invoke finalizers.      */
-/* We don't really have an opportunity to do this on a rarely executed */
-/* path on which the lock is not held.  Thus we check at a             */
-/* rarely executed point at which it is safe to release the lock.      */
-/* We do this even where we could just call GC_INVOKE_FINALIZERS,      */
-/* since it's probably cheaper and certainly more uniform.             */
-/* FIXME - Consider doing the same elsewhere?                          */
+/* We need a mechanism to release the lock and invoke finalizers.       */
+/* We don't really have an opportunity to do this on a rarely executed  */
+/* path on which the lock is not held.  Thus we check at a              */
+/* rarely executed point at which it is safe to release the lock.       */
+/* We do this even where we could just call GC_INVOKE_FINALIZERS,       */
+/* since it's probably cheaper and certainly more uniform.              */
+/* FIXME - Consider doing the same elsewhere?                           */
 static void maybe_finalize(void)
 {
    static word last_finalized_no = 0;
@@ -126,18 +143,19 @@ static void maybe_finalize(void)
    if (!GC_is_initialized) return;
    UNLOCK();
    GC_INVOKE_FINALIZERS();
-   last_finalized_no = GC_gc_no;
    LOCK();
+   last_finalized_no = GC_gc_no;
 }
 
-/* Allocate an object, clear it, and store the pointer to the  */
-/* type structure (vtable in gcj).                             */
+/* Allocate an object, clear it, and store the pointer to the   */
+/* type structure (vtable in gcj).                              */
 /* This adds a byte at the end of the object if GC_malloc would.*/
 #ifdef THREAD_LOCAL_ALLOC
-  void * GC_core_gcj_malloc(size_t lb, void * ptr_to_struct_containing_descr)
+  GC_INNER void * GC_core_gcj_malloc(size_t lb,
+                                     void * ptr_to_struct_containing_descr)
 #else
   GC_API void * GC_CALL GC_gcj_malloc(size_t lb,
-                               void * ptr_to_struct_containing_descr)
+                                      void * ptr_to_struct_containing_descr)
 #endif
 {
     ptr_t op;
@@ -146,72 +164,75 @@ static void maybe_finalize(void)
     DCL_LOCK_STATE;
 
     if(SMALL_OBJ(lb)) {
-       lg = GC_size_map[lb];
-       opp = &(GC_gcjobjfreelist[lg]);
-       LOCK();
-       op = *opp;
+        lg = GC_size_map[lb];
+        opp = &(GC_gcjobjfreelist[lg]);
+        LOCK();
+        op = *opp;
         if(EXPECT(op == 0, 0)) {
-           maybe_finalize();
-            op = (ptr_t)GENERAL_MALLOC((word)lb, GC_gcj_kind);
-           if (0 == op) {
-               UNLOCK();
-               return(GC_oom_fn(lb));
-           }
+            maybe_finalize();
+            op = (ptr_t)GENERAL_MALLOC_INNER((word)lb, GC_gcj_kind);
+            if (0 == op) {
+                GC_oom_func oom_fn = GC_oom_fn;
+                UNLOCK();
+                return((*oom_fn)(lb));
+            }
         } else {
             *opp = obj_link(op);
             GC_bytes_allocd += GRANULES_TO_BYTES(lg);
         }
-       *(void **)op = ptr_to_struct_containing_descr;
-       GC_ASSERT(((void **)op)[1] == 0);
-       UNLOCK();
+        *(void **)op = ptr_to_struct_containing_descr;
+        GC_ASSERT(((void **)op)[1] == 0);
+        UNLOCK();
     } else {
-       LOCK();
-       maybe_finalize();
-       op = (ptr_t)GENERAL_MALLOC((word)lb, GC_gcj_kind);
-       if (0 == op) {
-           UNLOCK();
-           return(GC_oom_fn(lb));
-       }
-       *(void **)op = ptr_to_struct_containing_descr;
-       UNLOCK();
+        LOCK();
+        maybe_finalize();
+        op = (ptr_t)GENERAL_MALLOC_INNER((word)lb, GC_gcj_kind);
+        if (0 == op) {
+            GC_oom_func oom_fn = GC_oom_fn;
+            UNLOCK();
+            return((*oom_fn)(lb));
+        }
+        *(void **)op = ptr_to_struct_containing_descr;
+        UNLOCK();
     }
     return((void *) op);
 }
 
-void GC_start_debugging(void);
+GC_INNER void GC_start_debugging(void);
 
-/* Similar to GC_gcj_malloc, but add debug info.  This is allocated    */
-/* with GC_gcj_debug_kind.                                             */
+/* Similar to GC_gcj_malloc, but add debug info.  This is allocated     */
+/* with GC_gcj_debug_kind.                                              */
 GC_API void * GC_CALL GC_debug_gcj_malloc(size_t lb,
-               void * ptr_to_struct_containing_descr, GC_EXTRA_PARAMS)
+                void * ptr_to_struct_containing_descr, GC_EXTRA_PARAMS)
 {
     void * result;
 
-    /* We're careful to avoid extra calls, which could          */
-    /* confuse the backtrace.                                  */
+    /* We're careful to avoid extra calls, which could           */
+    /* confuse the backtrace.                                   */
     LOCK();
     maybe_finalize();
     result = GC_generic_malloc_inner(lb + DEBUG_BYTES, GC_gcj_debug_kind);
     if (result == 0) {
-       UNLOCK();
+        GC_oom_func oom_fn = GC_oom_fn;
+        UNLOCK();
         GC_err_printf("GC_debug_gcj_malloc(%ld, %p) returning NIL (",
-                     (unsigned long)lb, ptr_to_struct_containing_descr);
+                      (unsigned long)lb, ptr_to_struct_containing_descr);
         GC_err_puts(s);
         GC_err_printf(":%d)\n", i);
-        return(GC_oom_fn(lb));
+        return((*oom_fn)(lb));
     }
     *((void **)((ptr_t)result + sizeof(oh))) = ptr_to_struct_containing_descr;
     UNLOCK();
     if (!GC_debugging_started) {
-       GC_start_debugging();
+        GC_start_debugging();
     }
     ADD_CALL_CHAIN(result, ra);
     return (GC_store_debug_info(result, (word)lb, s, (word)i));
 }
 
-/* There is no THREAD_LOCAL_ALLOC for GC_gcj_malloc_ignore_off_page(). */
+/* There is no THREAD_LOCAL_ALLOC for GC_gcj_malloc_ignore_off_page().  */
 GC_API void * GC_CALL GC_gcj_malloc_ignore_off_page(size_t lb,
-                                    void * ptr_to_struct_containing_descr) 
+                                     void * ptr_to_struct_containing_descr)
 {
     ptr_t op;
     ptr_t * opp;
@@ -219,37 +240,34 @@ GC_API void * GC_CALL GC_gcj_malloc_ignore_off_page(size_t lb,
     DCL_LOCK_STATE;
 
     if(SMALL_OBJ(lb)) {
-       lg = GC_size_map[lb];
-       opp = &(GC_gcjobjfreelist[lg]);
-       LOCK();
+        lg = GC_size_map[lb];
+        opp = &(GC_gcjobjfreelist[lg]);
+        LOCK();
         if( (op = *opp) == 0 ) {
-           maybe_finalize();
-            op = (ptr_t)GENERAL_MALLOC_IOP(lb, GC_gcj_kind);
-           if (0 == op) {
-               UNLOCK();
-               return(GC_oom_fn(lb));
-           }
+            maybe_finalize();
+            op = (ptr_t)GENERAL_MALLOC_INNER_IOP(lb, GC_gcj_kind);
+            if (0 == op) {
+                GC_oom_func oom_fn = GC_oom_fn;
+                UNLOCK();
+                return((*oom_fn)(lb));
+            }
         } else {
             *opp = obj_link(op);
             GC_bytes_allocd += GRANULES_TO_BYTES(lg);
         }
     } else {
-       LOCK();
-       maybe_finalize();
-        op = (ptr_t)GENERAL_MALLOC_IOP(lb, GC_gcj_kind);
-       if (0 == op) {
-           UNLOCK();
-           return(GC_oom_fn(lb));
-       }
+        LOCK();
+        maybe_finalize();
+        op = (ptr_t)GENERAL_MALLOC_INNER_IOP(lb, GC_gcj_kind);
+        if (0 == op) {
+            GC_oom_func oom_fn = GC_oom_fn;
+            UNLOCK();
+            return((*oom_fn)(lb));
+        }
     }
     *(void **)op = ptr_to_struct_containing_descr;
     UNLOCK();
     return((void *) op);
 }
 
-#else
-
-extern int GC_quiet;
-       /* ANSI C doesn't allow translation units to be empty.  */
-
 #endif  /* GC_GCJ_SUPPORT */