]> granicus.if.org Git - gc/commitdiff
Allow to exclude finalization support by GC_NO_FINALIZATION macro
authorIvan Maidanski <ivmai@mail.ru>
Mon, 6 Feb 2012 15:49:06 +0000 (19:49 +0400)
committerIvan Maidanski <ivmai@mail.ru>
Mon, 6 Feb 2012 16:48:06 +0000 (20:48 +0400)
* doc/README.macros (GC_NO_FINALIZATION): Document.
* alloc.c (GC_finish_collection): Do not call GC_finalize and
GC_print_finalization_stats if GC_NO_FINALIZATION.
* dbg_mlc.c (closure, GC_make_closure, GC_debug_invoke_finalizer,
OFN_UNSET, store_old, GC_debug_register_finalizer,
GC_debug_register_finalizer_no_order,
GC_debug_register_finalizer_unreachable,
GC_debug_register_finalizer_ignore_self): Do not define if
GC_NO_FINALIZATION.
* finalize.c: Skip all definitions if GC_NO_FINALIZATION.
* finalize.c (GC_call_with_alloc_lock): Move to misc.c.
* include/private/gc_priv.h (GC_INVOKE_FINALIZERS): Define to empty
if GC_NO_FINALIZATION.
* include/private/gc_priv.h (GC_notify_or_invoke_finalizers,
GC_push_finalizer_structures, GC_finalize,
GC_print_finalization_stats): Do not declare if GC_NO_FINALIZATION.
* mark_rts.c (GC_push_gc_structures): Do not call
GC_push_finalizer_structures if GC_NO_FINALIZATION.
* misc.c (GC_call_with_alloc_lock): Move from "finalize" module.
* tests/test.c (mktree): Do not declare "my_index" and "new_link"
local variables, do not update live_indicators_count, do not call
GC_REGISTER_FINALIZER, GC_GENERAL_REGISTER_DISAPPEARING_LINK,
GC_move_disappearing_link, GC_unregister_disappearing_link if
GC_NO_FINALIZATION.
* tests/test.c (check_heap_stats): Do not declare "still_live",
"late_finalize_count" local variables and do not check finalization
for failures if GC_NO_FINALIZATION.

alloc.c
dbg_mlc.c
doc/README.macros
finalize.c
include/private/gc_priv.h
mark_rts.c
misc.c
tests/test.c
typd_mlc.c

diff --git a/alloc.c b/alloc.c
index a8231281e5d29be4a9dc4511cb02baaa8d189659..2a6b9fa8e0d2740b9243fdd0166b10b1f89ff0bc 100644 (file)
--- a/alloc.c
+++ b/alloc.c
@@ -841,7 +841,9 @@ STATIC void GC_finish_collection(void)
         /* The above just checks; it doesn't really reclaim anything.   */
     }
 
-    GC_finalize();
+#   ifndef GC_NO_FINALIZATION
+      GC_finalize();
+#   endif
 #   ifdef STUBBORN_ALLOC
       GC_clean_changing_list();
 #   endif
@@ -923,7 +925,9 @@ STATIC void GC_finish_collection(void)
         GET_TIME(done_time);
 
         /* A convenient place to output finalization statistics. */
