diff options
author | bryce <bryce@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-09-30 09:56:58 +0000 |
---|---|---|
committer | bryce <bryce@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-09-30 09:56:58 +0000 |
commit | 2629d8057817e7327f63d151692a5562895df341 (patch) | |
tree | 546907bd61de305c953b5ae99d05489fc543bc16 /libjava/boehm.cc | |
parent | 1a5c0c2c669c244f17e5b3b1d78868fd5f61373b (diff) | |
download | gcc-2629d8057817e7327f63d151692a5562895df341.tar.gz |
2000-09-30 Hans Boehm <boehm@acm.org>
Bryce McKinlay <bryce@albatross.co.nz>
Implement bitmap descriptor based marking for Boehm GC.
* configure.in: Define JC1GCSPEC. Set it if boehm-gc is used.
* configure: Rebuilt.
* libgcj.spec.in: Pass JC1GCSPEC to jc1.
* include/jvm.h (struct _Jv_VTable): New field `gc_descr'. New inline
method get_finalizer().
(struct _Jv_ArrayVTable): Ditto. Declare method array with
NUM_OBJECT_METHODS elements instead of NUM_OBJECT_METHODS + 1.
(_Jv_AllocObj): Add new jclass parameter.
(_Jv_AllocArray): Ditto.
(_Jv_BuildGCDescr): New prototype.
* prims.cc (_Jv_AllocObject): Rename parameter `c' to `klass'. Pass
`klass' to _Jv_AllocObj. Don't set the new object's vtable. Use
get_finalizer() instead of direct finalizer vtable offset.
(_Jv_NewObjectArray): Rename parameter `clas' to `klass'. Pass
`klass' to _Jv_AllocArray. Don't set the new array's vtable.
(_Jv_NewPrimArray): Call _Jv_FindArrayClass before _Jv_AllocObj.
Pass `klass' to _Jv_AllocObj. Don't set the new array's vtable.
* resolve.cc (METHOD_NOT_THERE, METHOD_INACCESSIBLE): New #defines.
(_Jv_ResolvePoolEntry): Use METHOD_NOT_THERE and METHOD_INACCESSIBLE.
(_Jv_DetermineVTableIndex): Ditto.
(_Jv_PrepareClass): Ditto. Remove offset-by-one adjustments from vtable
calculations to account for new gc_descr field.
* boehm.cc: #include gc_gcj.h.
(obj_kind_x, obj_free_list): `#if 0'-ed away.
(_Jv_MarkObj): Check that vtable doesn't point to a cleared object.
New commentary from HB. Mark the classes vtable.
(_Jv_MarkArray): Check that vtable doesn't point to a cleared object.
(GC_DEFAULT_DESCR): New #define.
(_Jv_BuildGCDescr): New function. Use GC_DEFAULT_DESCR, for now.
(_Jv_AllocObj): New parameter `klass'. Use GC_GCJ_MALLOC ().
(_Jv_AllocArray): New parameter `klass'. Allocate with GC_MALLOC and
scan conservativly if size is less than min_heap_addr. Set vtable
pointer of new object before returning.
(_Jv_AllocBytes): Use GC_MALLOC_ATOMIC, not GC_GENERIC_MALLOC.
(_Jv_InitGC): Call GC_init_gcj_malloc(). Don't set up marking and
allocation for obj_kind_x.
* nogc.cc (_Jv_BuildGCDescr): New function. Return 0.
(_Jv_AllocObj): Set vtable on returned object.
(_Jv_AllocArray): Ditto.
* java/lang/Class.h (_Jv_NewObjectArray): No longer a friend.
(_Jv_NewPrimArray): Ditto.
(_Jv_AllocObj): Declare as a friend.
(_Jv_AllocArray): Ditto.
* java/lang/natClassLoader.cc (_Jv_FindArrayClass): Copy gc_descr
from &ObjectClass into new array class. Remove offset-by-one
adjustments from `method' size calculations to account for gc_descr
field.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@36679 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/boehm.cc')
-rw-r--r-- | libjava/boehm.cc | 151 |
1 files changed, 130 insertions, 21 deletions
diff --git a/libjava/boehm.cc b/libjava/boehm.cc index 14c4263cd27..f0d679c06ac 100644 --- a/libjava/boehm.cc +++ b/libjava/boehm.cc @@ -28,6 +28,7 @@ extern "C" { #include <gc_priv.h> #include <gc_mark.h> +#include <include/gc_gcj.h> // These aren't declared in any Boehm GC header. void GC_finalize_all (void); @@ -58,14 +59,16 @@ extern java::lang::Class ClassClass; // Nonzero if this module has been initialized. static int initialized = 0; +#if 0 // `kind' index used when allocating Java objects. static int obj_kind_x; -// `kind' index used when allocating Java arrays. -static int array_kind_x; - // Freelist used for Java objects. static ptr_t *obj_free_list; +#endif /* 0 */ + +// `kind' index used when allocating Java arrays. +static int array_kind_x; // Freelist used for Java arrays. static ptr_t *array_free_list; @@ -79,16 +82,24 @@ static _Jv_Mutex_t disable_gc_mutex; // object. We use `void *' arguments and return, and not what the // Boehm GC wants, to avoid pollution in our headers. void * -_Jv_MarkObj (void *addr, void *msp, void *msl, void * /*env*/) +_Jv_MarkObj (void *addr, void *msp, void *msl, void * /* env */) { mse *mark_stack_ptr = (mse *) msp; mse *mark_stack_limit = (mse *) msl; jobject obj = (jobject) addr; + // FIXME: if env is 1, this object was allocated through the debug + // interface, and addr points to the beginning of the debug header. + // In that case, we should really add the size of the header to addr. + _Jv_VTable *dt = *(_Jv_VTable **) addr; - // We check this in case a GC occurs before the vtbl is set. FIXME: - // should use allocation lock while initializing object. - if (__builtin_expect (! dt, false)) + // The object might not yet have its vtable set, or it might + // really be an object on the freelist. In either case, the vtable slot + // will either be 0, or it will point to a cleared object. + // This assumes Java objects have size at least 3 words, + // including the header. But this should remain true, since this + // should only be used with debugging allocation or with large objects. + if (__builtin_expect (! dt || !(dt -> get_finalizer()), false)) return mark_stack_ptr; jclass klass = dt->clas; @@ -101,6 +112,18 @@ _Jv_MarkObj (void *addr, void *msp, void *msl, void * /*env*/) if (__builtin_expect (klass == &ClassClass, false)) { + // Currently we allocate some of the memory referenced from class objects + // as pointerfree memory, and then mark it more intelligently here. + // We ensure that the ClassClass mark descriptor forces invocation of + // this procedure. + // Correctness of this is subtle, but it looks OK to me for now. For the incremental + // collector, we need to make sure that the class object is written whenever + // any of the subobjects are altered and may need rescanning. This may be tricky + // during construction, and this may not be the right way to do this with + // incremental collection. + // If we overflow the mark stack, we will rescan the class object, so we should + // be OK. The same applies if we redo the mark phase because win32 unmapped part + // of our root set. - HB jclass c = (jclass) addr; p = (ptr_t) c->name; @@ -121,6 +144,8 @@ _Jv_MarkObj (void *addr, void *msp, void *msl, void * /*env*/) MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, c5alabel); p = (ptr_t) c->constants.data; MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, c5blabel); + p = (ptr_t) c->vtable; + MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, c5clabel); } #endif @@ -272,9 +297,10 @@ _Jv_MarkArray (void *addr, void *msp, void *msl, void * /*env*/) jobjectArray array = (jobjectArray) addr; _Jv_VTable *dt = *(_Jv_VTable **) addr; - // We check this in case a GC occurs before the vtbl is set. FIXME: - // should use allocation lock while initializing object. - if (__builtin_expect (! dt, false)) + // Assumes size >= 3 words. That's currently true since arrays have + // a vtable, sync pointer, and size. If the sync pointer goes away, + // we may need to round up the size. + if (__builtin_expect (! dt || !(dt -> get_finalizer()), false)) return mark_stack_ptr; jclass klass = dt->clas; @@ -295,29 +321,61 @@ _Jv_MarkArray (void *addr, void *msp, void *msl, void * /*env*/) return mark_stack_ptr; } -// Allocate space for a new Java object. FIXME: this might be the -// wrong interface; we might prefer to pass in the object type as -// well. It isn't important for this collector, but it might be for -// other collectors. +// Return GC descriptor for interpreted class +#ifdef INTERPRETER + +// We assume that the gcj mark proc has index 0. This is a dubious assumption, +// since another one could be registered first. But the compiler also +// knows this, so in that case everything else will break, too. +#define GCJ_DEFAULT_DESCR MAKE_PROC(GCJ_RESERVED_MARK_PROC_INDEX,0) +void * +_Jv_BuildGCDescr(jclass klass) +{ + /* FIXME: We should really look at the class and build the descriptor. */ + return (void *)(GCJ_DEFAULT_DESCR); +} +#endif + +// Allocate space for a new Java object. void * -_Jv_AllocObj (jsize size) +_Jv_AllocObj (jsize size, jclass klass) { - return GC_GENERIC_MALLOC (size, obj_kind_x); + return GC_GCJ_MALLOC (size, klass->vtable); } -// Allocate space for a new Java array. FIXME: again, this might be -// the wrong interface. +// Allocate space for a new Java array. +// Used only for arrays of objects. void * -_Jv_AllocArray (jsize size) +_Jv_AllocArray (jsize size, jclass klass) { - return GC_GENERIC_MALLOC (size, array_kind_x); + void *obj; + const jsize min_heap_addr = 16*1024; + // A heuristic. If size is less than this value, the size + // stored in the array can't possibly be misinterpreted as + // a pointer. Thus we lose nothing by scanning the object + // completely conservatively, since no misidentification can + // take place. + +#ifdef GC_DEBUG + // There isn't much to lose by scanning this conservatively. + // If we didn't, the mark proc would have to understand that + // it needed to skip the header. + obj = GC_MALLOC(size); +#else + if (size < min_heap_addr) + obj = GC_MALLOC(size); + else + obj = GC_GENERIC_MALLOC (size, array_kind_x); +#endif + *((_Jv_VTable **) obj) = klass->vtable; + return obj; } // Allocate some space that is known to be pointer-free. void * _Jv_AllocBytes (jsize size) { - void *r = GC_GENERIC_MALLOC (size, PTRFREE); + void *r = GC_MALLOC_ATOMIC (size); // We have to explicitly zero memory here, as the GC doesn't // guarantee that PTRFREE allocations are zeroed. Note that we // don't have to do this for other allocation types because we set @@ -423,6 +481,56 @@ _Jv_InitGC (void) return; } initialized = 1; + UNLOCK (); + + // Configure the collector to use the bitmap marking descriptors that we + // stash in the class vtable. + GC_init_gcj_malloc (0, (void *) _Jv_MarkObj); + + LOCK (); + GC_java_finalization = 1; + + // We use a different mark procedure for object arrays. This code + // configures a different object `kind' for object array allocation and + // marking. FIXME: see above. + array_free_list = (ptr_t *) GC_generic_malloc_inner ((MAXOBJSZ + 1) + * sizeof (ptr_t), + PTRFREE); + memset (array_free_list, 0, (MAXOBJSZ + 1) * sizeof (ptr_t)); + + proc = GC_n_mark_procs++; + GC_mark_procs[proc] = (mark_proc) _Jv_MarkArray; + + array_kind_x = GC_n_kinds++; + GC_obj_kinds[array_kind_x].ok_freelist = array_free_list; + GC_obj_kinds[array_kind_x].ok_reclaim_list = 0; + GC_obj_kinds[array_kind_x].ok_descriptor = MAKE_PROC (proc, 0); + GC_obj_kinds[array_kind_x].ok_relocate_descr = FALSE; + GC_obj_kinds[array_kind_x].ok_init = TRUE; + + _Jv_MutexInit (&disable_gc_mutex); + + UNLOCK (); + ENABLE_SIGNALS (); +} + +#if 0 +void +_Jv_InitGC (void) +{ + int proc; + DCL_LOCK_STATE; + + DISABLE_SIGNALS (); + LOCK (); + + if (initialized) + { + UNLOCK (); + ENABLE_SIGNALS (); + return; + } + initialized = 1; GC_java_finalization = 1; @@ -464,3 +572,4 @@ _Jv_InitGC (void) UNLOCK (); ENABLE_SIGNALS (); } +#endif /* 0 */ |