[armedbear-cvs] r14015 - trunk/abcl/src/org/armedbear/lisp

mevenson at common-lisp.net mevenson at common-lisp.net
Mon Jul 23 11:58:36 UTC 2012


Author: mevenson
Date: Mon Jul 23 04:58:34 2012
New Revision: 14015

Log:
dmiles:  classloaders to search their parent/system classloaders first.

Robustifies strategies for loading in non-JVM environments (iKVM/GCJ)
when using the "class" PATHNAME TYPE for bytecode artifacts.

Modified:
   trunk/abcl/src/org/armedbear/lisp/FaslClassLoader.java
   trunk/abcl/src/org/armedbear/lisp/JavaClassLoader.java
   trunk/abcl/src/org/armedbear/lisp/MemoryClassLoader.java

Modified: trunk/abcl/src/org/armedbear/lisp/FaslClassLoader.java
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/FaslClassLoader.java	Sat Jul 21 07:02:32 2012	(r14014)
+++ trunk/abcl/src/org/armedbear/lisp/FaslClassLoader.java	Mon Jul 23 04:58:34 2012	(r14015)
@@ -59,9 +59,16 @@
          * which - in ABCL - is pretty deep, most of the time.
          */
         if (name.startsWith(baseName + "_")) {
-            String internalName = "org/armedbear/lisp/" + name;
+            String internalName = name.replace(".", "/");
+            if (!internalName.contains("/")) internalName = "org/armedbear/lisp/" + internalName;
             Class<?> c = this.findLoadedClass(internalName);
 
+            if (c == null && checkPreCompiledClassLoader) {
+            	c = findPrecompiledClassOrNull(name);
+            	// Oh, we have to return here so we don't become the owning class loader?
+            	if (c != null)
+                  return c;
+            }            
             if (c == null) {
                 c = findClass(name);
             }
@@ -80,8 +87,13 @@
     @Override
     protected Class<?> findClass(String name) throws ClassNotFoundException {
         try {
+            if (checkPreCompiledClassLoader) {
+            	Class<?> c = findPrecompiledClassOrNull(name);
+            	if (c != null)
+            		return c;                	
+            }
             byte[] b = getFunctionClassBytes(name);
-            return defineClass(name, b, 0, b.length);
+            return defineLispClass(name, b, 0, b.length);
         } catch(Throwable e) { //TODO handle this better, readFunctionBytes uses Debug.assert() but should return null
             e.printStackTrace();
             if(e instanceof ControlTransfer) { throw (ControlTransfer) e; }
@@ -110,27 +122,16 @@
       return null;
     }
 
-    public byte[] getFunctionClassBytes(String name) {
-        Pathname pathname = new Pathname(name.substring("org/armedbear/lisp/".length()) + "." + Lisp._COMPILE_FILE_CLASS_EXTENSION_.symbolValue().getStringValue());
-        return readFunctionBytes(pathname);
-    }
-
-    public byte[] getFunctionClassBytes(Class<?> functionClass) {
-        return getFunctionClassBytes(functionClass.getName());
-    }
-
-    public byte[] getFunctionClassBytes(Function f) {
-        byte[] b = getFunctionClassBytes(f.getClass());
-        f.setClassBytes(b);
-        return b;
-    }
-
     public LispObject loadFunction(int fnNumber) {
         //Function name is fnIndex + 1
         String name = baseName + "_" + (fnNumber + 1);
         try {
-            Function f = (Function) loadClass(name).newInstance();
-            f.setClassBytes(getFunctionClassBytes(name));
+            Class clz = loadClass(name);
+            Function f = (Function) clz.newInstance();
+            if (clz.getClassLoader() instanceof JavaClassLoader) {
+                // Don't do this for system classes (though probably dont need this for other classes) 
+                f.setClassBytes(getFunctionClassBytes(name));
+            }
             return f;
         } catch(Throwable e) {
             if(e instanceof ControlTransfer) { throw (ControlTransfer) e; }

Modified: trunk/abcl/src/org/armedbear/lisp/JavaClassLoader.java
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/JavaClassLoader.java	Sat Jul 21 07:02:32 2012	(r14014)
+++ trunk/abcl/src/org/armedbear/lisp/JavaClassLoader.java	Mon Jul 23 04:58:34 2012	(r14015)
@@ -38,6 +38,9 @@
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
 import java.net.URL;
 import java.net.URLClassLoader;
 
@@ -45,6 +48,71 @@
 
     private static JavaClassLoader persistentInstance;
 
+    public static boolean checkPreCompiledClassLoader = true;
+    
+    public Class<?> loadClass(String name) throws ClassNotFoundException {
+        if (checkPreCompiledClassLoader) {
+            Class<?> c = findPrecompiledClassOrNull(name);
+            if (c != null) {
+                return c;                       
+            }
+        }
+        return loadClass(name, false);
+    }
+    
+    /**
+     * Returns a class loaded by the system or bootstrap class loader;
+     * or return null if not found.
+     * 
+     * On AOT systems like GCJ and IKVM this means a class implemented in ASM or CLR
+     * 
+     * like findLoadedClass it does not throw an exception if a class is not found
+     */
+    public Class<?> findPrecompiledClassOrNull(String name) {
+        ClassLoader ourCL = JavaClassLoader.class.getClassLoader();
+        while (ourCL != null) {
+            try {
+                return Class.forName(name, true, ourCL);
+            } catch (ClassNotFoundException cnf) {
+            }
+            ourCL = ourCL.getParent();
+        }
+        try {
+            return findSystemClass(name);
+        } catch (ClassNotFoundException e) {
+            return null;
+        }
+    }
+    
+    public byte[] getFunctionClassBytes(String name) {
+        Pathname pathname 
+            = new Pathname(name.substring("org/armedbear/lisp/".length()) 
+                           + "." + Lisp._COMPILE_FILE_CLASS_EXTENSION_.symbolValue().getStringValue());
+        return readFunctionBytes(pathname);
+    }
+
+    public byte[] getFunctionClassBytes(Class<?> functionClass) {
+        String className = functionClass.getName();
+        try {
+            String ext = Lisp._COMPILE_FILE_CLASS_EXTENSION_.symbolValue().getStringValue();
+            InputStream is = getResourceAsStream(className.replace('.', '/') + "." + ext);
+            if (is != null) {
+                byte[] imgDataBa = new byte[(int) is.available()];
+                DataInputStream dataIs = new DataInputStream(is);
+                dataIs.readFully(imgDataBa);
+                return imgDataBa;
+            }
+        } catch (IOException e) {
+        }
+        return getFunctionClassBytes(className);
+    }
+
+    final public byte[] getFunctionClassBytes(Function f) {
+        byte[] b = getFunctionClassBytes(f.getClass());
+        f.setClassBytes(b);
+        return b;
+    }
+
     private static Set<String> packages = Collections.synchronizedSet(new HashSet<String>());
 
     public JavaClassLoader()
@@ -53,11 +121,11 @@
     }
 
     public JavaClassLoader(ClassLoader parent) {
-	super(new URL[] {}, parent);
+        super(new URL[] {}, parent);
     }
 
     public JavaClassLoader(URL[] classpath, ClassLoader parent) {
-	super(classpath, parent);
+        super(classpath, parent);
     }
 
     public static JavaClassLoader getPersistentInstance()
@@ -69,7 +137,7 @@
     {
         if (persistentInstance == null)
             persistentInstance = new JavaClassLoader();
-	definePackage(packageName);
+        definePackage(packageName);
         return persistentInstance;
     }
 
@@ -89,30 +157,36 @@
                                                 byte[] classbytes)
     {
         try {
-            long length = classbytes.length;
+            long length = classbytes.length; 
             if (length < Integer.MAX_VALUE) {
                 Class<?> c =
-                    defineClass(className, classbytes, 0, (int) length);
+                    defineLispClass(className, classbytes, 0, (int) length);
                 if (c != null) {
                     resolveClass(c);
                     return c;
                 }
             }
         }
-    	catch (LinkageError e) {
+        catch (LinkageError e) {
                 throw e;
-    	}
+        }
         catch (Throwable t) {
             Debug.trace(t);
         }
         return null;
     }
 
+    protected final Class<?> defineLispClass(String name, byte[] b, int off, int len)
+                throws ClassFormatError {        
+        ///if (checkPreCompiledClassLoader) Debug.trace("DEFINE JAVA CLASS " + name + " " + len);
+        return defineClass(name, b, off, len);
+    }
+    
     public Class<?> loadClassFromByteArray(String className, byte[] bytes,
                                                 int offset, int length)
     {
         try {
-            Class<?> c = defineClass(className, bytes, offset, length);
+            Class<?> c = defineLispClass(className, bytes, offset, length);
             if (c != null) {
                 resolveClass(c);
                 return c;
@@ -130,15 +204,15 @@
 
     @Override
     public void addURL(URL url) {
-	super.addURL(url);
+        super.addURL(url);
     }
 
     public static final Symbol CLASSLOADER = PACKAGE_JAVA.intern("*CLASSLOADER*");
 
     private static final Primitive GET_DEFAULT_CLASSLOADER = new pf_get_default_classloader();
     private static final class pf_get_default_classloader extends Primitive {
-	
-	private final LispObject defaultClassLoader = new JavaObject(new JavaClassLoader());
+        
+        private final LispObject defaultClassLoader = new JavaObject(new JavaClassLoader());
 
         pf_get_default_classloader() {
             super("get-default-classloader", PACKAGE_JAVA, true, "");
@@ -146,7 +220,7 @@
 
         @Override
         public LispObject execute() {
-	    return defaultClassLoader;
+            return defaultClassLoader;
         }
     };
 
@@ -161,12 +235,12 @@
 
         @Override
         public LispObject execute() {
-	    return new JavaObject(new JavaClassLoader(getCurrentClassLoader()));
+            return new JavaObject(new JavaClassLoader(getCurrentClassLoader()));
         }
 
         @Override
         public LispObject execute(LispObject parent) {
-	    return new JavaObject(new JavaClassLoader((ClassLoader) parent.javaInstance(ClassLoader.class)));
+            return new JavaObject(new JavaClassLoader((ClassLoader) parent.javaInstance(ClassLoader.class)));
         }
     };
 
@@ -181,19 +255,19 @@
 
         @Override
         public LispObject execute() {
-	    return execute(new JavaObject(getCurrentClassLoader()));
+            return execute(new JavaObject(getCurrentClassLoader()));
         }
 
         @Override
         public LispObject execute(LispObject classloader) {
-	    LispObject list = NIL;
-	    Object o = classloader.javaInstance();
-	    while(o instanceof ClassLoader) {
-		ClassLoader cl = (ClassLoader) o;
-		list = list.push(dumpClassPath(cl));
-		o = cl.getParent();
-	    }
-	    return list.nreverse();
+            LispObject list = NIL;
+            Object o = classloader.javaInstance();
+            while(o instanceof ClassLoader) {
+                ClassLoader cl = (ClassLoader) o;
+                list = list.push(dumpClassPath(cl));
+                o = cl.getParent();
+            }
+            return list.nreverse();
         }
     };
 
@@ -221,26 +295,26 @@
 
         @Override
         public LispObject execute(LispObject jarOrJars) {
-	    return execute(jarOrJars, new JavaObject(getCurrentClassLoader()));
+            return execute(jarOrJars, new JavaObject(getCurrentClassLoader()));
         }
 
         @Override
         public LispObject execute(LispObject jarOrJars, LispObject classloader) {
-	    Object o = classloader.javaInstance();
-	    if(o instanceof JavaClassLoader) {
-		JavaClassLoader jcl = (JavaClassLoader) o;
-		if(jarOrJars instanceof Cons) {
-		    while(jarOrJars != NIL) {
-			addURL(jcl, jarOrJars.car());
-			jarOrJars = jarOrJars.cdr();
-		    }
-		} else {
-		    addURL(jcl, jarOrJars);
-		}
-		return T;
-	    } else {
-		return error(new TypeError(o + " must be an instance of " + JavaClassLoader.class.getName()));
-	    }
+            Object o = classloader.javaInstance();
+            if(o instanceof JavaClassLoader) {
+                JavaClassLoader jcl = (JavaClassLoader) o;
+                if(jarOrJars instanceof Cons) {
+                    while(jarOrJars != NIL) {
+                        addURL(jcl, jarOrJars.car());
+                        jarOrJars = jarOrJars.cdr();
+                    }
+                } else {
+                    addURL(jcl, jarOrJars);
+                }
+                return T;
+            } else {
+                return error(new TypeError(o + " must be an instance of " + JavaClassLoader.class.getName()));
+            }
         }
     };
 
@@ -256,24 +330,24 @@
 
 
     public static LispObject dumpClassPath(ClassLoader o) {
-	if(o instanceof URLClassLoader) {
-	    LispObject list = NIL;
-	    for(URL u : ((URLClassLoader) o).getURLs()) {
-		list = list.push(new Pathname(u));
-	    }
-	    return new Cons(new JavaObject(o), list.nreverse());
-	} else {
-	    return new JavaObject(o);
-	}
+        if(o instanceof URLClassLoader) {
+            LispObject list = NIL;
+            for(URL u : ((URLClassLoader) o).getURLs()) {
+                list = list.push(new Pathname(u));
+            }
+            return new Cons(new JavaObject(o), list.nreverse());
+        } else {
+            return new JavaObject(o);
+        }
     }
 
     public static ClassLoader getCurrentClassLoader() {
-	LispObject classLoader = CLASSLOADER.symbolValueNoThrow();
-	if(classLoader != null) {
-	    return (ClassLoader) classLoader.javaInstance(ClassLoader.class);
-	} else {
-	    return Lisp.class.getClassLoader();
-	}
+        LispObject classLoader = CLASSLOADER.symbolValueNoThrow();
+        if(classLoader != null) {
+            return (ClassLoader) classLoader.javaInstance(ClassLoader.class);
+        } else {
+            return Lisp.class.getClassLoader();
+        }
     }
 
 

Modified: trunk/abcl/src/org/armedbear/lisp/MemoryClassLoader.java
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/MemoryClassLoader.java	Sat Jul 21 07:02:32 2012	(r14014)
+++ trunk/abcl/src/org/armedbear/lisp/MemoryClassLoader.java	Mon Jul 23 04:58:34 2012	(r14015)
@@ -78,6 +78,13 @@
                 return c;
             }
         }
+        
+        if (checkPreCompiledClassLoader) {
+            Class<?> c = findPrecompiledClassOrNull(name);
+            if (c != null) {
+                return c;     
+            }
+        }
 
         // Fall through to our super's default handling
         return super.loadClass(name, resolve);
@@ -86,8 +93,13 @@
     @Override
     protected Class<?> findClass(String name) throws ClassNotFoundException {
         try {
+            if (checkPreCompiledClassLoader) {
+                Class<?> c = findPrecompiledClassOrNull(name);
+                if (c != null)
+                        return c;                       
+            }
             byte[] b = getFunctionClassBytes(name);
-            return defineClass(name, b, 0, b.length);
+            return defineLispClass(name, b, 0, b.length);
         } catch(Throwable e) { //TODO handle this better, readFunctionBytes uses Debug.assert() but should return null
             e.printStackTrace();
             if(e instanceof ControlTransfer) { throw (ControlTransfer) e; }
@@ -96,23 +108,17 @@
     }
 
     public byte[] getFunctionClassBytes(String name) {
-        return (byte[])hashtable.get(name).javaInstance();
-    }
-
-    public byte[] getFunctionClassBytes(Class<?> functionClass) {
-        return getFunctionClassBytes(functionClass.getName());
-    }
-
-    public byte[] getFunctionClassBytes(Function f) {
-        byte[] b = getFunctionClassBytes(f.getClass());
-        f.setClassBytes(b);
-        return b;
+        if (hashtable.containsKey(name)) {
+            return (byte[])hashtable.get(name).javaInstance();
+        }
+        return super.getFunctionClassBytes(name);
     }
 
     public LispObject loadFunction(String name) {
         try {
-            Function f = (Function) loadClass(name).newInstance();
-            f.setClassBytes(getFunctionClassBytes(name));
+            Class clz = loadClass(name);
+            Function f = (Function) clz.newInstance();
+            getFunctionClassBytes(f); //as a side effect it sets them
             return f;
         } catch(Throwable e) {
             if(e instanceof ControlTransfer) { throw (ControlTransfer) e; }
@@ -135,29 +141,28 @@
 
     private static final Primitive PUT_MEMORY_FUNCTION = new pf_put_memory_function();
     private static final class pf_put_memory_function extends Primitive {
-	pf_put_memory_function() {
+        pf_put_memory_function() {
             super("put-memory-function", PACKAGE_SYS, false, "loader class-name class-bytes");
         }
 
         @Override
         public LispObject execute(LispObject loader, LispObject className, LispObject classBytes) {
             MemoryClassLoader l = (MemoryClassLoader) loader.javaInstance(MemoryClassLoader.class);
-	    return (LispObject)l.hashtable.put(className.getStringValue(), (JavaObject)classBytes);
+            return (LispObject)l.hashtable.put(className.getStringValue(), (JavaObject)classBytes);
         }
     };
     
     private static final Primitive GET_MEMORY_FUNCTION = new pf_get_memory_function();
     private static final class pf_get_memory_function extends Primitive {
-	pf_get_memory_function() {
+        pf_get_memory_function() {
             super("get-memory-function", PACKAGE_SYS, false, "loader class-name");
         }
 
         @Override
         public LispObject execute(LispObject loader, LispObject name) {
             MemoryClassLoader l = (MemoryClassLoader) loader.javaInstance(MemoryClassLoader.class);
-	    return l.loadFunction(name.getStringValue());
+            return l.loadFunction(name.getStringValue());
         }
     };
+}
 
-
-}
\ No newline at end of file




More information about the armedbear-cvs mailing list