[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