package com.oracle.svm.hosted.agent;
import static jdk.internal.org.objectweb.asm.ClassReader.EXPAND_FRAMES;
import static jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES;
import static jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_MAXS;
import java.lang.instrument.Instrumentation;
import com.oracle.svm.hosted.agent.jdk8.lambda.LambdaMetaFactoryRewriteVisitor;
import com.oracle.svm.util.AgentSupport;
import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.internal.org.objectweb.asm.ClassWriter;
@SuppressWarnings({"Anonymous2MethodRef", "Convert2Lambda"})
public class NativeImageBytecodeInstrumentationAgent {
private static TracingAdvisor advisor;
@SuppressWarnings({"unused", "Convert2Lambda"})
public static void premain(String agentArgs, Instrumentation inst) {
if (getJavaVersion() == 8) {
inst.addTransformer(AgentSupport.createClassInstrumentationTransformer(NativeImageBytecodeInstrumentationAgent::applyRewriteLambdasTransformation));
}
if (agentArgs != null && !agentArgs.isEmpty()) {
advisor = new TracingAdvisor(agentArgs);
inst.addTransformer(AgentSupport.createClassInstrumentationTransformer(NativeImageBytecodeInstrumentationAgent::applyInitializationTrackingTransformation));
}
}
private static byte[] applyInitializationTrackingTransformation(@SuppressWarnings("unused") String moduleName, @SuppressWarnings("unused") ClassLoader loader, String className,
byte[] classfileBuffer) {
if (advisor.shouldTraceClassInitialization(className)) {
ClassReader reader = new ClassReader(classfileBuffer);
ClassWriter writer = new ClassWriter(reader, COMPUTE_FRAMES);
ClinitGenerationVisitor visitor = new ClinitGenerationVisitor(writer);
reader.accept(visitor, 0);
return writer.toByteArray();
} else {
return classfileBuffer;
}
}
@SuppressWarnings("unused")
private static byte[] applyRewriteLambdasTransformation(String moduleName, ClassLoader loader, String className, byte[] classfileBuffer) {
ClassReader reader = new ClassReader(classfileBuffer);
ClassWriter writer = new ClassWriter(reader, COMPUTE_MAXS);
LambdaMetaFactoryRewriteVisitor visitor = new LambdaMetaFactoryRewriteVisitor(loader, className, writer);
reader.accept(visitor, EXPAND_FRAMES);
return writer.toByteArray();
}
public static int getJavaVersion() {
String version = System.getProperty("java.version");
if (version.startsWith("1.")) {
version = version.substring(2, 3);
} else {
int dot = version.indexOf(".");
if (dot != -1) {
version = version.substring(0, dot);
}
int dash = version.indexOf("-");
if (dash != -1) {
version = version.substring(0, dash);
}
}
return Integer.parseInt(version);
}
}