]> granicus.if.org Git - gc/commitdiff
Enable 'Force GC at every GC_malloc' debug-related functionality
authorIvan Maidanski <ivmai@mail.ru>
Tue, 11 Sep 2012 19:03:55 +0000 (23:03 +0400)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 11 Sep 2012 19:03:55 +0000 (23:03 +0400)
* doc/README.environment (GC_COLLECT_AT_MALLOC): Document.
* doc/README.macros (GC_COLLECT_AT_MALLOC): Likewise.
* fnlz_mlc.c (GC_core_finalized_malloc): Insert
GC_DBG_COLLECT_AT_MALLOC invocation (before LOCK).
* gcj_mlc.c (GC_core_gcj_malloc, GC_gcj_malloc_ignore_off_page):
Likewise.
* malloc.c (GC_generic_malloc, GC_malloc_atomic, GC_malloc,
GC_malloc_uncollectable): Likewise.
* mallocx.c (GC_generic_malloc_ignore_off_page,
GC_generic_malloc_many, GC_malloc_atomic_uncollectable): Likewise.
* typd_mlc.c (GC_malloc_explicitly_typed,
GC_malloc_explicitly_typed_ignore_off_page): Likewise.
* include/private/gc_priv.h (GC_COLLECT_AT_MALLOC): Recognize new
macro.
(GC_dbg_collect_at_malloc_min_lb): New global variable declaration
(only if GC_COLLECT_AT_MALLOC defined).
(GC_DBG_COLLECT_AT_MALLOC): Define new macro (invoking GC_gcollect).
* malloc.c (GC_dbg_collect_at_malloc_min_lb): New global variable
(only if GC_COLLECT_AT_MALLOC defined).
* misc.c (GC_init): Test "GC_COLLECT_AT_MALLOC" environment variable
and alter default GC_dbg_collect_at_malloc_min_lb value (only if
GC_COLLECT_AT_MALLOC macro defined).

doc/README.environment
doc/README.macros
fnlz_mlc.c
gcj_mlc.c
include/private/gc_priv.h
malloc.c
mallocx.c
misc.c
typd_mlc.c

index 866e905591bfe92cc4eb2e8f4487c8f7c42d3fb2..79752f7834a229518f08a8f684d5a411c04064f4 100644 (file)
@@ -34,6 +34,10 @@ GC_DUMP_REGULARLY - Generate a GC debugging dump GC_dump() on startup
                     if you have a bug to report, but please include only the
                     last complete dump.
 
+GC_COLLECT_AT_MALLOC=<n> - Override the default value specified by
+                           GC_COLLECT_AT_MALLOC macro.  Has no effect unless
+                           GC is built with GC_COLLECT_AT_MALLOC defined.
+
 GC_BACKTRACES=<n> - Generate n random back-traces (for heap profiling) after
                     each GC.  Collector must have been built with
                     KEEP_BACK_PTRS.  This won't generate useful output unless
index 86334a4f786e8aa64e89ef7d68833fd1b2456912..6f3a8f501c3ba956fb7d494507de0a1726ed3400 100644 (file)
@@ -235,6 +235,10 @@ NO_DEBUGGING    Removes GC_dump and the debugging routines it calls.
 DEBUG_THREADS   Turn on printing additional thread-support debugging
   information.
 
+GC_COLLECT_AT_MALLOC=<n>        Force garbage collection at every
+  GC_malloc_* call with the size greater than the specified value.
+  (Might be useful for application debugging or in find-leak mode.)
+
 JAVA_FINALIZATION       Makes it somewhat safer to finalize objects out of
   order by specifying a nonstandard finalization mark procedure  (see
   finalize.c).  Objects reachable from finalizable objects will be marked
