X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=boehm-gc%2Fgcj_mlc.c;h=2aaef795d923ef33a64825661faf4dff5ffdf3c0;hb=eb57d4df8f05eb3fb2c683013e4d36f94a9596fc;hp=519c5cb916cc98f8dd40bcef5fe6fff7a508a011;hpb=d00b9cd2494d3f9e2f3b3966781884d85083d77f;p=pf3gnuchains%2Fgcc-fork.git diff --git a/boehm-gc/gcj_mlc.c b/boehm-gc/gcj_mlc.c index 519c5cb916c..2aaef795d92 100644 --- a/boehm-gc/gcj_mlc.c +++ b/boehm-gc/gcj_mlc.c @@ -14,16 +14,14 @@ */ /* Boehm, July 31, 1995 5:02 pm PDT */ -#ifdef GC_GCJ_SUPPORT - /* - * This is an allocator interface tuned for gcj (the GNU/Cygnus static + * This is an allocator interface tuned for gcj (the GNU static * java compiler). * * Each allocated object has a pointer in its first word to a vtable, * which for our purposes is simply a structure describing the type of * the object. - * This descriptor structur contains a GC marking descriptor at offset + * This descriptor structure contains a GC marking descriptor at offset * MARK_DESCR_OFFSET. * * It is hoped that this interface may also be useful for other systems, @@ -36,10 +34,11 @@ * 3) FASTLOCK is not a significant win. */ -#include "gc_priv.h" -#include "gc_mark.h" -#include "include/gc_gcj.h" -#include "dbg_mlc.h" +#include "private/gc_pmark.h" +#include "gc_gcj.h" +#include "private/dbg_mlc.h" + +#ifdef GC_GCJ_SUPPORT GC_bool GC_gcj_malloc_initialized = FALSE; @@ -51,14 +50,11 @@ int GC_gcj_debug_kind; /* The kind of objects that is always marked */ ptr_t * GC_gcjobjfreelist; ptr_t * GC_gcjdebugobjfreelist; -void * GC_default_oom_action(void) { return 0; } - -void * (*GC_oom_action)(void) = GC_default_oom_action; - /* Caller does not hold allocation lock. */ -void GC_init_gcj_malloc(int mp_index, void * /* really mark_proc */mp) +void GC_init_gcj_malloc(int mp_index, void * /* really GC_mark_proc */mp) { register int i; + GC_bool ignore_gcj_info; DCL_LOCK_STATE; GC_init(); /* In case it's not already done. */ @@ -70,33 +66,42 @@ void GC_init_gcj_malloc(int mp_index, void * /* really mark_proc */mp) return; } GC_gcj_malloc_initialized = TRUE; - GC_mark_procs[mp_index] = (mark_proc)mp; + ignore_gcj_info = (0 != GETENV("GC_IGNORE_GCJ_INFO")); +# ifdef CONDPRINT + if (GC_print_stats && ignore_gcj_info) { + GC_printf0("Gcj-style type information is disabled!\n"); + } +# endif + GC_ASSERT(GC_mark_procs[mp_index] == (GC_mark_proc)0); /* unused */ + GC_mark_procs[mp_index] = (GC_mark_proc)mp; if (mp_index >= GC_n_mark_procs) ABORT("GC_init_gcj_malloc: bad index"); /* Set up object kind gcj-style indirect descriptor. */ - GC_gcjobjfreelist = (ptr_t *) - GC_generic_malloc_inner((MAXOBJSZ+1)*sizeof(ptr_t), PTRFREE); - if (GC_gcjobjfreelist == 0) ABORT("Couldn't allocate GC_gcjobjfreelist"); - BZERO(GC_gcjobjfreelist, (MAXOBJSZ+1)*sizeof(ptr_t)); - GC_gcj_kind = GC_n_kinds++; - GC_obj_kinds[GC_gcj_kind].ok_freelist = GC_gcjobjfreelist; - GC_obj_kinds[GC_gcj_kind].ok_reclaim_list = 0; - GC_obj_kinds[GC_gcj_kind].ok_descriptor = - (((word)(-MARK_DESCR_OFFSET - INDIR_PER_OBJ_BIAS)) | DS_PER_OBJECT); - GC_obj_kinds[GC_gcj_kind].ok_relocate_descr = FALSE; - GC_obj_kinds[GC_gcj_kind].ok_init = TRUE; + GC_gcjobjfreelist = (ptr_t *)GC_new_free_list_inner(); + if (ignore_gcj_info) { + /* Use a simple length-based descriptor, thus forcing a fully */ + /* conservative scan. */ + GC_gcj_kind = GC_new_kind_inner((void **)GC_gcjobjfreelist, + (0 | GC_DS_LENGTH), + TRUE, TRUE); + } else { + GC_gcj_kind = GC_new_kind_inner( + (void **)GC_gcjobjfreelist, + (((word)(-MARK_DESCR_OFFSET - GC_INDIR_PER_OBJ_BIAS)) + | GC_DS_PER_OBJECT), + FALSE, TRUE); + } /* Set up object kind for objects that require mark proc call. */ - GC_gcjdebugobjfreelist = (ptr_t *) - GC_generic_malloc_inner((MAXOBJSZ+1)*sizeof(ptr_t), PTRFREE); - if (GC_gcjdebugobjfreelist == 0) - ABORT("Couldn't allocate GC_gcjdebugobjfreelist"); - BZERO(GC_gcjdebugobjfreelist, (MAXOBJSZ+1)*sizeof(ptr_t)); - GC_gcj_debug_kind = GC_n_kinds++; - GC_obj_kinds[GC_gcj_debug_kind].ok_freelist = GC_gcjdebugobjfreelist; - GC_obj_kinds[GC_gcj_debug_kind].ok_reclaim_list = 0; - GC_obj_kinds[GC_gcj_debug_kind].ok_descriptor = - MAKE_PROC(mp_index, 1 /* allocated with debug info */); - GC_obj_kinds[GC_gcj_debug_kind].ok_relocate_descr = FALSE; - GC_obj_kinds[GC_gcj_debug_kind].ok_init = TRUE; + if (ignore_gcj_info) { + GC_gcj_debug_kind = GC_gcj_kind; + GC_gcjdebugobjfreelist = GC_gcjobjfreelist; + } else { + GC_gcjdebugobjfreelist = (ptr_t *)GC_new_free_list_inner(); + GC_gcj_debug_kind = GC_new_kind_inner( + (void **)GC_gcjdebugobjfreelist, + GC_MAKE_PROC(mp_index, + 1 /* allocated with debug info */), + FALSE, TRUE); + } UNLOCK(); ENABLE_SIGNALS(); } @@ -109,6 +114,25 @@ ptr_t GC_clear_stack(); #define GENERAL_MALLOC_IOP(lb,k) \ (GC_PTR)GC_clear_stack(GC_generic_malloc_inner_ignore_off_page(lb, k)) +/* We need a mechanism to release the lock and invoke finalizers. */ +/* We don't really have an opportunity to do this on a rarely executed */ +/* path on which the lock is not held. Thus we check at a */ +/* rarely executed point at which it is safe to release the lock. */ +/* We do this even where we could just call GC_INVOKE_FINALIZERS, */ +/* since it's probably cheaper and certainly more uniform. */ +/* FIXME - Consider doing the same elsewhere? */ +static void maybe_finalize() +{ + static int last_finalized_no = 0; + + if (GC_gc_no == last_finalized_no) return; + if (!GC_is_initialized) return; + UNLOCK(); + GC_INVOKE_FINALIZERS(); + last_finalized_no = GC_gc_no; + LOCK(); +} + /* Allocate an object, clear it, and store the pointer to the */ /* type structure (vtable in gcj). */ /* This adds a byte at the end of the object if GC_malloc would.*/ @@ -119,7 +143,7 @@ register ptr_t * opp; register word lw; DCL_LOCK_STATE; - if( SMALL_OBJ(lb) ) { + if( EXPECT(SMALL_OBJ(lb), 1) ) { # ifdef MERGE_SIZES lw = GC_size_map[lb]; # else @@ -127,11 +151,13 @@ DCL_LOCK_STATE; # endif opp = &(GC_gcjobjfreelist[lw]); LOCK(); - if( (op = *opp) == 0 ) { + op = *opp; + if(EXPECT(op == 0, 0)) { + maybe_finalize(); op = (ptr_t)GENERAL_MALLOC((word)lb, GC_gcj_kind); if (0 == op) { UNLOCK(); - return(GC_oom_action()); + return(GC_oom_fn(lb)); } # ifdef MERGE_SIZES lw = GC_size_map[lb]; /* May have been uninitialized. */ @@ -141,13 +167,15 @@ DCL_LOCK_STATE; GC_words_allocd += lw; } *(void **)op = ptr_to_struct_containing_descr; + GC_ASSERT(((void **)op)[1] == 0); UNLOCK(); } else { LOCK(); + maybe_finalize(); op = (ptr_t)GENERAL_MALLOC((word)lb, GC_gcj_kind); if (0 == op) { UNLOCK(); - return(GC_oom_action()); + return(GC_oom_fn(lb)); } *(void **)op = ptr_to_struct_containing_descr; UNLOCK(); @@ -162,10 +190,10 @@ GC_PTR GC_debug_gcj_malloc(size_t lb, void * ptr_to_struct_containing_descr, { GC_PTR result; - /* We clone the code from GC_debug_gcj_malloc, so that we */ - /* dont end up with extra frames on the stack, which could */ + /* We're careful to avoid extra calls, which could */ /* confuse the backtrace. */ LOCK(); + maybe_finalize(); result = GC_generic_malloc_inner(lb + DEBUG_BYTES, GC_gcj_debug_kind); if (result == 0) { UNLOCK(); @@ -174,7 +202,7 @@ GC_PTR GC_debug_gcj_malloc(size_t lb, void * ptr_to_struct_containing_descr, (unsigned long) ptr_to_struct_containing_descr); GC_err_puts(s); GC_err_printf1(":%ld)\n", (unsigned long)i); - return(GC_oom_action()); + return(GC_oom_fn(lb)); } *((void **)((ptr_t)result + sizeof(oh))) = ptr_to_struct_containing_descr; UNLOCK(); @@ -196,12 +224,14 @@ DCL_LOCK_STATE; opp = &(GC_gcjobjfreelist[lw]); LOCK(); - if( (op = *opp) == 0 ) { + op = *opp; + if( EXPECT(op == 0, 0) ) { + maybe_finalize(); op = (ptr_t)GC_clear_stack( GC_generic_malloc_words_small_inner(lw, GC_gcj_kind)); if (0 == op) { UNLOCK(); - return(GC_oom_action()); + return GC_oom_fn(WORDS_TO_BYTES(lw)); } } else { *opp = obj_link(op); @@ -224,6 +254,7 @@ void * GC_debug_gcj_fast_malloc(size_t lw, /* dont end up with extra frames on the stack, which could */ /* confuse the backtrace. */ LOCK(); + maybe_finalize(); result = GC_generic_malloc_inner(lb + DEBUG_BYTES, GC_gcj_debug_kind); if (result == 0) { UNLOCK(); @@ -232,7 +263,7 @@ void * GC_debug_gcj_fast_malloc(size_t lw, (unsigned long) ptr_to_struct_containing_descr); GC_err_puts(s); GC_err_printf1(":%ld)\n", (unsigned long)i); - return(GC_oom_action()); + return GC_oom_fn(WORDS_TO_BYTES(lw)); } *((void **)((ptr_t)result + sizeof(oh))) = ptr_to_struct_containing_descr; UNLOCK(); @@ -260,6 +291,7 @@ DCL_LOCK_STATE; opp = &(GC_gcjobjfreelist[lw]); LOCK(); if( (op = *opp) == 0 ) { + maybe_finalize(); op = (ptr_t)GENERAL_MALLOC_IOP(lb, GC_gcj_kind); # ifdef MERGE_SIZES lw = GC_size_map[lb]; /* May have been uninitialized. */ @@ -271,6 +303,8 @@ DCL_LOCK_STATE; *(void **)op = ptr_to_struct_containing_descr; UNLOCK(); } else { + LOCK(); + maybe_finalize(); op = (ptr_t)GENERAL_MALLOC_IOP(lb, GC_gcj_kind); if (0 != op) { *(void **)op = ptr_to_struct_containing_descr;