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: RFC: PR 9125 change


This patch provides a fix/workaround for PR 9125.  I'd like some
comments before checking it in.

This is a variant of a patch I added for eclipse.  That patch adds
caching to the dlopen() step in the default class loader.  With the
cache, if we fail to find a library once, we will never look for it
again.

If you watch eclipse startup, you can see why this is desirable.  It
makes a very large number of dlopen attempts.

Now, eclipse doesn't need this dlopen code at all.  It is
self-contained and each plugin is already set up to know where to find
the required code.  Eliminating this dlopen step entirely avoids
another 20,000 (really) failing dlopen calls -- this isn't counting
the many times more we eliminated by caching failed dlopens.

The reason this is so high is that eclipse loads everything through
custom class loaders.  When we're using the solib: URL patch, compiled
classes loaded through these are registered with the plugin loader
only.  So the plugin loader does the usual delegation, and eventually
winds up in the system class loader.  In a more straightforward
program, no dlopen is done for ordinary class lookup since classes
linked or loaded in are available in the internal registration table.

Anyway, my solution to all this was to add a new property which can be
set to control how dlopens are done by the system class loader.  We
can just link eclipse with a setting of `never'.

Tom

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

	* gcj.texi (Extensions): Added xref.
	(libgcj Runtime Properties): Document
	gnu.gcj.runtime.VMClassLoader.library_control.

Index: gcc/java/gcj.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/gcj.texi,v
retrieving revision 1.55
diff -u -r1.55 gcj.texi
--- gcc/java/gcj.texi 13 Aug 2003 17:18:20 -0000 1.55
+++ gcc/java/gcj.texi 16 Aug 2003 22:02:24 -0000
@@ -543,7 +543,9 @@
 for inner classes starts with their outermost outer class.  If the class
 cannot be found this way the system classloader tries to use
 the @code{libgcj} bytecode interpreter to load the class from the standard
-classpath.
+classpath.  This process can be controlled to some degree via the
+@code{gnu.gcj.runtime.VMClassLoader.library_control} property;
+@xref{libgcj Runtime Properties}.
 @end itemize
 
 @node Invoking gcjh
@@ -2246,6 +2248,14 @@
 Whether an external process (@command{addr2line} or @command{addr2name.awk})
 should be used as fallback to convert the addresses to function names when
 the runtime is unable to do it through @code{dladdr}.
+
+@item gnu.gcj.runtime.VMClassLoader.library_control
+This controls how shared libraries are automatically loaded by the
+built-in class loader.  By default, or if this property is set to
+@samp{full}, a full search is done for each requested class.  If this
+property is set to @samp{cache}, then any failed lookups are cached
+and not tried again.  If this property is set to @samp{never}, then
+lookups are never done.  For more information, @xref{Extensions}.
 
 @end table
 
Index: libjava/ChangeLog
from  Tom Tromey  <tromey@redhat.com>

	Fix for PR libgcj/9125:
	* gnu/gcj/runtime/natVMClassLoader.cc (findClass): Find Runtime
	object outside of loop.  Respect lib_control setting.
	* gnu/gcj/runtime/VMClassLoader.java (tried_libraries): New
	field.
	(lib_control): New field.
	(LIB_FULL, LIB_CACHE, LIB_NEVER): New constants.
	(VMClassLoader): Initialize new field.

Index: libjava/gnu/gcj/runtime/VMClassLoader.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/gcj/runtime/VMClassLoader.java,v
retrieving revision 1.9
diff -u -r1.9 VMClassLoader.java
--- libjava/gnu/gcj/runtime/VMClassLoader.java 9 Dec 2002 00:03:59 -0000 1.9
+++ libjava/gnu/gcj/runtime/VMClassLoader.java 16 Aug 2003 22:02:28 -0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999, 2001, 2002  Free Software Foundation
+/* Copyright (C) 1999, 2001, 2002, 2003  Free Software Foundation
 
    This file is part of libgcj.
 
@@ -12,6 +12,7 @@
 
 import java.io.*;
 import java.util.StringTokenizer;
+import java.util.HashSet;
 import java.net.URL;
 
 public final class VMClassLoader extends java.net.URLClassLoader
@@ -19,6 +20,20 @@
   private VMClassLoader ()
   {	
     super (init());
+    String p
+      = System.getProperty ("gnu.gcj.runtime.VMClassLoader.library_control",
+			    "");
+    if ("never".equals(p))
+      lib_control = LIB_NEVER;
+    else if ("cache".equals(p))
+      lib_control = LIB_CACHE;
+    else if ("full".equals(p))
+      {
+	// In case we ever want to change the default.
+	lib_control = LIB_FULL;
+      }
+    else
+      lib_control = LIB_FULL;
   }
 
   private static URL[] init() 
@@ -67,6 +82,17 @@
   protected native Class findClass(String name) 
     throws java.lang.ClassNotFoundException;
 
+  // This keeps track of shared libraries we've already tried to load.
+  private HashSet tried_libraries = new HashSet();
+
+  // Holds one of the LIB_* constants; used to determine how shared
+  // library loads are done.
+  private int lib_control;
+
   // The only VMClassLoader that can exist.
-  public static VMClassLoader instance = new VMClassLoader ();
+  public static VMClassLoader instance = new VMClassLoader();
+
+  private static final int LIB_FULL = 0;
+  private static final int LIB_CACHE = 1;
+  private static final int LIB_NEVER = 2;
 }
Index: libjava/gnu/gcj/runtime/natVMClassLoader.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/gcj/runtime/natVMClassLoader.cc,v
retrieving revision 1.1
diff -u -r1.1 natVMClassLoader.cc
--- libjava/gnu/gcj/runtime/natVMClassLoader.cc 11 Dec 2002 03:15:14 -0000 1.1
+++ libjava/gnu/gcj/runtime/natVMClassLoader.cc 16 Aug 2003 22:02:28 -0000
@@ -1,6 +1,6 @@
 // Native code for VMClassLoader
 
-/* Copyright (C) 2002  Free Software Foundation
+/* Copyright (C) 2002, 2003  Free Software Foundation
 
    This file is part of libgcj.
 
@@ -18,6 +18,7 @@
 #include <java/lang/StringBuffer.h>
 #include <java/net/URLClassLoader.h>
 #include <java/lang/Runtime.h>
+#include <java/util/HashSet.h>
 
 jclass
 gnu::gcj::runtime::VMClassLoader::findClass (jstring name)
@@ -25,7 +26,7 @@
   _Jv_Utf8Const *name_u = _Jv_makeUtf8Const (name);
   jclass klass = _Jv_FindClassInCache (name_u, 0);
 
-  if (! klass)
+  if (! klass && lib_control != LIB_NEVER)
     {
       // Turn `gnu.pkg.quux' into `lib-gnu-pkg-quux'.  Then search for
       // a module named (eg, on Linux) `lib-gnu-pkg-quux.so', followed
@@ -41,11 +42,20 @@
 	cn = name->substring (0, ci);
       jstring so_base_name = (sb->append (cn)->toString ())->replace ('.', '-');
 
+      using namespace ::java::lang;
+      Runtime *rt = Runtime::getRuntime();
+
       // Compare against `3' because that is the length of "lib".
       while (! klass && so_base_name && so_base_name->length() > 3)
 	{
-	  using namespace ::java::lang;
-	  Runtime *rt = Runtime::getRuntime();
+	  if (lib_control == LIB_CACHE)
+	    {
+	      // If we've already tried this name, we're done.
+	      if (tried_libraries->contains(so_base_name))
+		break;
+	      tried_libraries->add(so_base_name);
+	    }
+
 	  jboolean loaded = rt->loadLibraryInternal (so_base_name);
 
 	  jint nd = so_base_name->lastIndexOf ('-');


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