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]

Patch: FYI: BC classes -vs- JV_STATE_LOADING


I'm checking this in on the trunk.

Bryce's change to make the test suite use -findirect-dispatch pointed
out a bug in how we register BC-compiled classes.  Due to how our
registration system worked, it was possible for the system class
loader to return classes which didn't have their 'super's installed.
This violates an assumption that is made throughout libgcj.

This patch fixes the problem by changing how the system class loader
keeps track of BC-compiled classes.  It also adds a comment to Class.h
to document the assumption in question.

Tom

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

	* java/lang/Class.h (JV_STATE_LOADING): Added comment.
	* Makefile.in: Rebuilt.
	* Makefile.am (nat_source_files): Added natSystemClassLoader.cc.
	* gnu/gcj/runtime/natSystemClassLoader.cc: New file.
	* gnu/gcj/runtime/SystemClassLoader.java (nativeClasses):
	New field.
	(loadedClasses): Removed.
	(findClass): Declare.
	(addClass): Add to nativeClasses, not loadedClasses.

Index: gnu/gcj/runtime/SystemClassLoader.java
===================================================================
--- gnu/gcj/runtime/SystemClassLoader.java	(revision 113527)
+++ gnu/gcj/runtime/SystemClassLoader.java	(working copy)
@@ -22,7 +22,9 @@
     super(new URL[0], parent);
   }
 
-  private HashMap loadedClasses;
+  // This holds all the "native" classes linked into the executable
+  // and registered with this loader.
+  private HashMap nativeClasses = new HashMap();
 
   // This is called to register a native class which was linked into
   // the application but which is registered with the system class
@@ -42,23 +44,11 @@
       }
       
     // Use reflection to access the package-private "loadedClasses" field.
-    if (this.loadedClasses == null)
-      {
-	try
-	{
-	  Class cl = java.lang.ClassLoader.class;
-	  Field lcField = cl.getDeclaredField("loadedClasses");
-	  lcField.setAccessible(true);
-	  this.loadedClasses = (HashMap) lcField.get(this);
-	}
-	catch (Exception x)
-	{
-	  throw new RuntimeException(x);
-	}      
-      }
-    this.loadedClasses.put(className, klass);
+    nativeClasses.put(className, klass);
   }
 
+  protected native Class findClass(String name);
+
   // We add the URLs to the system class loader late.  The reason for
   // this is that during bootstrap we don't want to parse URLs or
   // create URL connections, since that will result in circularities
Index: gnu/gcj/runtime/natSystemClassLoader.cc
===================================================================
--- gnu/gcj/runtime/natSystemClassLoader.cc	(revision 0)
+++ gnu/gcj/runtime/natSystemClassLoader.cc	(revision 0)
@@ -0,0 +1,31 @@
+// natSystemClassLoader.cc - native code for system class loader
+
+/* Copyright (C) Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+#include <platform.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <execution.h>
+
+#include <gnu/gcj/runtime/SystemClassLoader.h>
+#include <java/lang/ClassNotFoundException.h>
+#include <java/util/HashMap.h>
+
+jclass
+gnu::gcj::runtime::SystemClassLoader::findClass (jstring name)
+{
+  jclass result = (jclass) nativeClasses->get(name);
+  if (! result)
+    return URLClassLoader::findClass(name);
+  // Never return a class whose supers are not installed.
+  _Jv_Linker::wait_for_state (result, JV_STATE_LOADING);
+  return result;
+}
Index: java/lang/Class.h
===================================================================
--- java/lang/Class.h	(revision 113527)
+++ java/lang/Class.h	(working copy)
@@ -59,6 +59,14 @@
   JV_STATE_NOTHING = 0,		// Set by compiler.
 
   JV_STATE_PRELOADING = 1,	// Can do _Jv_FindClass.
+
+  // There is an invariant through libgcj that a class will always be
+  // at a state greater than or equal to JV_STATE_LOADING when it is
+  // returned by a class loader to user code.  Hence, defineclass.cc
+  // installs supers before returning a class, C++-ABI-compiled
+  // classes are created with supers installed, and BC-ABI-compiled
+  // classes are linked to this state before being returned by their
+  // class loader.
   JV_STATE_LOADING = 3,		// Has super installed.
   JV_STATE_READ = 4,		// Has been completely defined.
   JV_STATE_LOADED = 5,		// Has Miranda methods defined.
Index: Makefile.am
===================================================================
--- Makefile.am	(revision 113527)
+++ Makefile.am	(working copy)
@@ -783,6 +783,7 @@
 gnu/gcj/io/shs.cc \
 gnu/gcj/runtime/natFinalizerThread.cc \
 gnu/gcj/runtime/natSharedLibLoader.cc \
+gnu/gcj/runtime/natSystemClassLoader.cc \
 gnu/gcj/runtime/natStringBuffer.cc \
 gnu/gcj/util/natDebug.cc \
 gnu/java/lang/natMainThread.cc \


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