< prev index next >

test/compiler/jvmci/common/CTVMUtilities.java

Print this page
rev 9261 : 8138815: improve tests CompilerToVM::getStackTraceElement

*** 21,34 **** --- 21,49 ---- * 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,74 **** --- 84,158 ---- 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 >