< prev index next >
test/compiler/jvmci/common/CTVMUtilities.java
Print this page
rev 9261 : 8138815: improve tests CompilerToVM::getStackTraceElement
@@ -21,14 +21,29 @@
* questions.
*/
package compiler.jvmci.common;
+import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Executable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Parameter;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+
+import jdk.internal.org.objectweb.asm.ClassReader;
+import jdk.internal.org.objectweb.asm.ClassVisitor;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.Label;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.org.objectweb.asm.tree.ClassNode;
+import jdk.test.lib.Utils;
import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
public class CTVMUtilities {
@@ -69,6 +84,75 @@
super(name);
this.address = address;
this.entryPoint = entryPoint;
}
}
+ public static Map<Integer, Integer> getBciToLineNumber(Executable method) {
+ Map<Integer, Integer> lineNumbers = new TreeMap<>();
+ try {
+ ClassReader cr = new ClassReader(method.getDeclaringClass()
+ .getName());
+ ClassNode cn = new ClassNode();
+ cr.accept(cn, ClassReader.EXPAND_FRAMES);
+
+ Map<Label, Integer> labels = new HashMap<>();
+ ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+ ClassVisitor cv = new ClassVisitorForLabels(cw, labels, method);
+ cr.accept(cv, ClassReader.EXPAND_FRAMES);
+ labels.forEach((k, v) -> lineNumbers.put(k.getOffset(), v));
+ } catch (IOException e) {
+ throw new Error("TEST BUG " + e, e);
+ }
+ boolean isEmptyMethod = Modifier.isAbstract(method.getModifiers())
+ || Modifier.isNative(method.getModifiers());
+ if (lineNumbers.isEmpty() && !isEmptyMethod) {
+ throw new Error(method + " doesn't contains the line numbers table "
+ +"(the method marked neither abstract nor native)");
+ }
+ return lineNumbers;
+ }
+
+ private static class ClassVisitorForLabels extends ClassVisitor {
+ private final Map<Label, Integer> lineNumbers;
+ private final String targetName;
+ private final String targetDesc;
+
+ public ClassVisitorForLabels(ClassWriter cw, Map<Label, Integer> lines,
+ Executable target) {
+ super(Opcodes.ASM5, cw);
+ this.lineNumbers = lines;
+
+ StringBuilder builder = new StringBuilder("(");
+ for (Parameter parameter : target.getParameters()) {
+ builder.append(Utils.toJVMTypeSignature(parameter.getType()));
+ }
+ builder.append(")");
+ if (target instanceof Constructor) {
+ targetName = "<init>";
+ builder.append("V");
+ } else {
+ targetName = target.getName();
+ builder.append(Utils.toJVMTypeSignature(
+ ((Method) target).getReturnType()));
+ }
+ targetDesc = builder.toString();
+ }
+
+ @Override
+ public final MethodVisitor visitMethod(int access, String name,
+ String desc, String signature,
+ String[] exceptions) {
+ MethodVisitor mv = cv.visitMethod(access, name, desc, signature,
+ exceptions);
+ if (targetDesc.equals(desc) && targetName.equals(name)) {
+ return new MethodVisitor(Opcodes.ASM5, mv) {
+ @Override
+ public void visitLineNumber(int i, Label label) {
+ super.visitLineNumber(i, label);
+ lineNumbers.put(label, i);
+ }
+ };
+ }
+ return mv;
+ }
+ }
}
< prev index next >