improve the caching of parsed class files

This commit is contained in:
Volker Berlin 2020-01-07 19:54:05 +01:00
parent 3dbca800bb
commit 8d37faa81d
2 changed files with 35 additions and 0 deletions

View File

@ -20,6 +20,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.HashMap; import java.util.HashMap;
import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import de.inetsoftware.classparser.ClassFile; import de.inetsoftware.classparser.ClassFile;
@ -38,6 +39,8 @@ public class ClassFileLoader {
private final ClassLoader loader; private final ClassLoader loader;
private final ClassLoader bootLoader;
/** /**
* Create a new instance * Create a new instance
* *
@ -46,6 +49,15 @@ public class ClassFileLoader {
*/ */
public ClassFileLoader( ClassLoader loader ) { public ClassFileLoader( ClassLoader loader ) {
this.loader = loader; this.loader = loader;
ClassLoader cl = ClassLoader.getSystemClassLoader();
do {
ClassLoader parent = cl.getParent();
if( parent == null ) {
bootLoader = cl;
break;
}
cl = parent;
} while( true );
} }
/** /**
@ -65,16 +77,38 @@ public class ClassFileLoader {
} }
classFile = weakCache.get( className ); classFile = weakCache.get( className );
if( classFile != null ) { if( classFile != null ) {
if( "java/lang/String".equals( className ) ) {
System.err.println( className + " from cache" );
}
return classFile; return classFile;
} }
InputStream stream = loader.getResourceAsStream( className + ".class" ); InputStream stream = loader.getResourceAsStream( className + ".class" );
if( stream != null ) { if( stream != null ) {
if( "java/lang/String".equals( className ) ) {
System.err.println( className + " from URL " + loader.getResource( className + ".class" ) );
}
classFile = new ClassFile( stream ); classFile = new ClassFile( stream );
weakCache.put( className, classFile ); weakCache.put( className, classFile );
} }
return classFile; return classFile;
} }
/**
* Add a class file to the weak cache.
*
* @param classFile
* the class file
*/
public void cache( @Nonnull ClassFile classFile ) {
String name = classFile.getThisClass().getName();
if( bootLoader.getResource( name + ".class" ) != null ) {
// if the same resource is exist in the JVM self then we need to hold the reference permanently
replace.put( name, classFile );
} else {
weakCache.put( name, classFile );
}
}
/** /**
* Replace the class in the cache with the given instance. * Replace the class in the cache with the given instance.
* *

View File

@ -162,6 +162,7 @@ public class ModuleGenerator {
* if any I/O error occur * if any I/O error occur
*/ */
public void prepare( ClassFile classFile ) throws IOException { public void prepare( ClassFile classFile ) throws IOException {
classFileLoader.cache( classFile );
// check if this class replace another class // check if this class replace another class
Map<String,Object> annotationValues; Map<String,Object> annotationValues;
if( (annotationValues = classFile.getAnnotation( JWebAssembly.REPLACE_ANNOTATION )) != null ) { if( (annotationValues = classFile.getAnnotation( JWebAssembly.REPLACE_ANNOTATION )) != null ) {