This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
[BC] Patch: FYI: ensure supers linked by loadClass
- From: Tom Tromey <tromey at redhat dot com>
- To: Java Patch List <java-patches at gcc dot gnu dot org>
- Date: 11 Nov 2004 12:06:01 -0700
- Subject: [BC] Patch: FYI: ensure supers linked by loadClass
- Reply-to: tromey at redhat dot com
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;
}