change the static ClassFile cache to an instance cache

This commit is contained in:
Volker Berlin 2020-01-02 15:15:21 +01:00
parent f32a1ac067
commit 525a2f2f87
5 changed files with 27 additions and 51 deletions

View File

@ -34,8 +34,6 @@ import de.inetsoftware.classparser.Attributes.AttributeInfo;
*/ */
public class ClassFile { public class ClassFile {
private static final WeakValueCache<String,ClassFile> CACHE = new WeakValueCache<>();
private final DataInputStream input; private final DataInputStream input;
private final int minorVersion; private final int minorVersion;
@ -64,30 +62,6 @@ public class ClassFile {
private Map<String,Map<String,Object>> annotations; private Map<String,Map<String,Object>> 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. * Load a class file and create a model of the class.
* *
@ -141,7 +115,6 @@ public class ClassFile {
} }
} }
} }
CACHE.put( thisClass.getName(), this );
} }
/** /**

View File

@ -60,7 +60,7 @@ public class ModuleGenerator {
private final JavaScriptWriter javaScript; private final JavaScriptWriter javaScript;
private final URLClassLoader libraries; private final ClassFileLoader classFileLoader;
private final JavaMethodWasmCodeBuilder javaCodeBuilder; private final JavaMethodWasmCodeBuilder javaCodeBuilder;
@ -93,12 +93,12 @@ public class ModuleGenerator {
this.watParser = new WatParser(); this.watParser = new WatParser();
this.writer = writer; this.writer = writer;
this.javaScript = new JavaScriptWriter( target ); 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; WasmOptions options = writer.options;
types.init( options ); types.init( options );
strings.init( functions ); strings.init( functions );
javaCodeBuilder.init( types, functions, strings, options ); javaCodeBuilder.init( types, functions, strings, options, classFileLoader );
((WasmCodeBuilder)watParser).init( types, functions, strings, options ); ((WasmCodeBuilder)watParser).init( types, functions, strings, options, classFileLoader );
scanLibraries( libraries ); scanLibraries( libraries );
} }
@ -173,7 +173,7 @@ public class ModuleGenerator {
FunctionName next; FunctionName next;
NEXT: NEXT:
while( (next = functions.nextScannLater()) != null ) { while( (next = functions.nextScannLater()) != null ) {
ClassFile classFile = ClassFile.get( next.className, libraries ); ClassFile classFile = classFileLoader.get( next.className );
if( classFile == null ) { if( classFile == null ) {
if( next instanceof SyntheticFunctionName ) { if( next instanceof SyntheticFunctionName ) {
JWebAssembly.LOGGER.fine( '\t' + next.methodName + next.signature ); JWebAssembly.LOGGER.fine( '\t' + next.methodName + next.signature );
@ -213,7 +213,7 @@ public class ModuleGenerator {
continue NEXT; // we have found a super method continue NEXT; // we have found a super method
} }
ConstantClass superClass = superClassFile.getSuperClass(); 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 ); throw new WasmException( "Missing function: " + next.signatureName, -1 );
} }
@ -257,7 +257,7 @@ public class ModuleGenerator {
} }
JWebAssembly.LOGGER.fine( "scan finsih" ); 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 prepareFunctions(); // prepare of types can add some override methods as needed
functions.prepareFinish(); functions.prepareFinish();
strings.prepareFinish( writer ); strings.prepareFinish( writer );
@ -304,7 +304,7 @@ public class ModuleGenerator {
if( next instanceof SyntheticFunctionName ) { if( next instanceof SyntheticFunctionName ) {
writeMethodImpl( next, true, ((SyntheticFunctionName)next).getCodeBuilder( watParser ) ); writeMethodImpl( next, true, ((SyntheticFunctionName)next).getCodeBuilder( watParser ) );
} else { } else {
ClassFile classFile = ClassFile.get( next.className, libraries ); ClassFile classFile = classFileLoader.get( next.className );
if( classFile == null ) { if( classFile == null ) {
throw new WasmException( "Missing function: " + next.signatureName, -1 ); throw new WasmException( "Missing function: " + next.signatureName, -1 );
} else { } else {

View File

@ -73,15 +73,15 @@ public class TypeManager {
* the targets for the types * the targets for the types
* @param functions * @param functions
* the used functions for the vtables of the types * the used functions for the vtables of the types
* @param libraries * @param classFileLoader
* for loading the class files if not in the cache * for loading the class files
* @throws IOException * @throws IOException
* if any I/O error occur on loading or writing * 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; isFinish = true;
for( StructType type : structTypes.values() ) { 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 * the used functions for the vtables of the types
* @param types * @param types
* for types of fields * for types of fields
* @param libraries * @param classFileLoader
* for loading the class files if not in the cache * for loading the class files
* @throws IOException * @throws IOException
* if any I/O error occur on loading or writing * 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 ); JWebAssembly.LOGGER.fine( "write type: " + name );
fields = new ArrayList<>(); fields = new ArrayList<>();
methods = new ArrayList<>(); methods = new ArrayList<>();
HashSet<String> allNeededFields = new HashSet<>(); HashSet<String> allNeededFields = new HashSet<>();
listStructFields( name, functions, types, libraries, allNeededFields ); listStructFields( name, functions, types, classFileLoader, allNeededFields );
code = writer.writeStructType( this ); code = writer.writeStructType( this );
} }
@ -218,15 +218,15 @@ public class TypeManager {
* the used functions for the vtables of the types * the used functions for the vtables of the types
* @param types * @param types
* for types of fields * for types of fields
* @param libraries * @param classFileLoader
* for loading the class files if not in the cache * for loading the class files
* @param allNeededFields * @param allNeededFields
* for recursive call list this all used fields * for recursive call list this all used fields
* @throws IOException * @throws IOException
* if any I/O error occur on loading or writing * if any I/O error occur on loading or writing
*/ */
private void listStructFields( String className, FunctionManager functions, TypeManager types, ClassLoader libraries, HashSet<String> allNeededFields ) throws IOException { private void listStructFields( String className, FunctionManager functions, TypeManager types, ClassFileLoader classFileLoader, HashSet<String> allNeededFields ) throws IOException {
ClassFile classFile = ClassFile.get( className, libraries ); ClassFile classFile = classFileLoader.get( className );
if( classFile == null ) { if( classFile == null ) {
throw new WasmException( "Missing class: " + className, -1 ); throw new WasmException( "Missing class: " + className, -1 );
} }
@ -242,7 +242,7 @@ public class TypeManager {
ConstantClass superClass = classFile.getSuperClass(); ConstantClass superClass = classFile.getSuperClass();
if( superClass != null ) { if( superClass != null ) {
String superClassName = superClass.getName(); String superClassName = superClass.getName();
listStructFields( superClassName, functions, types, libraries, allNeededFields ); listStructFields( superClassName, functions, types, classFileLoader, allNeededFields );
} else { } else {
fields.add( new NamedStorageType( ValueType.i32, className, VTABLE ) ); fields.add( new NamedStorageType( ValueType.i32, className, VTABLE ) );
} }

View File

@ -68,6 +68,8 @@ public abstract class WasmCodeBuilder {
private StringManager strings; private StringManager strings;
private ClassFileLoader classFileLoader;
/** /**
* Initialize the code builder; * Initialize the code builder;
* *
@ -80,12 +82,13 @@ public abstract class WasmCodeBuilder {
* @param options * @param options
* compiler properties * 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.localVariables.init( types );
this.types = types; this.types = types;
this.functions = functions; this.functions = functions;
this.strings = strings; this.strings = strings;
this.options = options; this.options = options;
this.classFileLoader = classFileLoader;
} }
/** /**
@ -535,7 +538,7 @@ public abstract class WasmCodeBuilder {
*/ */
private FunctionName getNonGC( String name, int lineNumber ) { private FunctionName getNonGC( String name, int lineNumber ) {
try { try {
ClassFile classFile = ClassFile.get( NonGC.class.getName().replace( '.', '/' ), getClass().getClassLoader() ); ClassFile classFile = classFileLoader.get( NonGC.class.getName().replace( '.', '/' ) );
for( MethodInfo method : classFile.getMethods() ) { for( MethodInfo method : classFile.getMethods() ) {
if( name.equals( method.getName() ) ) { if( name.equals( method.getName() ) ) {
return new FunctionName( method ); return new FunctionName( method );

View File

@ -40,7 +40,7 @@ public class WatParserTest {
WasmOptions options = new WasmOptions( new HashMap<>() ); WasmOptions options = new WasmOptions( new HashMap<>() );
WatParser parser = new WatParser(); WatParser parser = new WatParser();
WasmCodeBuilder codeBuilder = parser; WasmCodeBuilder codeBuilder = parser;
codeBuilder.init( null, null, null, options ); codeBuilder.init( null, null, null, options, null );
parser.parse( wat, null, 100 ); parser.parse( wat, null, 100 );
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
ModuleWriter writer = new TextModuleWriter( new WasmTarget( builder ), options ); ModuleWriter writer = new TextModuleWriter( new WasmTarget( builder ), options );