This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]