+2011-04-07 Ivan Maidanski <ivmai@mail.ru>
+
+ * alloc.c (GC_check_heap, GC_print_all_smashed): Move the
+ definition from misc.c.
+ * dbg_mlc.c (GC_debug_malloc_atomic_uncollectable): Define as
+ public.
+ * include/gc.h (GC_debug_malloc_atomic_uncollectable): Declare.
+ * include/gc.h (GC_MALLOC_ATOMIC_UNCOLLECTABLE): Define new public
+ macro.
+ * dbg_mlc.c (MAX_SMASHED): Don't define if already set.
+ * reclaim.c (MAX_LEAKED): Ditto.
+ * dbg_mlc.c (GC_add_smashed): Add FIXME about the concurrent
+ access to the global array.
+ * reclaim.c (GC_add_leaked): Ditto.
+ * misc.c (GC_print_back_height): Set on if GC_PRINT_BACK_HEIGHT
+ (new macro) is defined.
+ * doc/README.macros (GC_PRINT_BACK_HEIGHT): Document.
+ * misc.c (GC_dump_regularly, GC_init): Replace 0/1 for
+ GC_dump_regularly and GC_print_back_height variables with
+ FALSE/TRUE.
+ * reclaim.c (GC_print_all_errors): Refine the comment.
+
2011-04-04 Ivan Maidanski <ivmai@mail.ru>
* tests/test.c (reverse_test_inner): Undo one of the previous
RESTORE_CANCEL(cancel_state);
}
+GC_INNER void (*GC_check_heap)(void) = 0;
+GC_INNER void (*GC_print_all_smashed)(void) = 0;
+
GC_API int GC_CALL GC_collect_a_little(void)
{
int result;
ADD_CALL_CHAIN(result, GC_RETURN_ADDR);
return (GC_store_debug_info_inner(result, (word)lb, "INTERNAL", (word)0));
}
-#endif
+#endif /* DBG_HDRS_ALL */
#ifdef STUBBORN_ALLOC
-GC_API void * GC_CALL GC_debug_malloc_stubborn(size_t lb, GC_EXTRA_PARAMS)
-{
+ GC_API void * GC_CALL GC_debug_malloc_stubborn(size_t lb, GC_EXTRA_PARAMS)
+ {
void * result = GC_malloc_stubborn(lb + DEBUG_BYTES);
if (result == 0) {
}
ADD_CALL_CHAIN(result, ra);
return (GC_store_debug_info(result, (word)lb, s, (word)i));
-}
+ }
-GC_API void GC_CALL GC_debug_change_stubborn(void *p)
-{
+ GC_API void GC_CALL GC_debug_change_stubborn(void *p)
+ {
void * q = GC_base(p);
hdr * hhdr;
ABORT("GC_debug_change_stubborn: arg not stubborn");
}
GC_change_stubborn(q);
-}
+ }
-GC_API void GC_CALL GC_debug_end_stubborn_change(void *p)
-{
+ GC_API void GC_CALL GC_debug_end_stubborn_change(void *p)
+ {
void * q = GC_base(p);
hdr * hhdr;
ABORT("GC_debug_end_stubborn_change: arg not stubborn");
}
GC_end_stubborn_change(q);
-}
+ }
#else /* !STUBBORN_ALLOC */
-GC_API void * GC_CALL GC_debug_malloc_stubborn(size_t lb, GC_EXTRA_PARAMS)
-{
+ GC_API void * GC_CALL GC_debug_malloc_stubborn(size_t lb, GC_EXTRA_PARAMS)
+ {
return GC_debug_malloc(lb, OPT_RA s, i);
-}
-
-/*ARGSUSED*/
-GC_API void GC_CALL GC_debug_change_stubborn(void *p) {}
+ }
-/*ARGSUSED*/
-GC_API void GC_CALL GC_debug_end_stubborn_change(void *p) {}
+ /*ARGSUSED*/
+ GC_API void GC_CALL GC_debug_change_stubborn(void *p) {}
+ /*ARGSUSED*/
+ GC_API void GC_CALL GC_debug_end_stubborn_change(void *p) {}
#endif /* !STUBBORN_ALLOC */
GC_API void * GC_CALL GC_debug_malloc_atomic(size_t lb, GC_EXTRA_PARAMS)
}
#ifdef ATOMIC_UNCOLLECTABLE
- void * GC_debug_malloc_atomic_uncollectable(size_t lb, GC_EXTRA_PARAMS)
+ GC_API void * GC_CALL GC_debug_malloc_atomic_uncollectable(size_t lb,
+ GC_EXTRA_PARAMS)
{
void * result =
GC_malloc_atomic_uncollectable(lb + UNCOLLECTABLE_DEBUG_BYTES);
/* always print them nicely with the allocation lock held. */
/* We put them here instead of in GC_arrays, since it may be useful to */
/* be able to look at them with the debugger. */
-#define MAX_SMASHED 20
+#ifndef MAX_SMASHED
+# define MAX_SMASHED 20
+#endif
STATIC ptr_t GC_smashed[MAX_SMASHED] = {0};
STATIC unsigned GC_n_smashed = 0;
STATIC void GC_add_smashed(ptr_t smashed)
{
GC_ASSERT(GC_is_marked(GC_base(smashed)));
+ /* FIXME: Prevent adding an object while printing smashed list. */
GC_smashed[GC_n_smashed] = smashed;
if (GC_n_smashed < MAX_SMASHED - 1) ++GC_n_smashed;
/* In case of overflow, we keep the first MAX_SMASHED-1 */
support. Implies DBG_HDRS_ALL. All allocation should be done using
the debug interface.
+GC_PRINT_BACK_HEIGHT Permanently turn on back-height printing mode
+ (useful when NO_GETENV). See the similar environment variable description
+ in README.environment. Requires MAKE_BACK_GRAPH defined.
+
STUBBORN_ALLOC Allows allocation of "hard to change" objects, and thus
makes incremental collection easier. Was enabled by default until 6.0.
Rarely used, to my knowledge.
GC_API int GC_CALL GC_posix_memalign(void ** /* memptr */, size_t /* align */,
size_t /* lb */);
-/* The following is only defined if the library has been suitably */
-/* compiled: */
-GC_API void * GC_CALL GC_malloc_atomic_uncollectable(
- size_t /* size_in_bytes */)
- GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1);
-
/* Explicitly deallocate an object. Dangerous if used incorrectly. */
/* Requires a pointer to the base of an object. */
/* If the argument is stubborn, it should not be changeable when freed. */
# define GC_EXTRA_PARAMS const char * s, int i
#endif
+/* The following is only defined if the library has been suitably */
+/* compiled: */
+GC_API void * GC_CALL GC_malloc_atomic_uncollectable(
+ size_t /* size_in_bytes */)
+ GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1);
+GC_API void * GC_CALL GC_debug_malloc_atomic_uncollectable(size_t,
+ GC_EXTRA_PARAMS)
+ GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1);
+
/* Debugging (annotated) allocation. GC_gcollect will check */
/* objects allocated in this way for overwrites, etc. */
GC_API void * GC_CALL GC_debug_malloc(size_t /* size_in_bytes */,
# define GC_MALLOC_ATOMIC(sz) GC_debug_malloc_atomic(sz, GC_EXTRAS)
# define GC_STRDUP(s) GC_debug_strdup(s, GC_EXTRAS)
# define GC_STRNDUP(s, sz) GC_debug_strndup(s, sz, GC_EXTRAS)
+# define GC_MALLOC_ATOMIC_UNCOLLECTABLE(sz) \
+ GC_debug_malloc_atomic_uncollectable(sz, GC_EXTRAS)
# define GC_MALLOC_UNCOLLECTABLE(sz) \
GC_debug_malloc_uncollectable(sz, GC_EXTRAS)
# define GC_MALLOC_IGNORE_OFF_PAGE(sz) \
# define GC_MALLOC_ATOMIC(sz) GC_malloc_atomic(sz)
# define GC_STRDUP(s) GC_strdup(s)
# define GC_STRNDUP(s, sz) GC_strndup(s, sz)
+# define GC_MALLOC_ATOMIC_UNCOLLECTABLE(sz) GC_malloc_atomic_uncollectable(sz)
# define GC_MALLOC_UNCOLLECTABLE(sz) GC_malloc_uncollectable(sz)
# define GC_MALLOC_IGNORE_OFF_PAGE(sz) \
GC_malloc_ignore_off_page(sz)
GC_EXTERN GC_bool GC_have_errors; /* We saw a smashed or leaked object. */
/* Call error printing routine */
- /* occasionally. */
+ /* occasionally. It is ok to read it */
+ /* without acquiring the lock. */
#ifndef SMALL_CONFIG
/* GC_print_stats should be visible outside the GC in some cases. */
GC_INNER GC_bool GC_debugging_started = FALSE;
/* defined here so we don't have to load debug_malloc.o */
-GC_INNER void (*GC_check_heap)(void) = 0;
-GC_INNER void (*GC_print_all_smashed)(void) = 0;
-
ptr_t GC_stackbottom = 0;
#ifdef IA64
GC_bool GC_print_stats = 0;
#endif
-GC_INNER GC_bool GC_print_back_height = 0;
+#ifdef GC_PRINT_BACK_HEIGHT
+ GC_INNER GC_bool GC_print_back_height = TRUE;
+#else
+ GC_INNER GC_bool GC_print_back_height = FALSE;
+#endif
#ifndef NO_DEBUGGING
- GC_INNER GC_bool GC_dump_regularly = 0;
+ GC_INNER GC_bool GC_dump_regularly = FALSE;
/* Generate regular debugging dumps. */
#endif
# endif /* !SMALL_CONFIG */
# ifndef NO_DEBUGGING
if (0 != GETENV("GC_DUMP_REGULARLY")) {
- GC_dump_regularly = 1;
+ GC_dump_regularly = TRUE;
}
# endif
# ifdef KEEP_BACK_PTRS
GC_dont_gc = 1;
}
if (0 != GETENV("GC_PRINT_BACK_HEIGHT")) {
- GC_print_back_height = 1;
+ GC_print_back_height = TRUE;
}
if (0 != GETENV("GC_NO_BLACKLIST_WARNING")) {
GC_large_alloc_warn_interval = LONG_MAX;
/* We defer printing of leaked objects until we're done with the GC */
/* cycle, since the routine for printing objects needs to run outside */
/* the collector, e.g. without the allocation lock. */
-#define MAX_LEAKED 40
+#ifndef MAX_LEAKED
+# define MAX_LEAKED 40
+#endif
STATIC ptr_t GC_leaked[MAX_LEAKED] = { NULL };
STATIC unsigned GC_n_leaked = 0;
STATIC void GC_add_leaked(ptr_t leaked)
{
+ GC_have_errors = TRUE;
+ /* FIXME: Prevent adding an object while printing leaked ones. */
if (GC_n_leaked < MAX_LEAKED) {
- GC_have_errors = TRUE;
GC_leaked[GC_n_leaked++] = leaked;
/* Make sure it's not reclaimed this cycle */
- GC_set_mark_bit(leaked);
+ GC_set_mark_bit(leaked);
}
}
/* Print all objects on the list after printing any smashed objects. */
-/* Clear both lists. */
+/* Clear both lists. Called without the allocation lock held. */
GC_INNER void GC_print_all_errors(void)
{
static GC_bool printing_errors = FALSE;