Commit a43262a8 authored by Vít Kabele's avatar Vít Kabele

IsolatedSnippetParser now takes advance of session-local classloader.

Targeting #7
parent e3c881bf
Pipeline #3320 passed with stages
in 3 minutes and 52 seconds
......@@ -11,7 +11,6 @@ package ch.usi.dag.disl;
import org.objectweb.asm.tree.ClassNode;
import java.util.List;
import java.util.Map;
import java.util.Set;
......@@ -33,7 +32,7 @@ class IsolatedDislClasses extends DislClasses {
IsolatedDislClasses(
final Set<DiSL.CodeOption> options,
final List<ClassNode> classNodes,
final Map<String, byte[]> allClasses,
final List<ClassNode> allClasses,
final ClassLoader classLoader
)
throws ParserException,
......
......@@ -3,29 +3,31 @@
* Author: Vit Kabele <vit@kabele.me>
* Created on the 02/11/2018
*/
package ch.usi.dag.disl;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.ClassNode;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Load snippets using provided class bytes list.
* Load snippets using provided {@link ClassNode} list.
*/
class IsolatedSnippetParser extends SnippetParser {
/**
* Provided class bytes list
* Map of all available classes in instrumentation.
* The key here is binary name of the class as defined by The Java(TM) Language Specification.
*/
private final Map<String, byte[]> allClasses;
private final Map<String, ClassNode> allClasses = new HashMap<> ();
/**
* Guard cache to prevent attempts to reload a class multiple times.
* DiSL session {@link ClassLoader} instance.
*/
private final Map<String, Class<?>> guardCache = new ConcurrentHashMap<> ();
private final ClassLoader classLoader;
......@@ -34,10 +36,12 @@ class IsolatedSnippetParser extends SnippetParser {
* @param allClasses
*/
IsolatedSnippetParser(
final Map<String, byte[]> allClasses,
final List<ClassNode> allClasses,
final ClassLoader classLoader
){
this.allClasses = allClasses;
for(ClassNode classNode : allClasses){
this.allClasses.put ( classNode.name.replace ('/', '.'), classNode );
}
this.classLoader = classLoader;
}
......@@ -51,22 +55,14 @@ class IsolatedSnippetParser extends SnippetParser {
*/
@Override
Class<?> getGuard (final Type guardType) throws Reflection.MissingClassException {
if(guardType == null) return null;
final String guardName = guardType.getClassName ();
// If the class definition is already in cache, return the cached value
if ( guardCache.containsKey (guardName) )
return guardCache.get (guardName);
if ( !allClasses.containsKey (guardName + ".class") )
if ( !allClasses.containsKey (guardName) )
throw new Reflection.MissingClassException ("Requested class not found %", guardName);
final Class<?> c = classLoader.createClass (guardName, allClasses.get(guardName + ".class"));
guardCache.put (guardName, c);
return c;
return classLoader.getClass (allClasses.get(guardName));
}
}
......@@ -27,7 +27,7 @@ class ClassLoader extends java.lang.ClassLoader {
/**
* Returns an class definition from given byte array.
* @param name Class name.
* @param name Binary name of the class as defined by The Java(TM) Language Specification.
* @param classBytes Class bytes.
* @param offset Offset in array.
* @param length Length of class data.
......@@ -41,7 +41,7 @@ class ClassLoader extends java.lang.ClassLoader {
/**
* Returns an class definition from given byte array,
* using whole array as class bytes.
* @param name Class name.
* @param name Binary name of the class as defined by The Java(TM) Language Specification.
* @param classBytes Class bytes.
* @return Appropriate instance of the class.
*/
......@@ -51,7 +51,7 @@ class ClassLoader extends java.lang.ClassLoader {
/**
* Returns an class definition from given {@link ClassNode} instance.
* Creates class definition from given {@link ClassNode} instance.
* @param classNode Class node.
* @return Class definition.
*/
......@@ -61,7 +61,34 @@ class ClassLoader extends java.lang.ClassLoader {
classNode.accept (classWriter);
return createClass ( classNode.name, classWriter.toByteArray () );
return createClass ( getBinaryName (classNode), classWriter.toByteArray () );
}
/**
* Returns the loaded class definition for given {@link ClassNode}
* If the class is not yet loaded, it will be.
*
* @param classNode Class node.
* @return Class definition.
*/
Class<?> getClass(final ClassNode classNode){
final String binaryName = getBinaryName (classNode);
final Class<?> loadedClass = findLoadedClass (binaryName);
return (loadedClass != null) ? loadedClass : createClass (classNode);
}
/**
* Returns the binary name of the class as defined by The Java(TM) Language Specification.
* @param classNode ClassNode
* @return Binary name of the class as defined by The Java(TM) Language Specification.
*/
private static String getBinaryName(final ClassNode classNode){
return classNode.name.replace ('/', '.');
}
}
......@@ -188,12 +188,10 @@ public final class DiSL {
.flatMap ( i -> i.getTransformers ().stream () )
.collect (Collectors.toList ());
final Map<String, byte[]> allClasses = instrumentationJars
final List<ClassNode> allClasses = instrumentationJars
.stream ()
.map (InstrumentationJar::getAllClasses)
.map (Map::entrySet)
.flatMap (Collection::stream)
.collect ( Collectors.toMap (Map.Entry::getKey, Map.Entry::getValue) );
.flatMap (i -> i.allClasses ().stream ())
.collect (Collectors.toList ());
__dislClasses = new IsolatedDislClasses (__codeOptions, classNodes, allClasses, __classLoader);
__transformers = new IsolatedTransformers ( transformerList, __classLoader );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment