finalize.c: - Accomodate finalization requests for static objects.

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.

From-SVN: r41102
This commit is contained in:
Hans Boehm 2001-04-05 00:14:18 +00:00 committed by Tom Tromey
parent 48f9396dd6
commit 41029b884a
10 changed files with 133 additions and 28 deletions

View file

@ -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.

View file

@ -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++;

View file

@ -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
/*

View file

@ -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

View file

@ -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();

View file

@ -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, */

View file

@ -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 ) {

View file

@ -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 */

View file

@ -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

View file

@ -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;
}