index 5017a700c1a300e1d7ced3af18406ca893b0b110..df1fd4ca9bd430d87f378fce06b2ca77eee30c6c 100644 (file)
@@ -93,6 +93,7 @@ GC_API void GC_CALL GC_register_disclaim_proc(int kind, GC_disclaim_proc proc,
     lb += sizeof(void *);
     GC_ASSERT(done_init);
     if (EXPECT(SMALL_OBJ(lb), TRUE)) {
+        GC_DBG_COLLECT_AT_MALLOC(lb);
         lg = GC_size_map[lb];
         opp = &GC_finalized_objfreelist[lg];
         LOCK();
index a749c622a5fde3af828f609489becd2b3fa44513..ea5c88160d2f91a568bc06e1c7f74beab46a50c1 100644 (file)
--- a/gcj_mlc.c
+++ b/gcj_mlc.c
@@ -168,6 +168,7 @@ static void maybe_finalize(void)
     word lg;
     DCL_LOCK_STATE;
 
+    GC_DBG_COLLECT_AT_MALLOC(lb);
     if(SMALL_OBJ(lb)) {
         lg = GC_size_map[lb];
         opp = &(GC_gcjobjfreelist[lg]);
@@ -243,6 +244,7 @@ GC_API void * GC_CALL GC_gcj_malloc_ignore_off_page(size_t lb,
     word lg;
     DCL_LOCK_STATE;
 
+    GC_DBG_COLLECT_AT_MALLOC(lb);
     if(SMALL_OBJ(lb)) {
         lg = GC_size_map[lb];
         opp = &(GC_gcjobjfreelist[lg]);
index 823e2c5f094be668641cecbd15a4a0af2f815d01..0df1a2281138acf06147821db3760e17d6ab84ae 100644 (file)
@@ -1806,6 +1806,16 @@ GC_INNER ptr_t GC_allocobj(size_t sz, int kind);
 #define GENERAL_MALLOC_IOP(lb,k) \
     GC_clear_stack(GC_generic_malloc_ignore_off_page(lb, k))
 
+#ifdef GC_COLLECT_AT_MALLOC
+  extern size_t GC_dbg_collect_at_malloc_min_lb;
+                            /* variable visible outside for debugging   */
+# define GC_DBG_COLLECT_AT_MALLOC(lb) \
+                (void)((lb) >= GC_dbg_collect_at_malloc_min_lb ? \
+                            (GC_gcollect(), 0) : 0)
+#else
+# define GC_DBG_COLLECT_AT_MALLOC(lb) (void)0
+#endif /* !GC_COLLECT_AT_MALLOC */
+
 /* Allocation routines that bypass the thread local cache.      */
 #ifdef THREAD_LOCAL_ALLOC
   GC_INNER void * GC_core_malloc(size_t);
index 8e5552f8090e5da75c1254e0f8855f139a0f31a0..0bf84b22deaa3242b523bd725a5fd5961231a25a 100644 (file)
--- a/malloc.c
+++ b/malloc.c
@@ -161,6 +161,12 @@ GC_INNER void * GC_generic_malloc_inner_ignore_off_page(size_t lb, int k)
     return op;
 }
 
+#ifdef GC_COLLECT_AT_MALLOC
+  /* Parameter to force GC at every malloc of size greater or equal to  */
+  /* the given value.  This might be handy during debugging.            */
+  size_t GC_dbg_collect_at_malloc_min_lb = (GC_COLLECT_AT_MALLOC);
+#endif
+
 GC_API void * GC_CALL GC_generic_malloc(size_t lb, int k)
 {
     void * result;
@@ -169,6 +175,7 @@ GC_API void * GC_CALL GC_generic_malloc(size_t lb, int k)
     if (EXPECT(GC_have_errors, FALSE))
       GC_print_all_errors();
     GC_INVOKE_FINALIZERS();
+    GC_DBG_COLLECT_AT_MALLOC(lb);
     if (SMALL_OBJ(lb)) {
         LOCK();
         result = GC_generic_malloc_inner((word)lb, k);
@@ -178,6 +185,7 @@ GC_API void * GC_CALL GC_generic_malloc(size_t lb, int k)
         size_t lb_rounded;
         word n_blocks;
         GC_bool init;
+
         lg = ROUNDED_UP_GRANULES(lb);
         lb_rounded = GRANULES_TO_BYTES(lg);
         if (lb_rounded < lb)
@@ -226,6 +234,7 @@ GC_API void * GC_CALL GC_generic_malloc(size_t lb, int k)
     DCL_LOCK_STATE;
 
     if(SMALL_OBJ(lb)) {
+        GC_DBG_COLLECT_AT_MALLOC(lb);
         lg = GC_size_map[lb];
         opp = &(GC_aobjfreelist[lg]);
         LOCK();
@@ -255,6 +264,7 @@ GC_API void * GC_CALL GC_generic_malloc(size_t lb, int k)
     DCL_LOCK_STATE;
 
     if(SMALL_OBJ(lb)) {
+        GC_DBG_COLLECT_AT_MALLOC(lb);
         lg = GC_size_map[lb];
         opp = (void **)&(GC_objfreelist[lg]);
         LOCK();
@@ -286,6 +296,7 @@ GC_API void * GC_CALL GC_malloc_uncollectable(size_t lb)
     DCL_LOCK_STATE;
 
     if( SMALL_OBJ(lb) ) {
+        GC_DBG_COLLECT_AT_MALLOC(lb);
         if (EXTRA_BYTES != 0 && lb != 0) lb--;
                   /* We don't need the extra byte, since this won't be  */
                   /* collected anyway.                                  */
index 6f3b206463da694dabff7c4ac3bac86082786622..bf7f9f06013c86c5d0748266839515efbcd4a20e 100644 (file)
--- a/mallocx.c
+++ b/mallocx.c
@@ -189,6 +189,7 @@ GC_INNER void * GC_generic_malloc_ignore_off_page(size_t lb, int k)
     if (EXPECT(GC_have_errors, FALSE))
       GC_print_all_errors();
     GC_INVOKE_FINALIZERS();
+    GC_DBG_COLLECT_AT_MALLOC(lb);
     LOCK();
     result = (ptr_t)GC_alloc_large(ADD_SLOP(lb), k, IGNORE_OFF_PAGE);
     if (0 != result) {
@@ -293,6 +294,7 @@ GC_API void GC_CALL GC_generic_malloc_many(size_t lb, int k, void **result)
     if (EXPECT(GC_have_errors, FALSE))
       GC_print_all_errors();
     GC_INVOKE_FINALIZERS();
+    GC_DBG_COLLECT_AT_MALLOC(lb);
     LOCK();
     if (!EXPECT(GC_is_initialized, TRUE)) GC_init();
     /* Do our share of marking work */
@@ -513,6 +515,7 @@ GC_API int GC_CALL GC_posix_memalign(void **memptr, size_t align, size_t lb)
     DCL_LOCK_STATE;
 
     if( SMALL_OBJ(lb) ) {
+        GC_DBG_COLLECT_AT_MALLOC(lb);
         if (EXTRA_BYTES != 0 && lb != 0) lb--;
                   /* We don't need the extra byte, since this won't be  */
                   /* collected anyway.                                  */
diff --git a/misc.c b/misc.c
index 0133c1a61b7ecf61c5d6137425ef30266371894a..c886d71778a74831f913ca573113c13e74ecd5cc 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -876,6 +876,16 @@ GC_API void GC_CALL GC_init(void)
 #       endif
       }
     }
+#   ifdef GC_COLLECT_AT_MALLOC
+      {
+        char * string = GETENV("GC_COLLECT_AT_MALLOC");
+        if (0 != string) {
+          size_t min_lb = (size_t)STRTOULL(string, NULL, 10);
+          if (min_lb > 0)
+            GC_dbg_collect_at_malloc_min_lb = min_lb;
+        }
+      }
+#   endif
 #   ifndef GC_DISABLE_INCREMENTAL
       {
         char * time_limit_string = GETENV("GC_PAUSE_TIME_TARGET");
index 9a223047627f17a9b4e0b346f8a9334238cb26e9..827cc4f3801946fd2f257211a06ea2f5b2680ebe 100644 (file)
@@ -592,6 +592,7 @@ GC_API void * GC_CALL GC_malloc_explicitly_typed(size_t lb, GC_descr d)
 
     lb += TYPD_EXTRA_BYTES;
     if(SMALL_OBJ(lb)) {
+        GC_DBG_COLLECT_AT_MALLOC(lb);
         lg = GC_size_map[lb];
         opp = &(GC_eobjfreelist[lg]);
         LOCK();
@@ -628,6 +629,7 @@ GC_API void * GC_CALL GC_malloc_explicitly_typed_ignore_off_page(size_t lb,
 
     lb += TYPD_EXTRA_BYTES;
     if( SMALL_OBJ(lb) ) {
+        GC_DBG_COLLECT_AT_MALLOC(lb);
         lg = GC_size_map[lb];
         opp = &(GC_eobjfreelist[lg]);
         LOCK();