diff options
-rw-r--r-- | boehm-gc/ChangeLog | 41 | ||||
-rw-r--r-- | boehm-gc/finalize.c | 16 | ||||
-rw-r--r-- | boehm-gc/gc_priv.h | 12 | ||||
-rw-r--r-- | boehm-gc/gcconfig.h | 17 | ||||
-rw-r--r-- | boehm-gc/gcj_mlc.c | 1 | ||||
-rw-r--r-- | boehm-gc/linux_threads.c | 2 | ||||
-rw-r--r-- | boehm-gc/malloc.c | 2 | ||||
-rw-r--r-- | boehm-gc/misc.c | 37 | ||||
-rw-r--r-- | boehm-gc/os_dep.c | 25 | ||||
-rw-r--r-- | boehm-gc/test.c | 8 |
10 files changed, 133 insertions, 28 deletions
diff --git a/boehm-gc/ChangeLog b/boehm-gc/ChangeLog index e5636d9a0e0..31b8ebe038e 100644 --- a/boehm-gc/ChangeLog +++ b/boehm-gc/ChangeLog @@ -1,3 +1,44 @@ +2001-04-04 Hans Boehm <hans_boehm@hp.com> + + * finalize.c: + - Accomodate finalization requests for static objects. + (Will be required by hash synchronization. May be needed + in some configurations now.) + + * gc_priv.h: + - Define MIN_WORDS. All allocation requests are rounded + up to at least this size. Removes a subtle assumption that + Java objects have a 2 word header. + + * gcconfig.h: + - Adjust Linux/IA64 configuration for non-ancient kernels. + (Necessary fix for IA64.) + + * linux_threads.c: + - Fix syntax error in currently unused code. Will be needed + for Linux/PA-RISC. + + * malloc.c: + - Handle MIN_WORDS. + + * misc.c: + - Handle MIN_WORDS. + - Change stack cleaning code to typically clear about one tenth + the memory it used to in the threads configuration. Occasionally + still clear more. (This is really a fix for a long-standing + and fairly significant performance bug with threads.) + + * os_dep.c: + - Fix the code for finding the beginning of the data segment under + Linux. I believe this is necessary for some IA64 Linux + distributions. It will also helo other platforms, though those + may additionally require a gcconfig.h adjustment. (This basically + works around the absence of a data_start or __data_start + definition in glibc.) + + * test.c: + - Handle rounding due to MIN_WORDS. + 2001-03-22 Tom Tromey <tromey@redhat.com> * Makefile.am (gctest_LDFLAGS): Use -shared-libgcc. diff --git a/boehm-gc/finalize.c b/boehm-gc/finalize.c index e70a9ff1e99..7ff6798cfa5 100644 --- a/boehm-gc/finalize.c +++ b/boehm-gc/finalize.c @@ -324,6 +324,7 @@ finalization_mark_proc * mp; struct finalizable_object * curr_fo, * prev_fo; int index; struct finalizable_object *new_fo; + hdr *hhdr; DCL_LOCK_STATE; # ifdef THREADS @@ -402,6 +403,19 @@ finalization_mark_proc * mp; # endif return; } + GET_HDR(base, hhdr); + if (0 == hhdr) { + /* We won't collect it, hence finalizer wouldn't be run. */ + /* This is changed for gcj, but it will be in version 6.0 of the */ + /* standard collector distribution. It costs virtually nothing */ + /* here, but it's expensive to check in the hash synchronization */ + /* code, where it matters. -HB */ +# ifdef THREADS + UNLOCK(); + ENABLE_SIGNALS(); +# endif + return; + } # ifdef THREADS new_fo = (struct finalizable_object *) GC_generic_malloc_inner(sizeof(struct finalizable_object),NORMAL); @@ -413,7 +427,7 @@ finalization_mark_proc * mp; new_fo -> fo_hidden_base = (word)HIDE_POINTER(base); new_fo -> fo_fn = fn; new_fo -> fo_client_data = (ptr_t)cd; - new_fo -> fo_object_size = GC_size(base); + new_fo -> fo_object_size = hhdr -> hb_sz; new_fo -> fo_mark_proc = mp; fo_set_next(new_fo, fo_head[index]); GC_fo_entries++; diff --git a/boehm-gc/gc_priv.h b/boehm-gc/gc_priv.h index c0fa5d6e93c..314eced8525 100644 --- a/boehm-gc/gc_priv.h +++ b/boehm-gc/gc_priv.h @@ -890,6 +890,18 @@ extern GC_warn_proc GC_current_warn_proc; # define SMALL_OBJ(bytes) ((bytes) <= WORDS_TO_BYTES(MAXOBJSZ)) # define ADD_SLOP(bytes) (bytes) # endif +# ifndef MIN_WORDS + /* MIN_WORDS is the size of the smallest allocated object. */ + /* 1 and 2 are the only valid values. */ + /* 2 must be used if: */ + /* - GC_gcj_malloc can be used for objects of requested */ + /* size smaller than 2 words */ +# if defined(GC_GCJ_SUPPORT) +# define MIN_WORDS 2 /* Smallest allocated object. */ +# else +# define MIN_WORDS 1 +# endif +# endif /* diff --git a/boehm-gc/gcconfig.h b/boehm-gc/gcconfig.h index 4cab9c72cd6..84a4b3ccc46 100644 --- a/boehm-gc/gcconfig.h +++ b/boehm-gc/gcconfig.h @@ -1116,11 +1116,20 @@ # define CPP_WORDSZ 64 /* This should really be done through /proc, but that */ /* requires we run on an IA64 kernel. */ -# define STACKBOTTOM ((ptr_t) 0xa000000000000000l) + /* The following works on NUE and older kernels: */ +/* # define STACKBOTTOM ((ptr_t) 0xa000000000000000l) */ + /* This does not work on NUE: */ +# define LINUX_STACKBOTTOM /* We also need the base address of the register stack */ - /* backing store. There is probably a better way to */ - /* get that, too ... */ -# define BACKING_STORE_BASE ((ptr_t) 0x9fffffff80000000l) + /* backing store. There should be a better way to get */ + /* this: */ +# define APPROX_BS_BASE ((word)GC_stackbottom-0x80000000) + /* We round to the next multiple of 1 MB, to compensate */ + /* for the fact that the stack base is displaced by */ + /* the environment, etc. */ +# define BACKING_STORE_BASE \ + (ptr_t)((APPROX_BS_BASE + 0xfffff) & ~0xfffff) + # if 1 # define SEARCH_FOR_DATA_START # define DATASTART GC_data_start diff --git a/boehm-gc/gcj_mlc.c b/boehm-gc/gcj_mlc.c index d7b912c5a9b..519c5cb916c 100644 --- a/boehm-gc/gcj_mlc.c +++ b/boehm-gc/gcj_mlc.c @@ -267,7 +267,6 @@ DCL_LOCK_STATE; } else { *opp = obj_link(op); GC_words_allocd += lw; - FASTUNLOCK(); } *(void **)op = ptr_to_struct_containing_descr; UNLOCK(); diff --git a/boehm-gc/linux_threads.c b/boehm-gc/linux_threads.c index cac52374d72..2c856f567a0 100644 --- a/boehm-gc/linux_threads.c +++ b/boehm-gc/linux_threads.c @@ -611,7 +611,7 @@ void * GC_start_routine(void * arg) /* Needs to be plausible, since an asynchronous stack mark */ /* should not crash. */ # else - me -> stack_end = (ptr_t)(((word)(&dummy) & ~(GC_page_size - 1)); + me -> stack_end = (ptr_t)((word)(&dummy) & ~(GC_page_size - 1)); me -> stack_ptr = me -> stack_end + 0x10; # endif /* This is dubious, since we may be more than a page into the stack, */ diff --git a/boehm-gc/malloc.c b/boehm-gc/malloc.c index a5a93ad8119..c9222245362 100644 --- a/boehm-gc/malloc.c +++ b/boehm-gc/malloc.c @@ -52,7 +52,7 @@ register ptr_t *opp; lw = GC_size_map[lb]; # else lw = ALIGNED_WORDS(lb); - if (lw == 0) lw = 1; + if (lw == 0) lw = MIN_WORDS; # endif opp = &(kind -> ok_freelist[lw]); if( (op = *opp) == 0 ) { diff --git a/boehm-gc/misc.c b/boehm-gc/misc.c index dd42961c4b3..1e1ada57457 100644 --- a/boehm-gc/misc.c +++ b/boehm-gc/misc.c @@ -107,13 +107,17 @@ extern signed_word GC_mem_found; { register unsigned i; - /* Map size 0 to 1. This avoids problems at lower levels. */ - GC_size_map[0] = 1; + /* Map size 0 to something bigger. */ + /* This avoids problems at lower levels. */ /* One word objects don't have to be 2 word aligned. */ - for (i = 1; i < sizeof(word); i++) { - GC_size_map[i] = 1; + for (i = 0; i < sizeof(word); i++) { + GC_size_map[i] = MIN_WORDS; } - GC_size_map[sizeof(word)] = ROUNDED_UP_WORDS(sizeof(word)); +# if MIN_WORDS > 1 + GC_size_map[sizeof(word)] = MIN_WORDS; +# else + GC_size_map[sizeof(word)] = ROUNDED_UP_WORDS(sizeof(word)); +# endif for (i = sizeof(word) + 1; i <= 8 * sizeof(word); i++) { # ifdef ALIGN_DOUBLE GC_size_map[i] = (ROUNDED_UP_WORDS(i) + 1) & (~1); @@ -202,10 +206,10 @@ extern signed_word GC_mem_found; */ word GC_stack_last_cleared = 0; /* GC_no when we last did this */ # ifdef THREADS -# define CLEAR_SIZE 2048 -# else -# define CLEAR_SIZE 213 +# define BIG_CLEAR_SIZE 2048 /* Clear this much now and then. */ +# define SMALL_CLEAR_SIZE 256 /* Clear this much every time. */ # endif +# define CLEAR_SIZE 213 /* Granularity for GC_clear_stack_inner */ # define DEGRADE_RATE 50 word GC_min_sp; /* Coolest stack pointer value from which we've */ @@ -262,10 +266,12 @@ ptr_t arg; { register word sp = (word)GC_approx_sp(); /* Hotter than actual sp */ # ifdef THREADS - word dummy[CLEAR_SIZE]; -# else - register word limit; + word dummy[SMALL_CLEAR_SIZE]; + unsigned random_no = 0; /* Should be more random than it is ... */ + /* Used to occasionally clear a bigger */ + /* chunk. */ # endif + register word limit; # define SLOP 400 /* Extra bytes we clear every time. This clears our own */ @@ -283,7 +289,14 @@ ptr_t arg; /* thus more junk remains accessible, thus the heap gets */ /* larger ... */ # ifdef THREADS - BZERO(dummy, CLEAR_SIZE*sizeof(word)); + if (++random_no % 13 == 0) { + limit = sp; + MAKE_HOTTER(limit, BIG_CLEAR_SIZE*sizeof(word)); + return GC_lear_stack_inner(arg, limit); + } else { + BZERO(dummy, SMALL_CLEAR_SIZE*sizeof(word)); + return arg; + } # else if (GC_gc_no > GC_stack_last_cleared) { /* Start things over, so we clear the entire stack again */ diff --git a/boehm-gc/os_dep.c b/boehm-gc/os_dep.c index 87f84e7bccd..a192d35a21a 100644 --- a/boehm-gc/os_dep.c +++ b/boehm-gc/os_dep.c @@ -144,20 +144,37 @@ #endif #if defined(SEARCH_FOR_DATA_START) - /* The following doesn't work if the GC is in a dynamic library. */ /* The I386 case can be handled without a search. The Alpha case */ /* used to be handled differently as well, but the rules changed */ /* for recent Linux versions. This seems to be the easiest way to */ /* cover all versions. */ - ptr_t GC_data_start; - extern char * GC_copyright[]; /* Any data symbol would do. */ +# ifdef LINUX +# pragma weak __data_start + extern int __data_start; +# pragma weak data_start + extern int data_start; +# endif /* LINUX */ + extern int _end; + + ptr_t GC_data_start; void GC_init_linux_data_start() { extern ptr_t GC_find_limit(); - GC_data_start = GC_find_limit((ptr_t)GC_copyright, FALSE); +# ifdef LINUX + /* Try the easy approaches first: */ + if (&__data_start != 0) { + GC_data_start = (ptr_t)(&__data_start); + return; + } + if (&data_start != 0) { + GC_data_start = (ptr_t)(&data_start); + return; + } +# endif /* LINUX */ + GC_data_start = GC_find_limit((ptr_t)(&_end), FALSE); } #endif diff --git a/boehm-gc/test.c b/boehm-gc/test.c index 96a54150a86..9254fa8370d 100644 --- a/boehm-gc/test.c +++ b/boehm-gc/test.c @@ -958,17 +958,17 @@ void run_one_test() "This test program is not designed for leak detection mode\n"); (void)GC_printf0("Expect lots of problems.\n"); # endif - if (GC_size(GC_malloc(7)) != 8 + if (GC_size(GC_malloc(7)) != 8 && + GC_size(GC_malloc(7)) != MIN_WORDS * sizeof(GC_word) || GC_size(GC_malloc(15)) != 16) { (void)GC_printf0("GC_size produced unexpected results\n"); FAIL; } - if (GC_size(GC_malloc(0)) != 4 && GC_size(GC_malloc(0)) != 8) { + if (GC_size(GC_malloc(0)) != MIN_WORDS * sizeof(GC_word)) { (void)GC_printf0("GC_malloc(0) failed\n"); FAIL; } - if (GC_size(GC_malloc_uncollectable(0)) != 4 - && GC_size(GC_malloc_uncollectable(0)) != 8) { + if (GC_size(GC_malloc_uncollectable(0)) != MIN_WORDS * sizeof(GC_word)) { (void)GC_printf0("GC_malloc_uncollectable(0) failed\n"); FAIL; } |