diff options
| author | Bryce McKinlay <bryce@albatross.co.nz> | 2001-01-08 23:28:56 +0000 |
|---|---|---|
| committer | Bryce McKinlay <bryce@gcc.gnu.org> | 2001-01-08 23:28:56 +0000 |
| commit | 5bb11b2e20b893361704d444fcf3a02de7f0bc89 (patch) | |
| tree | be919e8f9daa4b9caa6045e085c18aa82e8c4a09 /libjava/java/lang/natClassLoader.cc | |
| parent | 5bab9296f5a87f0bf7c8785b87d92db9a3b5ecf9 (diff) | |
| download | gcc-5bb11b2e20b893361704d444fcf3a02de7f0bc89.zip gcc-5bb11b2e20b893361704d444fcf3a02de7f0bc89.tar.gz gcc-5bb11b2e20b893361704d444fcf3a02de7f0bc89.tar.bz2 | |
In gcc/java:
* class.c (make_class_data): Push initial value for "arrayclass".
* decl.c (init_decl_processing): Add new class field "arrayclass".
In libjava:
* java/lang/Class.h (_Jv_InitClass): Use __builtin_expect.
(_Jv_NewArrayClass): Renamed from _Jv_FindArrayClass.
(_Jv_GetArrayClass): New inline function.
(arrayclass): New field.
* prims.cc (_Jv_NewObjectArray): Use _Jv_GetArrayClass. Don't use
_Jv_GetArrayElementFromElementType.
(_Jv_NewPrimArray): Ditto.
(_Jv_PrimClass constructor): Initialize "depth", "ancestors", and
"idt" for completeness. Initialze "arrayclass" using _Jv_NewArrayClass.
Set Modifier::ABSTRACT.
* java/lang/natClassLoader.cc (_Jv_NewClass): Initialize "arrayclass".
(_Jv_NewArrayClass): Renamed from _Jv_FindArrayClass. Now void.
Now synchronized. Array classes are now referenced from
elementClass->arrayclass. Don't use _Jv_FindClassInCache.
Set array classes' accessibility flags correctly. Optimize so that
all array classes share the same IDT.
* java/lang/reflect/natArray.cc (newInstance): Use _Jv_GetArrayClass.
* java/lang/reflect/natMethod.cc (_Jv_GetTypesFromSignature): Ditto.
* java/lang/natClass.cc (_getFields): Increment offset. Prevent fields
in superclasses from overwriting classes own fields.
(_Jv_IsAssignableFrom): Check for NULL source idt instead of calling
Modifier::isAbstract().
(null_idt): New static field.
(_Jv_PrepareConstantTimeTables): Optimize case where class implements
no interfaces.
(_Jv_IndexOf): Made inline.
* boehm.cc (_Jv_MarkObj): Mark "arrayclass" field.
From-SVN: r38808
Diffstat (limited to 'libjava/java/lang/natClassLoader.cc')
| -rw-r--r-- | libjava/java/lang/natClassLoader.cc | 150 |
1 files changed, 85 insertions, 65 deletions
diff --git a/libjava/java/lang/natClassLoader.cc b/libjava/java/lang/natClassLoader.cc index f1704ed..979de3f 100644 --- a/libjava/java/lang/natClassLoader.cc +++ b/libjava/java/lang/natClassLoader.cc @@ -530,26 +530,35 @@ _Jv_NewClass (_Jv_Utf8Const *name, jclass superclass, ret->depth = 0; ret->ancestors = NULL; ret->idt = NULL; + ret->arrayclass = NULL; _Jv_RegisterClass (ret); return ret; } -jclass -_Jv_FindArrayClass (jclass element, java::lang::ClassLoader *loader, - _Jv_VTable *array_vtable) +static _Jv_IDispatchTable *array_idt = NULL; +static jshort array_depth = 0; +static jclass *array_ancestors = NULL; + +// Create a class representing an array of ELEMENT and store a pointer to it +// in element->arrayclass. LOADER is the ClassLoader which _initiated_ the +// instantiation of this array. ARRAY_VTABLE is the vtable to use for the new +// array class. This parameter is optional. +void +_Jv_NewArrayClass (jclass element, java::lang::ClassLoader *loader, + _Jv_VTable *array_vtable) { + JvSynchronize sync (element); + _Jv_Utf8Const *array_name; int len; + + if (element->arrayclass) + return; + if (element->isPrimitive()) - { - // For primitive types the array is cached in the class. - jclass ret = (jclass) element->methods; - if (ret) - return ret; - len = 3; - } + len = 3; else len = element->name->length + 5; @@ -557,7 +566,7 @@ _Jv_FindArrayClass (jclass element, java::lang::ClassLoader *loader, char signature[len]; int index = 0; signature[index++] = '['; - // Compute name of array class to see if we've already cached it. + // Compute name of array class. if (element->isPrimitive()) { signature[index++] = (char) element->method_count; @@ -576,65 +585,76 @@ _Jv_FindArrayClass (jclass element, java::lang::ClassLoader *loader, array_name = _Jv_makeUtf8Const (signature, index); } - jclass array_class = _Jv_FindClassInCache (array_name, element->loader); - - if (! array_class) + // Create new array class. + jclass array_class = _Jv_NewClass (array_name, &ObjectClass, + element->loader); + + // Note that `vtable_method_count' doesn't include the initial + // gc_descr slot. + JvAssert (ObjectClass.vtable_method_count == NUM_OBJECT_METHODS); + int dm_count = ObjectClass.vtable_method_count; + + // Create a new vtable by copying Object's vtable (except the + // class pointer, of course). Note that we allocate this as + // unscanned memory -- the vtables are handled specially by the + // GC. + int size = (sizeof (_Jv_VTable) + ((dm_count - 1) * sizeof (void *))); + _Jv_VTable *vtable; + if (array_vtable) + vtable = array_vtable; + else + vtable = (_Jv_VTable *) _Jv_AllocBytes (size); + vtable->clas = array_class; + memcpy (vtable->method, ObjectClass.vtable->method, + dm_count * sizeof (void *)); + vtable->gc_descr = ObjectClass.vtable->gc_descr; + array_class->vtable = vtable; + array_class->vtable_method_count = ObjectClass.vtable_method_count; + + // Stash the pointer to the element type. + array_class->methods = (_Jv_Method *) element; + + // Register our interfaces. + static jclass interfaces[] = { &CloneableClass, &SerializableClass }; + array_class->interfaces = interfaces; + array_class->interface_count = sizeof interfaces / sizeof interfaces[0]; + + // Since all array classes have the same interface dispatch table, we can + // cache one and reuse it. It is not neccessary to synchronize this. + if (!array_idt) { - // Create new array class. - array_class = _Jv_NewClass (array_name, &ObjectClass, element->loader); - - // Note that `vtable_method_count' doesn't include the initial - // gc_descr slot. - JvAssert (ObjectClass.vtable_method_count == NUM_OBJECT_METHODS); - int dm_count = ObjectClass.vtable_method_count; - - // Create a new vtable by copying Object's vtable (except the - // class pointer, of course). Note that we allocate this as - // unscanned memory -- the vtables are handled specially by the - // GC. - int size = (sizeof (_Jv_VTable) + ((dm_count - 1) * sizeof (void *))); - _Jv_VTable *vtable; - if (array_vtable) - vtable = array_vtable; - else - vtable = (_Jv_VTable *) _Jv_AllocBytes (size); - vtable->clas = array_class; - memcpy (vtable->method, ObjectClass.vtable->method, - dm_count * sizeof (void *)); - vtable->gc_descr = ObjectClass.vtable->gc_descr; - array_class->vtable = vtable; - array_class->vtable_method_count = ObjectClass.vtable_method_count; - - // Stash the pointer to the element type. - array_class->methods = (_Jv_Method *) element; - - // Register our interfaces. - static jclass interfaces[] = { &CloneableClass, &SerializableClass }; - array_class->interfaces = interfaces; - array_class->interface_count = sizeof interfaces / sizeof interfaces[0]; - - // FIXME: Shouldn't this be synchronized? _Jv_PrepareConstantTimeTables - // needs to be called with the mutex for array_class held. - // Generate the interface dispatch table. _Jv_PrepareConstantTimeTables (array_class); + array_idt = array_class->idt; + array_depth = array_class->depth; + array_ancestors = array_class->ancestors; + } + else + { + array_class->idt = array_idt; + array_class->depth = array_depth; + array_class->ancestors = array_ancestors; + } - // as per vmspec 5.3.3.2 - array_class->accflags = element->accflags; - - // FIXME: initialize other Class instance variables, - // e.g. `fields'. + using namespace java::lang::reflect; + { + // Array classes are "abstract final"... + _Jv_ushort accflags = Modifier::FINAL | Modifier::ABSTRACT; + // ... and inherit accessibility from element type, per vmspec 5.3.3.2 + accflags |= (element->accflags & Modifier::PUBLIC); + accflags |= (element->accflags & Modifier::PROTECTED); + accflags |= (element->accflags & Modifier::PRIVATE); + array_class->accflags = accflags; + } - // say this class is initialized and ready to go! - array_class->state = JV_STATE_DONE; + // An array class has no visible instance fields. "length" is invisible to + // reflection. - // vmspec, section 5.3.3 describes this - if (element->loader != loader) - _Jv_RegisterInitiatingLoader (array_class, loader); - } + // say this class is initialized and ready to go! + array_class->state = JV_STATE_DONE; - // For primitive types, point back at this array. - if (element->isPrimitive()) - element->methods = (_Jv_Method *) array_class; + // vmspec, section 5.3.3 describes this + if (element->loader != loader) + _Jv_RegisterInitiatingLoader (array_class, loader); - return array_class; + element->arrayclass = array_class; } |
