This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
PR java/19285: Interfaces not initialized by static field access
- From: Andrew Haley <aph at redhat dot com>
- To: java-patches at gcc dot gnu dot org
- Date: Wed, 27 Apr 2005 20:03:13 +0100
- Subject: PR java/19285: Interfaces not initialized by static field access
This patch fixes the interpreter case, and adds a new interface
(_Jv_ResolvePoolEntry) that allows compiled code to resolve a fieldref
and thereby use the same fix. The compiler half of this patch will
follow.
Tested on JOnAS where it does find a few cases in which the wrong
class was initialized, which strangely doesn't break anything...
Andrew.
2005-04-27 Andrew Haley <aph@redhat.com>
PR java/19285
* prims.cc (_Jv_ResolvePoolEntry): New function.
* include/jvm.h (_Jv_Linker::find_field): New arg: found_class.
* link.cc (_Jv_Linker::find_field): New arg: found_class.
(resolve_pool_entry): Initialize the class in which a field is
found.
(link_symbol_table): Pass new arg to found_class.
Index: link.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/link.cc,v
retrieving revision 1.13
diff -u -2 -p -r1.13 link.cc
--- link.cc 5 Apr 2005 22:26:22 -0000 1.13
+++ link.cc 27 Apr 2005 18:28:19 -0000
@@ -166,4 +166,6 @@ _Jv_Linker::has_field_p (jclass search,
// OWNER is the class in which the field should be found.
// FIELD_TYPE_NAME is the type descriptor for the field.
+// Fill FOUND_CLASS with the address of the class in which the field
+// is actually declared.
// This function does the class loader type checks, and
// also access checks. Returns the field, or throws an
@@ -171,4 +173,5 @@ _Jv_Linker::has_field_p (jclass search,
_Jv_Field *
_Jv_Linker::find_field (jclass klass, jclass owner,
+ jclass *found_class,
_Jv_Utf8Const *field_name,
_Jv_Utf8Const *field_type_name)
@@ -181,7 +184,6 @@ _Jv_Linker::find_field (jclass klass, jc
throw new java::lang::NoClassDefFoundError(field_name->toString());
- jclass found_class = 0;
_Jv_Field *the_field = find_field_helper (owner, field_name,
- field_type->name, &found_class);
+ field_type->name, found_class);
if (the_field == 0)
@@ -196,5 +198,5 @@ _Jv_Linker::find_field (jclass klass, jc
}
- if (_Jv_CheckAccess (klass, found_class, the_field->flags))
+ if (_Jv_CheckAccess (klass, *found_class, the_field->flags))
{
// Note that the field returned by find_field_helper is always
@@ -213,5 +215,5 @@ _Jv_Linker::find_field (jclass klass, jc
sb->append(klass->getName());
sb->append(JvNewStringLatin1(": "));
- sb->append(found_class->getName());
+ sb->append((*found_class)->getName());
sb->append(JvNewStringLatin1("."));
sb->append(_Jv_NewStringUtf8Const (field_name));
@@ -301,7 +303,11 @@ _Jv_Linker::resolve_pool_entry (jclass k
_Jv_Utf8Const *field_type_name = pool->data[type_index].utf8;
- _Jv_Field *the_field = find_field (klass, owner, field_name,
+ jclass found_class = 0;
+ _Jv_Field *the_field = find_field (klass, owner,
+ &found_class,
+ field_name,
field_type_name);
-
+ if (owner != found_class)
+ _Jv_InitClass (found_class);
pool->data[index].field = the_field;
pool->tags[index] |= JV_CONSTANT_ResolvedFlag;
@@ -968,5 +974,6 @@ _Jv_Linker::link_symbol_table (jclass kl
{
wait_for_state(target_class, JV_STATE_PREPARED);
- _Jv_Field *the_field = find_field (klass, target_class,
+ jclass found_class;
+ _Jv_Field *the_field = find_field (klass, target_class, &found_class,
sym.name, sym.signature);
if ((the_field->flags & java::lang::reflect::Modifier::STATIC))
@@ -1048,5 +1055,6 @@ _Jv_Linker::link_symbol_table (jclass kl
{
wait_for_state(target_class, JV_STATE_PREPARED);
- _Jv_Field *the_field = find_field (klass, target_class,
+ jclass found_class;
+ _Jv_Field *the_field = find_field (klass, target_class, &found_class,
sym.name, sym.signature);
if ((the_field->flags & java::lang::reflect::Modifier::STATIC))
Index: prims.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/prims.cc,v
retrieving revision 1.110
diff -u -2 -p -r1.110 prims.cc
--- prims.cc 13 Apr 2005 16:37:20 -0000 1.110
+++ prims.cc 27 Apr 2005 18:28:19 -0000
@@ -360,4 +360,20 @@ _Jv_ThrowNullPointerException ()
}
+// Resolve an entry in the constant pool and return the target
+// address.
+void *
+_Jv_ResolvePoolEntry (jclass this_class, jint index)
+{
+ _Jv_Constants *pool = &this_class->constants;
+
+ if ((pool->tags[index] & JV_CONSTANT_ResolvedFlag) != 0)
+ return pool->data[index].field->u.addr;
+
+ JvSynchronize sync (this_class);
+ return (_Jv_Linker::resolve_pool_entry (this_class, index))
+ .field->u.addr;
+}
+
+
// Explicitly throw a no memory exception.
// The collector calls this when it encounters an out-of-memory condition.
Index: include/jvm.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/include/jvm.h,v
retrieving revision 1.83
diff -u -2 -p -r1.83 jvm.h
--- include/jvm.h 5 Apr 2005 22:26:24 -0000 1.83
+++ include/jvm.h 27 Apr 2005 18:28:20 -0000
@@ -239,5 +239,5 @@ private:
static _Jv_Field *find_field_helper(jclass, _Jv_Utf8Const *, _Jv_Utf8Const *,
jclass *);
- static _Jv_Field *find_field(jclass, jclass, _Jv_Utf8Const *,
+ static _Jv_Field *find_field(jclass, jclass, jclass *, _Jv_Utf8Const *,
_Jv_Utf8Const *);
static void prepare_constant_time_tables(jclass);
Index: java/lang/Class.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/Class.h,v
retrieving revision 1.81
diff -u -2 -p -r1.81 Class.h
--- java/lang/Class.h 17 Mar 2005 00:18:50 -0000 1.81
+++ java/lang/Class.h 27 Apr 2005 18:28:20 -0000
@@ -32,4 +32,5 @@ extern "C" void _Jv_RegisterClasses_Coun
extern "C" void *_Jv_LookupInterfaceMethodIdx (jclass klass, jclass iface,
int meth_idx);
+extern "C" void *_Jv_ResolvePoolEntry (jclass this_class, jint index);
// These are the possible values for the `state' field of the class
@@ -492,4 +493,6 @@ private:
friend void ::_Jv_sharedlib_register_hook (jclass klass);
+ friend void *::_Jv_ResolvePoolEntry (jclass this_class, jint index);
+
// Chain for class pool. This also doubles as the ABI version
// number. It is only used for this purpose at class registration