-        GC_print_finalization_stats();
+#       ifndef GC_NO_FINALIZATION
+          GC_print_finalization_stats();
+#       endif
 
         GC_log_printf("Finalize plus initiate sweep took %lu + %lu msecs\n",
                       MS_TIME_DIFF(finalize_time,start_time),
index 932aaacae52a465900cf1cbcf880c5ad5e9631a0..94cbe162ebbebab2968461d51475b276804edb3d 100644 (file)
--- a/dbg_mlc.c
+++ b/dbg_mlc.c
@@ -987,6 +987,8 @@ GC_INNER GC_bool GC_check_leaked(ptr_t base)
 
 #endif /* !SHORT_DBG_HDRS */
 
+#ifndef GC_NO_FINALIZATION
+
 struct closure {
     GC_finalization_proc cl_fn;
     void * cl_data;
@@ -1165,6 +1167,8 @@ GC_API void GC_CALL GC_debug_register_finalizer_ignore_self
     store_old(obj, my_old_fn, (struct closure *)my_old_cd, ofn, ocd);
 }
 
+#endif /* !GC_NO_FINALIZATION */
+
 GC_API void * GC_CALL GC_debug_malloc_replacement(size_t lb)
 {
     return GC_debug_malloc(lb, GC_DBG_RA "unknown", 0);
index 09a05fcafa31a5804b6905e959f34f796c3f6e9e..e04037dc4d39e8f794aa7e4671fd2378610b56c6 100644 (file)
@@ -248,6 +248,8 @@ FINALIZE_ON_DEMAND      Causes finalizers to be run only in response
   In 5.0 this became runtime adjustable, and this only determines the
   initial value of GC_finalize_on_demand.
 
+GC_NO_FINALIZATION      Exclude finalization support (for smaller code size)
+
 ATOMIC_UNCOLLECTABLE    Includes code for GC_malloc_atomic_uncollectable.
   This is useful if either the vendor malloc implementation is poor,
   or if REDIRECT_MALLOC is used.
index a4c7ef5a0e69400b0d2e457e6cb3626f43c26f80..012c33579f67d24b8cf6846f014ce16bcf9f2b64 100644 (file)
@@ -16,6 +16,8 @@
 
 #include "private/gc_pmark.h"
 
+#ifndef GC_NO_FINALIZATION
+
 /* Type of mark procedure used for marking from finalizable object.     */
 /* This procedure normally does not mark the object, only its           */
 /* descendents.                                                         */
@@ -949,27 +951,6 @@ GC_INNER void GC_notify_or_invoke_finalizers(void)
         (*notifier_fn)(); /* Invoke the notifier */
 }
 
-GC_API void * GC_CALL GC_call_with_alloc_lock(GC_fn_type fn,
-                                              void * client_data)
-{
-    void * result;
-    DCL_LOCK_STATE;
-
-#   ifdef THREADS
-      LOCK();
-      /* FIXME - This looks wrong!! */
-      SET_LOCK_HOLDER();
-#   endif
-    result = (*fn)(client_data);
-#   ifdef THREADS
-#     ifndef GC_ASSERTIONS
-        UNSET_LOCK_HOLDER();
-#     endif /* o.w. UNLOCK() does it implicitly */
-      UNLOCK();
-#   endif
-    return(result);
-}
-
 #ifndef SMALL_CONFIG
   GC_INNER void GC_print_finalization_stats(void)
   {
@@ -985,3 +966,5 @@ GC_API void * GC_CALL GC_call_with_alloc_lock(GC_fn_type fn,
                   ready, (long)GC_old_dl_entries - (long)GC_dl_entries);
   }
 #endif /* !SMALL_CONFIG */
+
+#endif /* !GC_NO_FINALIZATION */
index e2af73f3afe5098fe263cc67b1388e11abfb68b8..4466e00a9893063d0217cea5763f1cd968820c90 100644 (file)
@@ -247,7 +247,29 @@ typedef char * ptr_t;   /* A generic pointer to which we can add        */
                     /* through GC_all_interior_pointers.                */
 
 
-#define GC_INVOKE_FINALIZERS() GC_notify_or_invoke_finalizers()
+#ifndef GC_NO_FINALIZATION
+#  define GC_INVOKE_FINALIZERS() GC_notify_or_invoke_finalizers()
+   GC_INNER void GC_notify_or_invoke_finalizers(void);
+                        /* If GC_finalize_on_demand is not set, invoke  */
+                        /* eligible finalizers. Otherwise:              */
+                        /* Call *GC_finalizer_notifier if there are     */
+                        /* finalizers to be run, and we haven't called  */
+                        /* this procedure yet this GC cycle.            */
+
+   GC_INNER void GC_push_finalizer_structures(void);
+   GC_INNER void GC_finalize(void);
+                        /* Perform all indicated finalization actions   */
+                        /* on unmarked objects.                         */
+                        /* Unreachable finalizable objects are enqueued */
+                        /* for processing by GC_invoke_finalizers.      */
+                        /* Invoked with lock.                           */
+
+#  ifndef SMALL_CONFIG
+     GC_INNER void GC_print_finalization_stats(void);
+#  endif
+#else
+#  define GC_INVOKE_FINALIZERS() (void)0
+#endif /* GC_NO_FINALIZATION */
 
 #if !defined(DONT_ADD_BYTE_AT_END)
 # ifdef LINT2
@@ -1517,7 +1539,6 @@ GC_EXTERN void (*GC_push_other_roots)(void);
                         /* supplied replacement should also call the    */
                         /* original function.                           */
 
-GC_INNER void GC_push_finalizer_structures(void);
 #ifdef THREADS
   void GC_push_thread_structures(void);
 #endif
@@ -1803,20 +1824,6 @@ GC_INNER void GC_remove_counts(struct hblk * h, size_t sz);
                                 /* Remove forwarding counts for h.      */
 GC_INNER hdr * GC_find_header(ptr_t h);
 
-GC_INNER void GC_finalize(void);
-                        /* Perform all indicated finalization actions   */
-                        /* on unmarked objects.                         */
-                        /* Unreachable finalizable objects are enqueued */
-                        /* for processing by GC_invoke_finalizers.      */
-                        /* Invoked with lock.                           */
-
-GC_INNER void GC_notify_or_invoke_finalizers(void);
-                        /* If GC_finalize_on_demand is not set, invoke  */
-                        /* eligible finalizers. Otherwise:              */
-                        /* Call *GC_finalizer_notifier if there are     */
-                        /* finalizers to be run, and we haven't called  */
-                        /* this procedure yet this GC cycle.            */
-
 GC_INNER void GC_add_to_heap(struct hblk *p, size_t bytes);
                         /* Add a HBLKSIZE aligned chunk to the heap.    */
 
@@ -1961,9 +1968,6 @@ void GC_print_block_list(void);
 void GC_print_hblkfreelist(void);
 void GC_print_heap_sects(void);
 void GC_print_static_roots(void);
-#ifndef SMALL_CONFIG
-  GC_INNER void GC_print_finalization_stats(void);
-#endif
 /* void GC_dump(void); - declared in gc.h */
 
 extern word GC_fo_entries; /* should be visible in extra/MacOS.c */
index 8bd9ddc2eeef15b4568ad4578c74569cc9505f14..a57ac3e9600568469a8a8708abad771e7d526d29 100644 (file)
@@ -706,7 +706,9 @@ GC_INNER void (*GC_push_typed_structures)(void) = 0;
  */
 STATIC void GC_push_gc_structures(void)
 {
-    GC_push_finalizer_structures();
+#   ifndef GC_NO_FINALIZATION
+      GC_push_finalizer_structures();
+#   endif
 #   if defined(THREADS)
       GC_push_thread_structures();
 #   endif
diff --git a/misc.c b/misc.c
index 3d6a579bfad45dd9da6944f8e6445959d9e09626..68d2fe4602931c4fd3727193f81c45f039a1a7db 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -1562,6 +1562,26 @@ GC_API unsigned GC_CALL GC_new_proc(GC_mark_proc proc)
     return result;
 }
 
+GC_API void * GC_CALL GC_call_with_alloc_lock(GC_fn_type fn, void *client_data)
+{
+    void * result;
+    DCL_LOCK_STATE;
+
+#   ifdef THREADS
+      LOCK();
+      /* FIXME - This looks wrong!! */
+      SET_LOCK_HOLDER();
+#   endif
+    result = (*fn)(client_data);
+#   ifdef THREADS
+#     ifndef GC_ASSERTIONS
+        UNSET_LOCK_HOLDER();
+#     endif /* o.w. UNLOCK() does it implicitly */
+      UNLOCK();
+#   endif
+    return(result);
+}
+
 GC_API void * GC_CALL GC_call_with_stack_base(GC_stack_base_func fn, void *arg)
 {
     int dummy;
index cf6c383d663cbfb1cb8cee536fc47064634377aa..5201d4b4bd8d008f2828cad55114508d29b8b4e4 100644 (file)
@@ -732,8 +732,10 @@ tn * mktree(int n)
         result -> rchild -> lchild = tmp;
     }
     if (counter++ % 119 == 0) {
-        int my_index;
-        void *new_link;
+#       ifndef GC_NO_FINALIZATION
+          int my_index;
+          void *new_link;
+#       endif
 
         {
 #         ifdef PCR
@@ -747,7 +749,9 @@ tn * mktree(int n)
 #         endif
                 /* Losing a count here causes erroneous report of failure. */
           finalizable_count++;
-          my_index = live_indicators_count++;
+#         ifndef GC_NO_FINALIZATION
+            my_index = live_indicators_count++;
+#         endif
 #         ifdef PCR
             PCR_ThCrSec_ExitSys();
 #         endif
@@ -758,6 +762,7 @@ tn * mktree(int n)
 #         endif
         }
 
+#     ifndef GC_NO_FINALIZATION
         GC_REGISTER_FINALIZER((void *)result, finalizer, (void *)(GC_word)n,
                               (GC_finalization_proc *)0, (void * *)0);
         if (my_index >= MAX_FINALIZED) {
@@ -795,6 +800,7 @@ tn * mktree(int n)
                 GC_printf("GC_general_register_disappearing_link failed 2\n");
                 FAIL;
         }
+#     endif
         GC_reachable_here(result);
     }
     return(result);
@@ -1281,9 +1287,11 @@ void check_heap_stats(void)
 {
     size_t max_heap_sz;
     int i;
-    int still_live;
-#   ifdef FINALIZE_ON_DEMAND
+#   ifndef GC_NO_FINALIZATION
+      int still_live;
+#     ifdef FINALIZE_ON_DEMAND
         int late_finalize_count = 0;
+#     endif
 #   endif
 
 #   ifdef VERY_SMALL_CONFIG
@@ -1322,10 +1330,12 @@ void check_heap_stats(void)
       while (GC_collect_a_little()) { }
       for (i = 0; i < 16; i++) {
         GC_gcollect();
-#   ifdef FINALIZE_ON_DEMAND
-           late_finalize_count +=
-#   endif
+#       ifndef GC_NO_FINALIZATION
+#         ifdef FINALIZE_ON_DEMAND
+            late_finalize_count +=
+#         endif
                 GC_invoke_finalizers();
+#       endif
       }
       if (GC_print_stats) {
         struct GC_stack_base sb;
@@ -1348,27 +1358,28 @@ void check_heap_stats(void)
     GC_printf("Allocated %d stubborn objects\n", stubborn_count);
     GC_printf("Finalized %d/%d objects - ",
                   finalized_count, finalizable_count);
-#   ifdef FINALIZE_ON_DEMAND
+#   ifndef GC_NO_FINALIZATION
+#     ifdef FINALIZE_ON_DEMAND
         if (finalized_count != late_finalize_count) {
             GC_printf("Demand finalization error\n");
             FAIL;
         }
-#   endif
-    if (finalized_count > finalizable_count
-        || finalized_count < finalizable_count/2) {
+#     endif
+      if (finalized_count > finalizable_count
+          || finalized_count < finalizable_count/2) {
         GC_printf("finalization is probably broken\n");
         FAIL;
-    } else {
+      } else {
         GC_printf("finalization is probably ok\n");
-    }
-    still_live = 0;
-    for (i = 0; i < MAX_FINALIZED; i++) {
+      }
+      still_live = 0;
+      for (i = 0; i < MAX_FINALIZED; i++) {
         if (live_indicators[i] != 0) {
             still_live++;
         }
-    }
-    i = finalizable_count - finalized_count - still_live;
-    if (0 != i) {
+      }
+      i = finalizable_count - finalized_count - still_live;
+      if (0 != i) {
         GC_printf("%d disappearing links remain and %d more objects "
                       "were not finalized\n", still_live, i);
         if (i > 10) {
@@ -1376,7 +1387,8 @@ void check_heap_stats(void)
         } else {
             GC_printf("\tSlightly suspicious, but probably OK\n");
         }
-    }
+      }
+#   endif
     GC_printf("Total number of bytes allocated is %lu\n",
                   (unsigned long)GC_get_total_bytes());
     GC_printf("Final heap size is %lu bytes\n",
index ce5c4c82a576eda33a1d012861a2e2b85af3d3a9..0326532a07be43aa391bf6f889c07421b0727e24 100644 (file)
@@ -714,13 +714,16 @@ GC_API void * GC_CALL GC_calloc_explicitly_typed(size_t n, size_t lb,
        lp -> ld_descriptor = leaf.ld_descriptor;
        ((volatile word *)op)[GRANULES_TO_WORDS(lg) - 1] = (word)lp;
    } else {
+#    ifndef GC_NO_FINALIZATION
        size_t lw = GRANULES_TO_WORDS(lg);
 
        ((word *)op)[lw - 1] = (word)complex_descr;
        /* Make sure the descriptor is cleared once there is any danger  */
        /* it may have been collected.                                   */
        if (GC_general_register_disappearing_link((void * *)((word *)op+lw-1),
-                                                 op) == GC_NO_MEMORY) {
+                                                 op) == GC_NO_MEMORY)
+#    endif
+       {
            /* Couldn't register it due to lack of memory.  Punt.        */
            /* This will probably fail too, but gives the recovery code  */
            /* a chance.                                                 */