summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--boehm-gc/ChangeLog41
-rw-r--r--boehm-gc/finalize.c16
-rw-r--r--boehm-gc/gc_priv.h12
-rw-r--r--boehm-gc/gcconfig.h17
-rw-r--r--boehm-gc/gcj_mlc.c1
-rw-r--r--boehm-gc/linux_threads.c2
-rw-r--r--boehm-gc/malloc.c2
-rw-r--r--boehm-gc/misc.c37
-rw-r--r--boehm-gc/os_dep.c25
-rw-r--r--boehm-gc/test.c8
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;
}