X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=libjava%2Fboehm.cc;h=642f451f92e198cda674e9ed9f925a8a22b8b5ce;hb=dbf7cb59f22d9a9fef0da7beaf58f3d19894366b;hp=7982eda095137e90a661a677da5df57fffa3d19b;hpb=75ae025532a15d2842c5401959ef6775e3ebe550;p=pf3gnuchains%2Fgcc-fork.git diff --git a/libjava/boehm.cc b/libjava/boehm.cc index 7982eda0951..642f451f92e 100644 --- a/libjava/boehm.cc +++ b/libjava/boehm.cc @@ -1,6 +1,6 @@ // boehm.cc - interface between libjava and Boehm GC. -/* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation +/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation This file is part of libgcj. @@ -11,6 +11,7 @@ details. */ #include #include +#include #include #include @@ -26,7 +27,6 @@ details. */ extern "C" { -#include #include #include @@ -40,23 +40,9 @@ extern "C" ptr_t GC_debug_generic_malloc (size_t size, int k, GC_EXTRA_PARAMS); }; -// We must check for plausibility ourselves. #define MAYBE_MARK(Obj, Top, Limit, Source, Exit) \ Top=GC_MARK_AND_PUSH((GC_PTR)Obj, Top, Limit, (GC_PTR *)Source) - - -// 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; - -// 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; @@ -148,6 +134,12 @@ _Jv_MarkObj (void *addr, void *msp, void *msl, void * /* env */) p = (ptr_t) c->methods; MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, c6label); + // The vtable might have been set, but the rest of the class + // could still be uninitialized. If this is the case, then + // c.isArray will SEGV. We check for this, and if it is the + // case we just return. + if (__builtin_expect (c->name == NULL, false)) + return mark_stack_ptr; if (! c->isArray() && ! c->isPrimitive()) { @@ -161,19 +153,6 @@ _Jv_MarkObj (void *addr, void *msp, void *msl, void * /* env */) p = (ptr_t) c->methods[i].signature; MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, cm2label); - - // FIXME: `ncode' entry? - -#ifdef INTERPRETER - // The interpreter installs a heap-allocated - // trampoline here, so we'll mark it. - if (_Jv_IsInterpretedClass (c)) - { - p = (ptr_t) c->methods[i].ncode; - MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, - cm3label); - } -#endif } } @@ -225,11 +204,15 @@ _Jv_MarkObj (void *addr, void *msp, void *msl, void * /* env */) MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, cBlabel); p = (ptr_t) c->arrayclass; MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, cDlabel); + p = (ptr_t) c->protectionDomain; + MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, cPlabel); + p = (ptr_t) c->hack_signers; + MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, cSlabel); #ifdef INTERPRETER if (_Jv_IsInterpretedClass (c)) { - _Jv_InterpClass* ic = (_Jv_InterpClass*)c; + _Jv_InterpClass* ic = (_Jv_InterpClass*) c; p = (ptr_t) ic->interpreted_methods; MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, ic, cElabel); @@ -239,6 +222,26 @@ _Jv_MarkObj (void *addr, void *msp, void *msl, void * /* env */) p = (ptr_t) ic->interpreted_methods[i]; MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, ic, \ cFlabel); + + // Mark the direct-threaded code. + if ((c->methods[i].accflags + & java::lang::reflect::Modifier::NATIVE) == 0) + { + _Jv_InterpMethod *im + = (_Jv_InterpMethod *) ic->interpreted_methods[i]; + if (im) + { + p = (ptr_t) im->prepared; + MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, ic, \ + cFlabel); + } + } + + // The interpreter installs a heap-allocated trampoline + // here, so we'll mark it. + p = (ptr_t) c->methods[i].ncode; + MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, + cm3label); } p = (ptr_t) ic->field_initializers; @@ -319,21 +322,63 @@ _Jv_MarkArray (void *addr, void *msp, void *msl, void * /*env*/) return mark_stack_ptr; } -// Return GC descriptor for interpreted class -#ifdef INTERPRETER - +// Generate a GC marking descriptor for a class. +// // 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 GC_MAKE_PROC(GC_GCJ_RESERVED_MARK_PROC_INDEX,0) + void * -_Jv_BuildGCDescr(jclass) +_Jv_BuildGCDescr(jclass self) { - /* FIXME: We should really look at the class and build the descriptor. */ - return (void *)(GCJ_DEFAULT_DESCR); -} + jlong desc = 0; + jint bits_per_word = CHAR_BIT * sizeof (void *); + + // Note: for now we only consider a bitmap mark descriptor. We + // could also handle the case where the first N fields of a type are + // references. However, this is not very likely to be used by many + // classes, and it is easier to compute things this way. + + // The vtable pointer. + desc |= 1ULL << (bits_per_word - 1); +#ifndef JV_HASH_SYNCHRONIZATION + // The sync_info field. + desc |= 1ULL << (bits_per_word - 2); #endif + for (jclass klass = self; klass != NULL; klass = klass->getSuperclass()) + { + jfieldID field = JvGetFirstInstanceField(klass); + int count = JvNumInstanceFields(klass); + + for (int i = 0; i < count; ++i) + { + if (field->isRef()) + { + unsigned int off = field->getOffset(); + // If we run into a weird situation, we bail. + if (off % sizeof (void *) != 0) + return (void *) (GCJ_DEFAULT_DESCR); + off /= sizeof (void *); + // If we find a field outside the range of our bitmap, + // fall back to procedure marker. The bottom 2 bits are + // reserved. + if (off >= bits_per_word - 2) + return (void *) (GCJ_DEFAULT_DESCR); + desc |= 1ULL << (bits_per_word - off - 1); + } + + field = field->getNextField(); + } + } + + // For bitmap mark type, bottom bits are 01. + desc |= 1; + // Bogus warning avoidance (on many platforms). + return (void *) (unsigned long) desc; +} + // Allocate some space that is known to be pointer-free. void * _Jv_AllocBytes (jsize size) @@ -375,6 +420,14 @@ _Jv_AllocArray (jsize size, jclass klass) return obj; } +/* Allocate space for a new non-Java object, which does not have the usual + Java object header but may contain pointers to other GC'ed objects. */ +void * +_Jv_AllocRawObj (jsize size) +{ + return (void *) GC_MALLOC (size); +} + static void call_finalizer (GC_PTR obj, GC_PTR client_data) { @@ -464,19 +517,9 @@ void _Jv_InitGC (void) { int proc; - DCL_LOCK_STATE; - DISABLE_SIGNALS (); - LOCK (); - - if (initialized) - { - UNLOCK (); - ENABLE_SIGNALS (); - return; - } - initialized = 1; - UNLOCK (); + // Ignore pointers that do not point to the start of an object. + GC_all_interior_pointers = 0; // Configure the collector to use the bitmap marking descriptors that we // stash in the class vtable. @@ -486,7 +529,6 @@ _Jv_InitGC (void) // instead of returning 0. This is cheaper than checking on allocation. GC_oom_fn = handle_out_of_memory; - LOCK (); GC_java_finalization = 1; // We use a different mark procedure for object arrays. This code @@ -508,9 +550,6 @@ _Jv_InitGC (void) GC_obj_kinds[array_kind_x].ok_init = TRUE; _Jv_MutexInit (&disable_gc_mutex); - - UNLOCK (); - ENABLE_SIGNALS (); } #ifdef JV_HASH_SYNCHRONIZATION @@ -523,7 +562,7 @@ static _Jv_VTable trace_one_vtable = { (void *)(2 * sizeof(void *)), // descriptor; scan 2 words incl. vtable ptr. // Least significant bits must be zero to - // identify this as a lenght descriptor + // identify this as a length descriptor {0} // First method }; @@ -533,64 +572,42 @@ _Jv_AllocTraceOne (jsize size /* includes vtable slot */) return GC_GCJ_MALLOC (size, &trace_one_vtable); } -#endif /* JV_HASH_SYNCHRONIZATION */ +// Ditto for two words. +// the first field (beyond the fake vtable pointer) to be traced. +// Eventually this should probably be generalized. -#if 0 -void -_Jv_InitGC (void) +static _Jv_VTable trace_two_vtable = { - int proc; - DCL_LOCK_STATE; - - DISABLE_SIGNALS (); - LOCK (); - - if (initialized) - { - UNLOCK (); - ENABLE_SIGNALS (); - return; - } - initialized = 1; - - GC_java_finalization = 1; - - // Set up state for marking and allocation of Java objects. - obj_free_list = (ptr_t *) GC_generic_malloc_inner ((MAXOBJSZ + 1) - * sizeof (ptr_t), - PTRFREE); - memset (obj_free_list, 0, (MAXOBJSZ + 1) * sizeof (ptr_t)); - - proc = GC_n_mark_procs++; - GC_mark_procs[proc] = (GC_mark_proc) _Jv_MarkObj; - - obj_kind_x = GC_n_kinds++; - GC_obj_kinds[obj_kind_x].ok_freelist = obj_free_list; - GC_obj_kinds[obj_kind_x].ok_reclaim_list = 0; - GC_obj_kinds[obj_kind_x].ok_descriptor = GC_MAKE_PROC (proc, 0); - GC_obj_kinds[obj_kind_x].ok_relocate_descr = FALSE; - GC_obj_kinds[obj_kind_x].ok_init = TRUE; + 0, // class pointer + (void *)(3 * sizeof(void *)), + // descriptor; scan 3 words incl. vtable ptr. + {0} // First method +}; - // Set up state for marking and allocation of arrays of Java - // objects. - 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)); +void * +_Jv_AllocTraceTwo (jsize size /* includes vtable slot */) +{ + return GC_GCJ_MALLOC (size, &trace_two_vtable); +} - proc = GC_n_mark_procs++; - GC_mark_procs[proc] = (GC_mark_proc) _Jv_MarkArray; +#endif /* JV_HASH_SYNCHRONIZATION */ - 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 = GC_MAKE_PROC (proc, 0); - GC_obj_kinds[array_kind_x].ok_relocate_descr = FALSE; - GC_obj_kinds[array_kind_x].ok_init = TRUE; +void +_Jv_GCInitializeFinalizers (void (*notifier) (void)) +{ + GC_finalize_on_demand = 1; + GC_finalizer_notifier = notifier; +} - _Jv_MutexInit (&disable_gc_mutex); +void +_Jv_GCRegisterDisappearingLink (jobject *objp) +{ + GC_general_register_disappearing_link ((GC_PTR *) objp, (GC_PTR) *objp); +} - UNLOCK (); - ENABLE_SIGNALS (); +jboolean +_Jv_GCCanReclaimSoftReference (jobject) +{ + // For now, always reclaim soft references. FIXME. + return true; } -#endif /* 0 */