diff options
Diffstat (limited to 'src/partest-javaagent/scala/tools/partest/javaagent/ASMTransformer.java')
-rw-r--r-- | src/partest-javaagent/scala/tools/partest/javaagent/ASMTransformer.java | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/src/partest-javaagent/scala/tools/partest/javaagent/ASMTransformer.java b/src/partest-javaagent/scala/tools/partest/javaagent/ASMTransformer.java new file mode 100644 index 0000000000..86f5e64516 --- /dev/null +++ b/src/partest-javaagent/scala/tools/partest/javaagent/ASMTransformer.java @@ -0,0 +1,49 @@ +/* NEST (New Scala Test) + * Copyright 2007-2013 LAMP/EPFL + * @author Grzegorz Kossakowski + */ + +package scala.tools.partest.javaagent; + +import java.lang.instrument.ClassFileTransformer; +import java.security.ProtectionDomain; + +import scala.tools.asm.ClassReader; +import scala.tools.asm.ClassWriter; + +public class ASMTransformer implements ClassFileTransformer { + + private boolean shouldTransform(String className) { + return + // do not instrument instrumentation logic (in order to avoid infinite recursion) + !className.startsWith("scala/tools/partest/instrumented/") && + !className.startsWith("scala/tools/partest/javaagent/") && + // we instrument all classes from empty package + (!className.contains("/") || + // we instrument all classes from scala package + className.startsWith("scala/") || + // we instrument all classes from `instrumented` package + className.startsWith("instrumented/")); + } + + public byte[] transform(final ClassLoader classLoader, final String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) { + if (shouldTransform(className)) { + ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS) { + @Override protected String getCommonSuperClass(final String type1, final String type2) { + // Since we are not recomputing stack frame map, this should never be called we override this method because + // default implementation uses reflection for implementation and might try to load the class that we are + // currently processing. That leads to weird results like swallowed exceptions and classes being not + // transformed. + throw new RuntimeException("Unexpected call to getCommonSuperClass(" + type1 + ", " + type2 + + ") while transforming " + className); + } + }; + ProfilerVisitor visitor = new ProfilerVisitor(writer); + ClassReader reader = new ClassReader(classfileBuffer); + reader.accept(visitor, 0); + return writer.toByteArray(); + } else { + return classfileBuffer; + } + } +} |