# define IS_MAPPED(hhdr) 1
# endif /* USE_MUNMAP */
+#if (!defined(NO_DEBUGGING) && !defined(USE_MUNMAP)) || defined(GC_ASSERTIONS)
+ /* Should return the same value as GC_large_free_bytes. */
+ GC_INNER word GC_compute_large_free_bytes(void)
+ {
+# ifdef USE_MUNMAP
+ return GC_large_free_bytes; /* FIXME: unimplemented */
+# else
+ struct hblk * h;
+ hdr * hhdr;
+ word total_free = 0;
+ unsigned i;
+
+ for (i = 0; i <= N_HBLK_FLS; ++i) {
+ for (h = GC_hblkfreelist[i]; h != 0; h = hhdr->hb_next) {
+ hhdr = HDR(h);
+ total_free += hhdr->hb_sz;
+ }
+ }
+ return total_free;
+# endif
+ }
+#endif /* !NO_DEBUGGING || GC_ASSERTIONS */
+
# if !defined(NO_DEBUGGING)
void GC_print_hblkfreelist(void)
{
struct hblk * h;
- word total_free = 0;
hdr * hhdr;
- word sz;
unsigned i;
for (i = 0; i <= N_HBLK_FLS; ++i) {
# endif
while (h != 0) {
hhdr = HDR(h);
- sz = hhdr -> hb_sz;
- total_free += sz;
GC_printf("\t%p size %lu %s black listed\n",
- (void *)h, (unsigned long)sz,
+ (void *)h, (unsigned long) hhdr -> hb_sz,
GC_is_black_listed(h, HBLKSIZE) != 0 ? "start" :
GC_is_black_listed(h, hhdr -> hb_sz) != 0 ? "partially" :
"not");
h = hhdr -> hb_next;
}
}
+ GC_printf("GC_large_free_bytes: %lu\n",
+ (unsigned long)GC_large_free_bytes);
+
# ifndef USE_MUNMAP
- if (total_free != GC_large_free_bytes) {
- GC_printf("GC_large_free_bytes = %lu (INCONSISTENT!!)\n",
- (unsigned long) GC_large_free_bytes);
+ {
+ word total;
+ if ((total = GC_compute_large_free_bytes()) != GC_large_free_bytes)
+ GC_err_printf("GC_large_free_bytes INCONSISTENT!! Should be: %lu\n",
+ (unsigned long)total);
}
# endif
- GC_printf("Total of %lu bytes on free list\n", (unsigned long)total_free);
}
/* Return the free list index on which the block described by the header */
#endif
#define VERBOSE 2
-#ifndef NO_DEBUGGING
- GC_EXTERN GC_bool GC_dump_regularly;
- /* Generate regular debugging dumps. */
-# define COND_DUMP if (EXPECT(GC_dump_regularly, FALSE)) GC_dump()
-#else
-# define COND_DUMP /* empty */
-#endif
-
#ifdef KEEP_BACK_PTRS
GC_EXTERN long GC_backtraces;
GC_INNER void GC_generate_random_backtrace_no_gc(void);
#endif /* NEED_PROC_MAPS */
#ifdef GC_ASSERTIONS
-# define GC_ASSERT(expr) \
+# define GC_ASSERT(expr) \
if (!(expr)) { \
GC_err_printf("Assertion failure: %s:%d\n", \
__FILE__, __LINE__); \
ABORT("assertion failure"); \
}
+ GC_INNER word GC_compute_large_free_bytes(void);
+ GC_INNER word GC_compute_root_size(void);
#else
-# define GC_ASSERT(expr)
+# define GC_ASSERT(expr)
#endif
/* Check a compile time assertion at compile time. The error */
# define GC_STATIC_ASSERT(expr) (void)sizeof(char[(expr)? 1 : -1])
#endif
+#define COND_DUMP_CHECKS { \
+ GC_ASSERT(GC_compute_large_free_bytes() == GC_large_free_bytes); \
+ GC_ASSERT(GC_compute_root_size() == GC_root_size); }
+
+#ifndef NO_DEBUGGING
+ GC_EXTERN GC_bool GC_dump_regularly;
+ /* Generate regular debugging dumps. */
+# define COND_DUMP { if (EXPECT(GC_dump_regularly, FALSE)) GC_dump(); \
+ else COND_DUMP_CHECKS; }
+#else
+# define COND_DUMP COND_DUMP_CHECKS
+#endif
+
#if defined(PARALLEL_MARK)
/* We need additional synchronization facilities from the thread */
/* support. We believe these are less performance critical */
static int n_root_sets = 0;
/* GC_static_roots[0..n_root_sets) contains the valid root sets. */
+#if !defined(NO_DEBUGGING) || defined(GC_ASSERTIONS)
+ /* Should return the same value as GC_root_size. */
+ GC_INNER word GC_compute_root_size(void)
+ {
+ int i;
+ word size = 0;
+
+ for (i = 0; i < n_root_sets; i++) {
+ size += GC_static_roots[i].r_end - GC_static_roots[i].r_start;
+ }
+ return size;
+ }
+#endif /* !NO_DEBUGGING || GC_ASSERTIONS */
+
#if !defined(NO_DEBUGGING)
/* For debugging: */
void GC_print_static_roots(void)
{
int i;
- size_t total = 0;
+ word size;
for (i = 0; i < n_root_sets; i++) {
GC_printf("From %p to %p%s\n",
- GC_static_roots[i].r_start,
- GC_static_roots[i].r_end,
+ GC_static_roots[i].r_start, GC_static_roots[i].r_end,
GC_static_roots[i].r_tmp ? " (temporary)" : "");
- total += GC_static_roots[i].r_end - GC_static_roots[i].r_start;
- }
- GC_printf("Total size: %lu\n", (unsigned long) total);
- if (GC_root_size != total) {
- GC_err_printf("GC_root_size incorrect: %lu!!\n",
- (unsigned long) GC_root_size);
}
+ GC_printf("GC_root_size: %lu\n", (unsigned long)GC_root_size);
+
+ if ((size = GC_compute_root_size()) != GC_root_size)
+ GC_err_printf("GC_root_size incorrect!! Should be: %lu\n",
+ (unsigned long)size);
}
#endif /* !NO_DEBUGGING */