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]

[BC] Patch: FYI: ensure supers linked by loadClass


I'm checking this in on the BC branch.

Andrew's testing showed that classloader.loadClass("...").getSuperclass()
would cause a crash on BC code, as the super wasn't installed.

I did some investigation and I believe loadClass should always ensure
the superclasses and interfaces are installed, even if we weren't
asked to resolve the class.  A test shows that this is what the JDK
does.  This makes sense as this is the only way to do class
circularity checking.

While doing this I noticed that BC classes are never checked for
inheritance cycles.  I've put this on my to-do list.

Tom

Index: ChangeLog
from  Tom Tromey  <tromey@redhat.com>

	* gnu/gcj/runtime/natSharedLibLoader.cc (ensureSupersLinked): New
	method.
	* gnu/gcj/runtime/SharedLibHelper.java (findClass): Ensure supers
	linked.
	(ensureSupersLinked): Declare.
	* java/lang/natVMClassLoader.cc (loadClass): Ensure supers
	linked.

Index: gnu/gcj/runtime/SharedLibHelper.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/gcj/runtime/SharedLibHelper.java,v
retrieving revision 1.1.32.4
diff -u -r1.1.32.4 SharedLibHelper.java
--- gnu/gcj/runtime/SharedLibHelper.java 12 Aug 2004 17:58:14 -0000 1.1.32.4
+++ gnu/gcj/runtime/SharedLibHelper.java 11 Nov 2004 19:01:25 -0000
@@ -127,7 +127,15 @@
   public Class findClass(String name)
   {
     ensureInit();
-    return (Class) classMap.get(name);
+    Class result = (Class) classMap.get(name);
+    if (result != null)
+      {
+	// We never want to return a class without its supers linked.
+	// It isn't clear from the spec, but this is what other
+	// implementations do in practice.
+	ensureSupersLinked(result);
+      }
+    return result;
   }
 
   public URL findResource (String name)
@@ -160,6 +168,7 @@
 
   native boolean hasResource(String name);
   native void init();
+  native void ensureSupersLinked(Class k);
 
   public String toString ()
   {
Index: gnu/gcj/runtime/natSharedLibLoader.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/gcj/runtime/natSharedLibLoader.cc,v
retrieving revision 1.5.18.1
diff -u -r1.5.18.1 natSharedLibLoader.cc
--- gnu/gcj/runtime/natSharedLibLoader.cc 14 Sep 2004 21:12:53 -0000 1.5.18.1
+++ gnu/gcj/runtime/natSharedLibLoader.cc 11 Nov 2004 19:01:25 -0000
@@ -125,3 +125,9 @@
   dlclose (handler);
 #endif
 }
+
+void
+gnu::gcj::runtime::SharedLibHelper::ensureSupersLinked(jclass k)
+{
+  _Jv_Linker::wait_for_state (k, JV_STATE_LOADING);
+}
Index: java/lang/natVMClassLoader.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natVMClassLoader.cc,v
retrieving revision 1.1.18.5
diff -u -r1.1.18.5 natVMClassLoader.cc
--- java/lang/natVMClassLoader.cc 18 Oct 2004 23:48:57 -0000 1.1.18.5
+++ java/lang/natVMClassLoader.cc 11 Nov 2004 19:01:25 -0000
@@ -132,9 +132,16 @@
 java::lang::VMClassLoader::loadClass(jstring name, jboolean resolve)
 {
   _Jv_Utf8Const *utf = _Jv_makeUtf8Const (name);
-  // FIXME: we culd make _Jv_FindClassFromSignature a template.
   jclass klass = _Jv_FindClassInCache (utf, NULL);
-  if (klass && resolve)
-    _Jv_InitClass (klass);
+  if (klass)
+    {
+      // We never want to return a class without its supers linked.
+      // It isn't clear from the spec, but this is what other
+      // implementations do in practice.
+      if (resolve)
+	_Jv_InitClass (klass);
+      else
+	_Jv_Linker::wait_for_state (klass, JV_STATE_LOADING);
+    }
   return klass;
 }


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