From 525a2f2f87b6bcd66f89fd64bd8a104015cf2535 Mon Sep 17 00:00:00 2001 From: Volker Berlin Date: Thu, 2 Jan 2020 15:15:21 +0100 Subject: [PATCH] change the static ClassFile cache to an instance cache --- .../inetsoftware/classparser/ClassFile.java | 27 ------------------- .../jwebassembly/module/ModuleGenerator.java | 16 +++++------ .../jwebassembly/module/TypeManager.java | 26 +++++++++--------- .../jwebassembly/module/WasmCodeBuilder.java | 7 +++-- .../jwebassembly/module/WatParserTest.java | 2 +- 5 files changed, 27 insertions(+), 51 deletions(-) diff --git a/src/de/inetsoftware/classparser/ClassFile.java b/src/de/inetsoftware/classparser/ClassFile.java index 4079e61..fa0332a 100644 --- a/src/de/inetsoftware/classparser/ClassFile.java +++ b/src/de/inetsoftware/classparser/ClassFile.java @@ -34,8 +34,6 @@ import de.inetsoftware.classparser.Attributes.AttributeInfo; */ public class ClassFile { - private static final WeakValueCache CACHE = new WeakValueCache<>(); - private final DataInputStream input; private final int minorVersion; @@ -64,30 +62,6 @@ public class ClassFile { private Map> annotations; - /** - * Get the ClassFile from cache or load it. - * - * @param className - * the class name - * @param loader - * the ClassLoader to load - * @return the ClassFile or null - * @throws IOException - * If any I/O error occur - */ - @Nullable - public static ClassFile get( String className, ClassLoader loader ) throws IOException { - ClassFile classFile = CACHE.get( className ); - if( classFile != null ) { - return classFile; - } - InputStream stream = loader.getResourceAsStream( className + ".class" ); - if( stream != null ) { - return new ClassFile( stream ); - } - return null; - } - /** * Load a class file and create a model of the class. * @@ -141,7 +115,6 @@ public class ClassFile { } } } - CACHE.put( thisClass.getName(), this ); } /** diff --git a/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java b/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java index 9abdfca..bd4e1f2 100644 --- a/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java +++ b/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java @@ -60,7 +60,7 @@ public class ModuleGenerator { private final JavaScriptWriter javaScript; - private final URLClassLoader libraries; + private final ClassFileLoader classFileLoader; private final JavaMethodWasmCodeBuilder javaCodeBuilder; @@ -93,12 +93,12 @@ public class ModuleGenerator { this.watParser = new WatParser(); this.writer = writer; this.javaScript = new JavaScriptWriter( target ); - this.libraries = new URLClassLoader( libraries.toArray( new URL[libraries.size()] ) ); + this.classFileLoader = new ClassFileLoader( new URLClassLoader( libraries.toArray( new URL[libraries.size()] ) ) ); WasmOptions options = writer.options; types.init( options ); strings.init( functions ); - javaCodeBuilder.init( types, functions, strings, options ); - ((WasmCodeBuilder)watParser).init( types, functions, strings, options ); + javaCodeBuilder.init( types, functions, strings, options, classFileLoader ); + ((WasmCodeBuilder)watParser).init( types, functions, strings, options, classFileLoader ); scanLibraries( libraries ); } @@ -173,7 +173,7 @@ public class ModuleGenerator { FunctionName next; NEXT: while( (next = functions.nextScannLater()) != null ) { - ClassFile classFile = ClassFile.get( next.className, libraries ); + ClassFile classFile = classFileLoader.get( next.className ); if( classFile == null ) { if( next instanceof SyntheticFunctionName ) { JWebAssembly.LOGGER.fine( '\t' + next.methodName + next.signature ); @@ -213,7 +213,7 @@ public class ModuleGenerator { continue NEXT; // we have found a super method } ConstantClass superClass = superClassFile.getSuperClass(); - superClassFile = superClass == null ? null : ClassFile.get( superClass.getName(), libraries ); + superClassFile = superClass == null ? null : classFileLoader.get( superClass.getName() ); } throw new WasmException( "Missing function: " + next.signatureName, -1 ); } @@ -257,7 +257,7 @@ public class ModuleGenerator { } JWebAssembly.LOGGER.fine( "scan finsih" ); - types.prepareFinish( writer, functions, libraries ); + types.prepareFinish( writer, functions, classFileLoader ); prepareFunctions(); // prepare of types can add some override methods as needed functions.prepareFinish(); strings.prepareFinish( writer ); @@ -304,7 +304,7 @@ public class ModuleGenerator { if( next instanceof SyntheticFunctionName ) { writeMethodImpl( next, true, ((SyntheticFunctionName)next).getCodeBuilder( watParser ) ); } else { - ClassFile classFile = ClassFile.get( next.className, libraries ); + ClassFile classFile = classFileLoader.get( next.className ); if( classFile == null ) { throw new WasmException( "Missing function: " + next.signatureName, -1 ); } else { diff --git a/src/de/inetsoftware/jwebassembly/module/TypeManager.java b/src/de/inetsoftware/jwebassembly/module/TypeManager.java index 28e8e64..52b3ad9 100644 --- a/src/de/inetsoftware/jwebassembly/module/TypeManager.java +++ b/src/de/inetsoftware/jwebassembly/module/TypeManager.java @@ -73,15 +73,15 @@ public class TypeManager { * the targets for the types * @param functions * the used functions for the vtables of the types - * @param libraries - * for loading the class files if not in the cache + * @param classFileLoader + * for loading the class files * @throws IOException * if any I/O error occur on loading or writing */ - void prepareFinish( ModuleWriter writer, FunctionManager functions, ClassLoader libraries ) throws IOException { + void prepareFinish( ModuleWriter writer, FunctionManager functions, ClassFileLoader classFileLoader ) throws IOException { isFinish = true; for( StructType type : structTypes.values() ) { - type.writeStructType( writer, functions, this, libraries ); + type.writeStructType( writer, functions, this, classFileLoader ); } } @@ -195,17 +195,17 @@ public class TypeManager { * the used functions for the vtables of the types * @param types * for types of fields - * @param libraries - * for loading the class files if not in the cache + * @param classFileLoader + * for loading the class files * @throws IOException * if any I/O error occur on loading or writing */ - private void writeStructType( ModuleWriter writer, FunctionManager functions, TypeManager types, ClassLoader libraries ) throws IOException { + private void writeStructType( ModuleWriter writer, FunctionManager functions, TypeManager types, ClassFileLoader classFileLoader ) throws IOException { JWebAssembly.LOGGER.fine( "write type: " + name ); fields = new ArrayList<>(); methods = new ArrayList<>(); HashSet allNeededFields = new HashSet<>(); - listStructFields( name, functions, types, libraries, allNeededFields ); + listStructFields( name, functions, types, classFileLoader, allNeededFields ); code = writer.writeStructType( this ); } @@ -218,15 +218,15 @@ public class TypeManager { * the used functions for the vtables of the types * @param types * for types of fields - * @param libraries - * for loading the class files if not in the cache + * @param classFileLoader + * for loading the class files * @param allNeededFields * for recursive call list this all used fields * @throws IOException * if any I/O error occur on loading or writing */ - private void listStructFields( String className, FunctionManager functions, TypeManager types, ClassLoader libraries, HashSet allNeededFields ) throws IOException { - ClassFile classFile = ClassFile.get( className, libraries ); + private void listStructFields( String className, FunctionManager functions, TypeManager types, ClassFileLoader classFileLoader, HashSet allNeededFields ) throws IOException { + ClassFile classFile = classFileLoader.get( className ); if( classFile == null ) { throw new WasmException( "Missing class: " + className, -1 ); } @@ -242,7 +242,7 @@ public class TypeManager { ConstantClass superClass = classFile.getSuperClass(); if( superClass != null ) { String superClassName = superClass.getName(); - listStructFields( superClassName, functions, types, libraries, allNeededFields ); + listStructFields( superClassName, functions, types, classFileLoader, allNeededFields ); } else { fields.add( new NamedStorageType( ValueType.i32, className, VTABLE ) ); } diff --git a/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java b/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java index c1d06f3..5524fa7 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java @@ -68,6 +68,8 @@ public abstract class WasmCodeBuilder { private StringManager strings; + private ClassFileLoader classFileLoader; + /** * Initialize the code builder; * @@ -80,12 +82,13 @@ public abstract class WasmCodeBuilder { * @param options * compiler properties */ - void init( TypeManager types, FunctionManager functions, StringManager strings, WasmOptions options ) { + void init( TypeManager types, FunctionManager functions, StringManager strings, WasmOptions options, ClassFileLoader classFileLoader ) { this.localVariables.init( types ); this.types = types; this.functions = functions; this.strings = strings; this.options = options; + this.classFileLoader = classFileLoader; } /** @@ -535,7 +538,7 @@ public abstract class WasmCodeBuilder { */ private FunctionName getNonGC( String name, int lineNumber ) { try { - ClassFile classFile = ClassFile.get( NonGC.class.getName().replace( '.', '/' ), getClass().getClassLoader() ); + ClassFile classFile = classFileLoader.get( NonGC.class.getName().replace( '.', '/' ) ); for( MethodInfo method : classFile.getMethods() ) { if( name.equals( method.getName() ) ) { return new FunctionName( method ); diff --git a/test/de/inetsoftware/jwebassembly/module/WatParserTest.java b/test/de/inetsoftware/jwebassembly/module/WatParserTest.java index 19aa484..ee3ca05 100644 --- a/test/de/inetsoftware/jwebassembly/module/WatParserTest.java +++ b/test/de/inetsoftware/jwebassembly/module/WatParserTest.java @@ -40,7 +40,7 @@ public class WatParserTest { WasmOptions options = new WasmOptions( new HashMap<>() ); WatParser parser = new WatParser(); WasmCodeBuilder codeBuilder = parser; - codeBuilder.init( null, null, null, options ); + codeBuilder.init( null, null, null, options, null ); parser.parse( wat, null, 100 ); StringBuilder builder = new StringBuilder(); ModuleWriter writer = new TextModuleWriter( new WasmTarget( builder ), options );