Skip to content

Commit

Permalink
AccessClassLoader - short-circuit class lookups for access classes th…
Browse files Browse the repository at this point in the history
…at have not yet been generated
  • Loading branch information
lytles@takashi committed Sep 28, 2016
1 parent fba5d5e commit d13b3f7
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 9 deletions.
14 changes: 14 additions & 0 deletions src/com/esotericsoftware/reflectasm/AccessClassLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
import java.security.ProtectionDomain;
import java.util.HashSet;
import java.util.WeakHashMap;

class AccessClassLoader extends ClassLoader {
Expand Down Expand Up @@ -82,6 +83,19 @@ private AccessClassLoader (ClassLoader parent) {
super(parent);
}

HashSet<String> locals = new HashSet<String>();
java.lang.Class<?> loadClassLocal(String name) throws ClassNotFoundException {
if (locals.contains(name))
return loadClass(name,false);
else
throw new ClassNotFoundException();
}
Class<?> defineClassLocal(String name, byte[] bytes) throws ClassFormatError {
locals.add(name);
return defineClass(name,bytes);
}


protected java.lang.Class<?> loadClass (String name, boolean resolve) throws ClassNotFoundException {
// These classes come from the classloader that loaded AccessClassLoader.
if (name.equals(FieldAccess.class.getName())) return FieldAccess.class;
Expand Down
6 changes: 3 additions & 3 deletions src/com/esotericsoftware/reflectasm/ConstructorAccess.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ static public <T> ConstructorAccess<T> get (Class<T> type) {

AccessClassLoader loader = AccessClassLoader.get(type);
try {
accessClass = loader.loadClass(accessClassName);
accessClass = loader.loadClassLocal(accessClassName);
} catch (ClassNotFoundException ignored) {
synchronized (loader) {
try {
accessClass = loader.loadClass(accessClassName);
accessClass = loader.loadClassLocal(accessClassName);
} catch (ClassNotFoundException ignored2) {
String accessClassNameInternal = accessClassName.replace('.', '/');
String classNameInternal = className.replace('.', '/');
Expand Down Expand Up @@ -100,7 +100,7 @@ static public <T> ConstructorAccess<T> get (Class<T> type) {
insertNewInstanceInner(cw, classNameInternal, enclosingClassNameInternal);

cw.visitEnd();
accessClass = loader.defineClass(accessClassName, cw.toByteArray());
accessClass = loader.defineClassLocal(accessClassName, cw.toByteArray());
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/com/esotericsoftware/reflectasm/FieldAccess.java
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,11 @@ static public FieldAccess get (Class type) {

AccessClassLoader loader = AccessClassLoader.get(type);
try {
accessClass = loader.loadClass(accessClassName);
accessClass = loader.loadClassLocal(accessClassName);
} catch (ClassNotFoundException ignored) {
synchronized (loader) {
try {
accessClass = loader.loadClass(accessClassName);
accessClass = loader.loadClassLocal(accessClassName);
} catch (ClassNotFoundException ignored2) {
String accessClassNameInternal = accessClassName.replace('.', '/');
String classNameInternal = className.replace('.', '/');
Expand Down Expand Up @@ -155,7 +155,7 @@ static public FieldAccess get (Class type) {
insertSetPrimitive(cw, classNameInternal, fields, Type.CHAR_TYPE);
insertGetString(cw, classNameInternal, fields);
cw.visitEnd();
accessClass = loader.defineClass(accessClassName, cw.toByteArray());
accessClass = loader.defineClassLocal(accessClassName, cw.toByteArray());
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/com/esotericsoftware/reflectasm/MethodAccess.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,11 @@ static public MethodAccess get (Class type) {

AccessClassLoader loader = AccessClassLoader.get(type);
try {
accessClass = loader.loadClass(accessClassName);
accessClass = loader.loadClassLocal(accessClassName);
} catch (ClassNotFoundException ignored) {
synchronized (loader) {
try {
accessClass = loader.loadClass(accessClassName);
accessClass = loader.loadClassLocal(accessClassName);
} catch (ClassNotFoundException ignored2) {
String accessClassNameInternal = accessClassName.replace('.', '/');
String classNameInternal = className.replace('.', '/');
Expand Down Expand Up @@ -272,7 +272,7 @@ else if (Modifier.isStatic(methods.get(i).getModifiers()))
}
cw.visitEnd();
byte[] data = cw.toByteArray();
accessClass = loader.defineClass(accessClassName, data);
accessClass = loader.defineClassLocal(accessClassName, data);
}
}
}
Expand Down

0 comments on commit d13b3f7

Please sign in to comment.