From 8d37faa81dc930849188175402f7945810069dfb Mon Sep 17 00:00:00 2001 From: Volker Berlin Date: Tue, 7 Jan 2020 19:54:05 +0100 Subject: [PATCH] improve the caching of parsed class files --- .../jwebassembly/module/ClassFileLoader.java | 34 +++++++++++++++++++ .../jwebassembly/module/ModuleGenerator.java | 1 + 2 files changed, 35 insertions(+) diff --git a/src/de/inetsoftware/jwebassembly/module/ClassFileLoader.java b/src/de/inetsoftware/jwebassembly/module/ClassFileLoader.java index 6773714..772a583 100644 --- a/src/de/inetsoftware/jwebassembly/module/ClassFileLoader.java +++ b/src/de/inetsoftware/jwebassembly/module/ClassFileLoader.java @@ -20,6 +20,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.HashMap; +import javax.annotation.Nonnull; import javax.annotation.Nullable; import de.inetsoftware.classparser.ClassFile; @@ -38,6 +39,8 @@ public class ClassFileLoader { private final ClassLoader loader; + private final ClassLoader bootLoader; + /** * Create a new instance * @@ -46,6 +49,15 @@ public class ClassFileLoader { */ public ClassFileLoader( ClassLoader 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 ); if( classFile != null ) { + if( "java/lang/String".equals( className ) ) { + System.err.println( className + " from cache" ); + } return classFile; } InputStream stream = loader.getResourceAsStream( className + ".class" ); if( stream != null ) { + if( "java/lang/String".equals( className ) ) { + System.err.println( className + " from URL " + loader.getResource( className + ".class" ) ); + } classFile = new ClassFile( stream ); weakCache.put( className, 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. * diff --git a/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java b/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java index 5b62159..a6b95dd 100644 --- a/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java +++ b/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java @@ -162,6 +162,7 @@ public class ModuleGenerator { * if any I/O error occur */ public void prepare( ClassFile classFile ) throws IOException { + classFileLoader.cache( classFile ); // check if this class replace another class Map annotationValues; if( (annotationValues = classFile.getAnnotation( JWebAssembly.REPLACE_ANNOTATION )) != null ) {