From 938f37772eae24bf9fd62530ed5f0bf0e43598ec Mon Sep 17 00:00:00 2001 From: Hans Boehm Date: Fri, 14 Dec 2001 18:43:55 +0000 Subject: prims.cc: Some old cleanups. * libjava/prims.cc: Some old cleanups. The collector now handles test for out of memory. * libjava/prims.cc, libjava/gcj/javaprims.h: (_Jv_AllocObjectNoInitNoFinalizer, _Jv_AllocObjectNoFinalizer): New functions for finalizer-free allocation. (jvmpi_notify_alloc): Became separate function. * libjava/java/lang/Object.h, libjava/include/jvm.h: Adjust for revised vtable layout on IA64. With TARGET_VTABLE_USES_DESCRIPTORS, there is only one extra descriptor. From-SVN: r48002 --- libjava/ChangeLog | 13 ++++++++ libjava/gcj/javaprims.h | 2 ++ libjava/include/jvm.h | 20 +++++++------ libjava/java/lang/Object.h | 7 +++-- libjava/prims.cc | 74 ++++++++++++++++++++++++++++++---------------- 5 files changed, 79 insertions(+), 37 deletions(-) diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 4116fae..40781b0 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,16 @@ +2001-12-14 Hans Boehm + * libjava/prims.cc: Some old cleanups. The collector now + handles test for out of memory. + + * libjava/prims.cc, libjava/gcj/javaprims.h: + (_Jv_AllocObjectNoInitNoFinalizer, _Jv_AllocObjectNoFinalizer): + New functions for finalizer-free allocation. + (jvmpi_notify_alloc): Became separate function. + + * libjava/java/lang/Object.h, libjava/include/jvm.h: Adjust for + revised vtable layout on IA64. With TARGET_VTABLE_USES_DESCRIPTORS, + there is only one extra descriptor. + 2001-12-12 Tom Tromey * prims.cc (_Jv_RunMain): Use `using' to simplify code. Set diff --git a/libjava/gcj/javaprims.h b/libjava/gcj/javaprims.h index 1382e4a..c07d40c 100644 --- a/libjava/gcj/javaprims.h +++ b/libjava/gcj/javaprims.h @@ -384,6 +384,8 @@ typedef struct _Jv_Field *jfieldID; typedef struct _Jv_Method *jmethodID; extern "C" jobject _Jv_AllocObject (jclass, jint) __attribute__((__malloc__)); +extern "C" jobject _Jv_AllocObjectNoFinalizer (jclass, jint) __attribute__((__malloc__)); +extern "C" jobject _Jv_AllocObjectNoInitNoFinalizer (jclass, jint) __attribute__((__malloc__)); #ifdef JV_HASH_SYNCHRONIZATION extern "C" jobject _Jv_AllocPtrFreeObject (jclass, jint) __attribute__((__malloc__)); diff --git a/libjava/include/jvm.h b/libjava/include/jvm.h index 1cba08c..57ba44f 100644 --- a/libjava/include/jvm.h +++ b/libjava/include/jvm.h @@ -28,18 +28,12 @@ details. */ struct _Jv_VTable { #ifdef __ia64__ - jclass clas; - unsigned long : 64; - void *gc_descr; - unsigned long : 64; - typedef struct { void *pc, *gp; } vtable_elt; #else - jclass clas; - void *gc_descr; - typedef void *vtable_elt; #endif + jclass clas; + void *gc_descr; // This must be last, as derived classes "extend" this by // adding new data members. @@ -48,12 +42,20 @@ struct _Jv_VTable #ifdef __ia64__ void *get_method(int i) { return &method[i]; } void set_method(int i, void *fptr) { method[i] = *(vtable_elt *)fptr; } + void *get_finalizer() + { + // We know that get_finalizer is only used for checking whether + // this object needs to have a finalizer registered. So it is + // safe to simply return just the PC component of the vtable + // slot. + return ((vtable_elt *)(get_method(0)))->pc; + } #else void *get_method(int i) { return method[i]; } void set_method(int i, void *fptr) { method[i] = fptr; } + void *get_finalizer() { return get_method(0); } #endif - void *get_finalizer() { return get_method(0); } static size_t vtable_elt_size() { return sizeof(vtable_elt); } static _Jv_VTable *new_vtable (int count); }; diff --git a/libjava/java/lang/Object.h b/libjava/java/lang/Object.h index 93e207f..b0d8270 100644 --- a/libjava/java/lang/Object.h +++ b/libjava/java/lang/Object.h @@ -21,8 +21,11 @@ struct _JvObjectPrefix { protected: // New ABI Compatibility Dummy, #1 and 2. - virtual void nacd_1 (void) {}; // This slot really contains the Class pointer. - virtual void nacd_2 (void) {}; // Actually the GC bitmap marking descriptor. + virtual void nacd_1 (void) {}; // This slot really contains the Class pointer. + // For IA64, the GC descriptor goes into the second word of the nacd1 descr. +# ifndef __ia64__ + virtual void nacd_2 (void) {}; // Actually the GC bitmap marking descriptor. +# endif }; class java::lang::Object : public _JvObjectPrefix diff --git a/libjava/prims.cc b/libjava/prims.cc index 75204b8..40d1bd6 100644 --- a/libjava/prims.cc +++ b/libjava/prims.cc @@ -256,8 +256,6 @@ _Jv_makeUtf8Const (char* s, int len) if (len < 0) len = strlen (s); Utf8Const* m = (Utf8Const*) _Jv_AllocBytes (sizeof(Utf8Const) + len + 1); - if (! m) - throw no_memory; memcpy (m->data, s, len); m->data[len] = 0; m->length = len; @@ -333,33 +331,14 @@ _Jv_ThrowNullPointerException () // The collector calls this when it encounters an out-of-memory condition. void _Jv_ThrowNoMemory() { - _Jv_Throw (no_memory); + throw no_memory; } -// Allocate a new object of class KLASS. SIZE is the size of the object -// to allocate. You might think this is redundant, but it isn't; some -// classes, such as String, aren't of fixed size. -jobject -_Jv_AllocObject (jclass klass, jint size) -{ - _Jv_InitClass (klass); - - jobject obj = (jobject) _Jv_AllocObj (size, klass); - - // If this class has inherited finalize from Object, then don't - // bother registering a finalizer. We know that finalize() is the - // very first method after the dummy entry. If this turns out to be - // unreliable, a more robust implementation can be written. Such an - // implementation would look for Object.finalize in Object's method - // table at startup, and then use that information to find the - // appropriate index in the method vector. - if (klass->vtable->get_finalizer() - != java::lang::Object::class$.vtable->get_finalizer()) - _Jv_RegisterFinalizer (obj, _Jv_FinalizeObject); - #ifdef ENABLE_JVMPI - // Service JVMPI request. - +static void +jvmpi_notify_alloc(jclass klass, jint size, jobject obj) +{ + // Service JVMPI allocation request. if (__builtin_expect (_Jv_JVMPI_Notify_OBJECT_ALLOC != 0, false)) { JVMPI_Event event; @@ -384,8 +363,51 @@ _Jv_AllocObject (jclass klass, jint size) (*_Jv_JVMPI_Notify_OBJECT_ALLOC) (&event); _Jv_EnableGC (); } +} +#else /* !ENABLE_JVMPI */ +# define jvmpi_notify_alloc(klass,size,obj) /* do nothing */ #endif +// Allocate a new object of class KLASS. SIZE is the size of the object +// to allocate. You might think this is redundant, but it isn't; some +// classes, such as String, aren't of fixed size. +// First a version that assumes that we have no finalizer, and that +// the class is already initialized. +// If we know that JVMPI is disabled, this can be replaced by a direct call +// to the allocator for the appropriate GC. +jobject +_Jv_AllocObjectNoInitNoFinalizer (jclass klass, jint size) +{ + jobject obj = (jobject) _Jv_AllocObj (size, klass); + jvmpi_notify_alloc (klass, size, obj); + return obj; +} + +// And now a version that initializes if necessary. +jobject +_Jv_AllocObjectNoFinalizer (jclass klass, jint size) +{ + _Jv_InitClass (klass); + jobject obj = (jobject) _Jv_AllocObj (size, klass); + jvmpi_notify_alloc (klass, size, obj); + return obj; +} + +// And now the general version that registers a finalizer if necessary. +jobject +_Jv_AllocObject (jclass klass, jint size) +{ + jobject obj = _Jv_AllocObjectNoFinalizer (klass, size); + + // We assume that the compiler only generates calls to this routine + // if there really is an interesting finalizer. + // Unfortunately, we still have to the dynamic test, since there may + // be cni calls to this routine. + // Nore that on IA64 get_finalizer() returns the starting address of the + // function, not a function pointer. Thus this still works. + if (klass->vtable->get_finalizer () + != java::lang::Object::class$.vtable->get_finalizer ()) + _Jv_RegisterFinalizer (obj, _Jv_FinalizeObject); return obj; } -- cgit v1.1