+2011-03-20 Ivan Maidanski <ivmai@mail.ru>
+
+ * alloc.c (GC_finish_collection): Remove redundant brackets;
+ adjust code indentation.
+ * blacklst.c (GC_add_to_black_list_normal): Simplify expression
+ (to improve code readability).
+ * blacklst.c (GC_is_black_listed): Join nested "if" (into a single
+ conditional expression); initialize "nblocks" just before the loop
+ beginning.
+ * misc.c (GC_init): Don't compute initial_heap_sz if GC is already
+ initialized.
+ * include/private/gc_priv.h (GC_initialize_offsets): Move the
+ function declaration to misc.c file.
+ * obj_map.c (GC_initialize_offsets): Remove offsets_initialized
+ static variable since the function is called only once.
+ * tests/middle.c: Include "gc.h" instead of <gc.h>; expand all
+ tabs to spaces; adjust code indentation; replace the K&R-style
+ function definition with the ANSI C one.
+ * tests/smash_test.c: Ditto.
+ * tests/middle.c (main): Use setter for GC_all_interior_pointers;
+ adjust printf format specifier (and cast the value passed to).
+
2011-03-15 Ivan Maidanski <ivmai@mail.ru>
* doc/README.macros (SMALL_CONFIG, LARGE_CONFIG): Refine the
# endif
COND_DUMP;
if (GC_find_leak) {
- /* Mark all objects on the free list. All objects should be */
- /* marked when we're done. */
- {
- word size; /* current object size */
- unsigned kind;
- ptr_t q;
-
- for (kind = 0; kind < GC_n_kinds; kind++) {
- for (size = 1; size <= MAXOBJGRANULES; size++) {
- q = GC_obj_kinds[kind].ok_freelist[size];
- if (q != 0) GC_set_fl_marks(q);
- }
- }
+ /* Mark all objects on the free list. All objects should be */
+ /* marked when we're done. */
+ word size; /* current object size */
+ unsigned kind;
+ ptr_t q;
+
+ for (kind = 0; kind < GC_n_kinds; kind++) {
+ for (size = 1; size <= MAXOBJGRANULES; size++) {
+ q = GC_obj_kinds[kind].ok_freelist[size];
+ if (q != 0) GC_set_fl_marks(q);
}
- GC_start_reclaim(TRUE);
- /* The above just checks; it doesn't really reclaim anything. */
+ }
+ GC_start_reclaim(TRUE);
+ /* The above just checks; it doesn't really reclaim anything. */
}
GC_finalize();
/* Note that composite objects on free list are cleared. */
/* Thus accidentally marking a free list is not a problem; only */
/* objects on the list itself will be marked, and that's fixed here. */
- {
- word size; /* current object size */
- ptr_t q; /* pointer to current object */
- unsigned kind;
-
- for (kind = 0; kind < GC_n_kinds; kind++) {
- for (size = 1; size <= MAXOBJGRANULES; size++) {
- q = GC_obj_kinds[kind].ok_freelist[size];
- if (q != 0) GC_clear_fl_marks(q);
- }
+ {
+ word size; /* current object size */
+ ptr_t q; /* pointer to current object */
+ unsigned kind;
+
+ for (kind = 0; kind < GC_n_kinds; kind++) {
+ for (size = 1; size <= MAXOBJGRANULES; size++) {
+ q = GC_obj_kinds[kind].ok_freelist[size];
+ if (q != 0) GC_clear_fl_marks(q);
}
}
-
+ }
if (GC_print_stats == VERBOSE)
GC_log_printf("Bytes recovered before sweep - f.l. count = %ld\n",
(long)GC_bytes_found);
/* Reconstruct free lists to contain everything not marked */
- GC_start_reclaim(FALSE);
- if (GC_print_stats) {
- GC_log_printf("Heap contains %lu pointer-containing "
- "+ %lu pointer-free reachable bytes\n",
- (unsigned long)GC_composite_in_use,
- (unsigned long)GC_atomic_in_use);
- }
- if (GC_is_full_gc) {
- GC_used_heap_size_after_full = USED_HEAP_SIZE;
- GC_need_full_gc = FALSE;
- } else {
- GC_need_full_gc =
- USED_HEAP_SIZE - GC_used_heap_size_after_full
- > min_bytes_allocd();
- }
+ GC_start_reclaim(FALSE);
+ if (GC_print_stats) {
+ GC_log_printf("Heap contains %lu pointer-containing "
+ "+ %lu pointer-free reachable bytes\n",
+ (unsigned long)GC_composite_in_use,
+ (unsigned long)GC_atomic_in_use);
+ }
+ if (GC_is_full_gc) {
+ GC_used_heap_size_after_full = USED_HEAP_SIZE;
+ GC_need_full_gc = FALSE;
+ } else {
+ GC_need_full_gc = USED_HEAP_SIZE - GC_used_heap_size_after_full
+ > min_bytes_allocd();
+ }
if (GC_print_stats == VERBOSE) {
# ifdef USE_MUNMAP
}
/* Reset or increment counters for next cycle */
- GC_n_attempts = 0;
- GC_is_full_gc = FALSE;
- GC_bytes_allocd_before_gc += GC_bytes_allocd;
- GC_non_gc_bytes_at_gc = GC_non_gc_bytes;
- GC_bytes_allocd = 0;
- GC_bytes_dropped = 0;
- GC_bytes_freed = 0;
- GC_finalizer_bytes_freed = 0;
+ GC_n_attempts = 0;
+ GC_is_full_gc = FALSE;
+ GC_bytes_allocd_before_gc += GC_bytes_allocd;
+ GC_non_gc_bytes_at_gc = GC_non_gc_bytes;
+ GC_bytes_allocd = 0;
+ GC_bytes_dropped = 0;
+ GC_bytes_freed = 0;
+ GC_finalizer_bytes_freed = 0;
# ifdef USE_MUNMAP
GC_unmap_old();
GC_INNER void GC_add_to_black_list_normal(word p)
#endif
{
- if (!(GC_modws_valid_offsets[p & (sizeof(word)-1)])) return;
- {
- word index = PHT_HASH((word)p);
+ if (GC_modws_valid_offsets[p & (sizeof(word)-1)]) {
+ word index = PHT_HASH((word)p);
- if (HDR(p) == 0 || get_pht_entry_from_index(GC_old_normal_bl, index)) {
-# ifdef PRINT_BLACK_LIST
- if (!get_pht_entry_from_index(GC_incomplete_normal_bl, index)) {
- GC_err_printf(
- "Black listing (normal) %p referenced from %p ",
- (ptr_t) p, source);
- GC_print_source_ptr(source);
- GC_err_puts("\n");
- }
-# endif
- set_pht_entry_from_index(GC_incomplete_normal_bl, index);
- } /* else this is probably just an interior pointer to an allocated */
- /* object, and isn't worth black listing. */
- }
+ if (HDR(p) == 0 || get_pht_entry_from_index(GC_old_normal_bl, index)) {
+# ifdef PRINT_BLACK_LIST
+ if (!get_pht_entry_from_index(GC_incomplete_normal_bl, index)) {
+ GC_err_printf("Black listing (normal) %p referenced from %p ",
+ (ptr_t)p, source);
+ GC_print_source_ptr(source);
+ GC_err_puts("\n");
+ }
+# endif
+ set_pht_entry_from_index(GC_incomplete_normal_bl, index);
+ } /* else this is probably just an interior pointer to an allocated */
+ /* object, and isn't worth black listing. */
+ }
}
/* And the same for false pointers from the stack. */
GC_INNER void GC_add_to_black_list_stack(word p)
#endif
{
- word index = PHT_HASH((word)p);
+ word index = PHT_HASH((word)p);
- if (HDR(p) == 0 || get_pht_entry_from_index(GC_old_stack_bl, index)) {
-# ifdef PRINT_BLACK_LIST
- if (!get_pht_entry_from_index(GC_incomplete_stack_bl, index)) {
- GC_err_printf(
- "Black listing (stack) %p referenced from %p ",
- (ptr_t)p, source);
- GC_print_source_ptr(source);
- GC_err_puts("\n");
- }
-# endif
- set_pht_entry_from_index(GC_incomplete_stack_bl, index);
- }
+ if (HDR(p) == 0 || get_pht_entry_from_index(GC_old_stack_bl, index)) {
+# ifdef PRINT_BLACK_LIST
+ if (!get_pht_entry_from_index(GC_incomplete_stack_bl, index)) {
+ GC_err_printf("Black listing (stack) %p referenced from %p ",
+ (ptr_t)p, source);
+ GC_print_source_ptr(source);
+ GC_err_puts("\n");
+ }
+# endif
+ set_pht_entry_from_index(GC_incomplete_stack_bl, index);
+ }
}
/*
{
word index = PHT_HASH((word)h);
word i;
- word nblocks = divHBLKSZ(len);
+ word nblocks;
- if (!GC_all_interior_pointers) {
- if (get_pht_entry_from_index(GC_old_normal_bl, index)
- || get_pht_entry_from_index(GC_incomplete_normal_bl, index)) {
- return(h+1);
- }
+ if (!GC_all_interior_pointers
+ && (get_pht_entry_from_index(GC_old_normal_bl, index)
+ || get_pht_entry_from_index(GC_incomplete_normal_bl, index))) {
+ return (h+1);
}
+ nblocks = divHBLKSZ(len);
for (i = 0;;) {
if (GC_old_stack_bl[divWORDSZ(index)] == 0
&& GC_incomplete_stack_bl[divWORDSZ(index)] == 0) {
/* An easy case */
- i += WORDSZ - modWORDSZ(index);
+ i += WORDSZ - modWORDSZ(index);
} else {
if (get_pht_entry_from_index(GC_old_stack_bl, index)
|| get_pht_entry_from_index(GC_incomplete_stack_bl, index)) {
/* Version of GC_register_displacement */
/* that assumes lock is already held. */
-GC_INNER void GC_initialize_offsets(void);
- /* Initialize GC_valid_offsets, */
- /* depending on current */
- /* GC_all_interior_pointers settings. */
-
/* hblk allocation: */
GC_INNER void GC_new_hblk(size_t size_in_granules, int kind);
/* Allocate a new heap block, and build */
STATIC int GC_log = 2;
#endif
+GC_INNER void GC_initialize_offsets(void); /* defined in obj_map.c */
+
GC_API void GC_CALL GC_init(void)
{
/* LOCK(); -- no longer does anything this early. */
# if !defined(THREADS) && defined(GC_ASSERTIONS)
word dummy;
# endif
-# ifdef GC_INITIAL_HEAP_SIZE
- word initial_heap_sz = divHBLKSZ(GC_INITIAL_HEAP_SIZE);
-# else
- word initial_heap_sz = (word)MINHINCR;
-# endif
+ word initial_heap_sz;
IF_CANCEL(int cancel_state;)
if (GC_is_initialized) return;
+# ifdef GC_INITIAL_HEAP_SIZE
+ initial_heap_sz = divHBLKSZ(GC_INITIAL_HEAP_SIZE);
+# else
+ initial_heap_sz = (word)MINHINCR;
+# endif
DISABLE_CANCEL(cancel_state);
/* Note that although we are nominally called with the */
/* allocation lock held, the allocation lock is now */
GC_INNER void GC_initialize_offsets(void)
{
- static GC_bool offsets_initialized = FALSE;
-
- if (!offsets_initialized) {
- int i;
- if (GC_all_interior_pointers) {
- for (i = 0; i < VALID_OFFSET_SZ; ++i)
- GC_valid_offsets[i] = TRUE;
- }
- offsets_initialized = TRUE;
- }
+ int i;
+ if (GC_all_interior_pointers) {
+ for (i = 0; i < VALID_OFFSET_SZ; ++i)
+ GC_valid_offsets[i] = TRUE;
+ }
}
* Test at the boundary between small and large objects.
* Inspired by a test case from Zoltan Varga.
*/
-#include <gc.h>
+#include "gc.h"
#include <stdio.h>
-int main ()
+int main (void)
{
- int i;
+ int i;
- GC_all_interior_pointers = 0;
- GC_INIT();
+ GC_set_all_interior_pointers(0);
+ GC_INIT();
- for (i = 0; i < 20000; ++i) {
- GC_malloc_atomic (4096);
- GC_malloc (4096);
- }
- for (i = 0; i < 20000; ++i) {
- GC_malloc_atomic (2048);
- GC_malloc (2048);
- }
- printf("Final heap size is %ld\n", GC_get_heap_size());
- return 0;
+ for (i = 0; i < 20000; ++i) {
+ GC_malloc_atomic (4096);
+ GC_malloc (4096);
+ }
+ for (i = 0; i < 20000; ++i) {
+ GC_malloc_atomic (2048);
+ GC_malloc (2048);
+ }
+ printf("Final heap size is %lu\n", (unsigned long)GC_get_heap_size());
+ return 0;
}
-
* Test that overwrite error detection works reasonably.
*/
#define GC_DEBUG
-#include <gc.h>
+#include "gc.h"
+
#include <stdio.h>
#define COUNT 7000
char * A[COUNT];
-int main ()
+int main(void)
{
- int i;
- char *p;
+ int i;
+ char *p;
- GC_INIT();
+ GC_INIT();
- for (i = 0; i < COUNT; ++i) {
- A[i] = p = GC_MALLOC(SIZE);
+ for (i = 0; i < COUNT; ++i) {
+ A[i] = p = GC_MALLOC(SIZE);
- if (i%3000 == 0) GC_gcollect();
- if (i%5678 == 0) p[SIZE + i/2000] = 42;
- }
- return 0;
+ if (i%3000 == 0) GC_gcollect();
+ if (i%5678 == 0) p[SIZE + i/2000] = 42;
+ }
+ return 0;
}
-