summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2012-09-11 23:03:55 +0400
committerIvan Maidanski <ivmai@mail.ru>2012-09-11 23:03:55 +0400
commit9dbe549fded38f9a456004831a9eced840a6ce36 (patch)
tree08e2c078a9257058529b6a6d07a3304481a715d6
parent8102d42dd2e5b398e1085d5e3a90fdbee5ed6ed1 (diff)
downloadbdwgc-9dbe549fded38f9a456004831a9eced840a6ce36.tar.gz
Enable 'Force GC at every GC_malloc' debug-related functionality
* 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).
-rw-r--r--doc/README.environment4
-rw-r--r--doc/README.macros4
-rw-r--r--fnlz_mlc.c1
-rw-r--r--gcj_mlc.c2
-rw-r--r--include/private/gc_priv.h10
-rw-r--r--malloc.c11
-rw-r--r--mallocx.c3
-rw-r--r--misc.c10
-rw-r--r--typd_mlc.c2
9 files changed, 47 insertions, 0 deletions
diff --git a/doc/README.environment b/doc/README.environment
index 866e9055..79752f78 100644
--- a/doc/README.environment
+++ b/doc/README.environment
@@ -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
diff --git a/doc/README.macros b/doc/README.macros
index 86334a4f..6f3a8f50 100644
--- a/doc/README.macros
+++ b/doc/README.macros
@@ -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
diff --git a/fnlz_mlc.c b/fnlz_mlc.c
index 5017a700..df1fd4ca 100644
--- a/fnlz_mlc.c
+++ b/fnlz_mlc.c
@@ -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();
diff --git a/gcj_mlc.c b/gcj_mlc.c
index a749c622..ea5c8816 100644
--- 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]);
diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h
index 823e2c5f..0df1a228 100644
--- a/include/private/gc_priv.h
+++ b/include/private/gc_priv.h
@@ -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);
diff --git a/malloc.c b/malloc.c
index 8e5552f8..0bf84b22 100644
--- 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. */
diff --git a/mallocx.c b/mallocx.c
index 6f3b2064..bf7f9f06 100644
--- 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 0133c1a6..c886d717 100644
--- 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");
diff --git a/typd_mlc.c b/typd_mlc.c
index 9a223047..827cc4f3 100644
--- a/typd_mlc.c
+++ b/typd_mlc.c
@@ -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();