Skip to content

Commit 1f6d38f

Browse files
liachasotona
authored andcommitted
8294978: Convert 5 test/jdk/jdk/jfr tests from ASM library to Classfile API
Reviewed-by: asotona
1 parent c60474b commit 1f6d38f

File tree

5 files changed

+176
-211
lines changed

5 files changed

+176
-211
lines changed

test/jdk/jdk/jfr/event/compiler/TestCompilerInlining.java

Lines changed: 67 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,6 @@
2323

2424
package jdk.jfr.event.compiler;
2525

26-
import jdk.internal.org.objectweb.asm.*;
2726
import jdk.jfr.Recording;
2827
import jdk.jfr.consumer.RecordedEvent;
2928
import jdk.jfr.consumer.RecordedMethod;
@@ -35,13 +34,24 @@
3534
import jdk.test.whitebox.WhiteBox;
3635

3736
import java.io.IOException;
37+
import java.lang.classfile.ClassModel;
38+
import java.lang.classfile.ClassFile;
39+
import java.lang.classfile.Instruction;
40+
import java.lang.classfile.instruction.InvokeInstruction;
41+
import java.lang.constant.ClassDesc;
42+
import java.lang.constant.MethodTypeDesc;
3843
import java.lang.reflect.Constructor;
3944
import java.lang.reflect.Executable;
4045
import java.lang.reflect.Method;
4146
import java.util.*;
4247
import java.util.stream.IntStream;
48+
import java.util.stream.Stream;
4349

44-
/**
50+
import static java.lang.constant.ConstantDescs.CD_Object;
51+
import static java.lang.constant.ConstantDescs.CD_void;
52+
import static java.lang.constant.ConstantDescs.INIT_NAME;
53+
54+
/*
4555
* @test CompilerInliningTest
4656
* @bug 8073607
4757
* @key jfr
@@ -50,8 +60,8 @@
5060
*
5161
* @requires vm.opt.Inline == true | vm.opt.Inline == null
5262
* @library /test/lib
53-
* @modules java.base/jdk.internal.org.objectweb.asm
54-
* jdk.jfr
63+
* @modules jdk.jfr
64+
* @enablePreview
5565
*
5666
* @build jdk.test.whitebox.WhiteBox
5767
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
@@ -64,7 +74,7 @@ public class TestCompilerInlining {
6474
private static final int LEVEL_SIMPLE = 1;
6575
private static final int LEVEL_FULL_OPTIMIZATION = 4;
6676
private static final Executable ENTRY_POINT = getConstructor(TestCase.class);
67-
private static final String TEST_CASE_CLASS_NAME = TestCase.class.getName().replace('.', '/');
77+
private static final ClassDesc CD_TestCase = TestCase.class.describeConstable().orElseThrow();
6878

6979
public static void main(String[] args) throws Exception {
7080
InlineCalls inlineCalls = new InlineCalls(TestCase.class);
@@ -100,8 +110,8 @@ private static void testLevel(Map<Call, Boolean> expectedResult, int level) thro
100110
MethodDesc caller = methodToMethodDesc(callerObject);
101111
MethodDesc callee = ciMethodToMethodDesc(calleeObject);
102112
// only TestCase.* -> TestCase.* OR TestCase.* -> Object.<init> are tested/filtered
103-
if (caller.className.equals(TEST_CASE_CLASS_NAME) && (callee.className.equals(TEST_CASE_CLASS_NAME)
104-
|| (callee.className.equals("java/lang/Object") && callee.methodName.equals("<init>")))) {
113+
if (caller.className.equals(CD_TestCase) && (callee.className.equals(CD_TestCase)
114+
|| (callee.className.equals(CD_Object) && callee.methodName.equals(INIT_NAME)))) {
105115
System.out.println(event);
106116
boolean succeeded = (boolean) event.getValue("succeeded");
107117
int bci = Events.assertField(event, "bci").atLeast(0).getValue();
@@ -132,17 +142,17 @@ private static int[] determineAvailableLevels() {
132142
}
133143

134144
private static MethodDesc methodToMethodDesc(RecordedMethod method) {
135-
String internalClassName = method.getType().getName().replace('.', '/');
145+
ClassDesc classDesc = ClassDesc.of(method.getType().getName());
136146
String methodName = method.getValue("name");
137-
String methodDescriptor = method.getValue("descriptor");
138-
return new MethodDesc(internalClassName, methodName, methodDescriptor);
147+
MethodTypeDesc methodDescriptor = MethodTypeDesc.ofDescriptor(method.getValue("descriptor"));
148+
return new MethodDesc(classDesc, methodName, methodDescriptor);
139149
}
140150

141151
private static MethodDesc ciMethodToMethodDesc(RecordedObject ciMethod) {
142-
String internalClassName = ciMethod.getValue("type");
152+
ClassDesc classDesc = ClassDesc.ofInternalName(ciMethod.getValue("type"));
143153
String methodName = ciMethod.getValue("name");
144-
String methodDescriptor = ciMethod.getValue("descriptor");
145-
return new MethodDesc(internalClassName, methodName, methodDescriptor);
154+
MethodTypeDesc methodDescriptor = MethodTypeDesc.ofDescriptor(ciMethod.getValue("descriptor"));
155+
return new MethodDesc(classDesc, methodName, methodDescriptor);
146156
}
147157

148158
private static Method getMethod(Class<?> aClass, String name, Class<?>... params) {
@@ -246,35 +256,33 @@ public String toString() {
246256
* data structure for method description
247257
*/
248258
class MethodDesc {
249-
public final String className;
259+
public final ClassDesc className;
250260
public final String methodName;
251-
public final String descriptor;
252-
253-
public MethodDesc(Class<?> aClass, String methodName, String descriptor) {
254-
this(aClass.getName().replace('.', '/'), methodName, descriptor);
255-
}
261+
public final MethodTypeDesc descriptor;
256262

257-
public MethodDesc(String className, String methodName, String descriptor) {
263+
public MethodDesc(ClassDesc className, String methodName, MethodTypeDesc descriptor) {
258264
Objects.requireNonNull(className);
259265
Objects.requireNonNull(methodName);
260266
Objects.requireNonNull(descriptor);
261-
this.className = className.replace('.', '/');
267+
this.className = className;
262268
this.methodName = methodName;
263269
this.descriptor = descriptor;
264270
}
265271

266272
public MethodDesc(Executable executable) {
267-
Class<?> aClass = executable.getDeclaringClass();
268-
className = Type.getInternalName(aClass).replace('.', '/');
273+
className = executable.getDeclaringClass().describeConstable().orElseThrow();
274+
ClassDesc retType;
269275

270-
if (executable instanceof Constructor<?>) {
271-
methodName = "<init>";
272-
descriptor = Type.getConstructorDescriptor((Constructor<?>) executable);
273-
} else {
276+
if (executable instanceof Method method) {
274277
methodName = executable.getName();
275-
descriptor = Type.getMethodDescriptor((Method) executable);
278+
retType = method.getReturnType().describeConstable().orElseThrow();
279+
} else {
280+
methodName = INIT_NAME;
281+
retType = CD_void;
276282
}
277283

284+
descriptor = MethodTypeDesc.of(retType, Stream.of(executable.getParameterTypes())
285+
.map(c -> c.describeConstable().orElseThrow()).toArray(ClassDesc[]::new));
278286
}
279287

280288
@Override
@@ -361,43 +369,41 @@ public void forceInline(Executable executable) {
361369

362370
private static Collection<Call> getCalls(Class<?> aClass) {
363371
List<Call> calls = new ArrayList<>();
364-
ClassWriter cw;
365-
ClassReader cr;
372+
ClassModel clm;
366373
try {
367-
cr = new ClassReader(aClass.getName());
374+
var stream = ClassLoader.getSystemResourceAsStream(aClass.getName()
375+
.replace('.', '/') + ".class");
376+
if (stream == null) {
377+
throw new IOException("Cannot find class file for " + aClass.getName());
378+
}
379+
clm = ClassFile.of().parse(stream.readAllBytes());
368380
} catch (IOException e) {
369381
throw new Error("TESTBUG : unexpected IOE during class reading", e);
370382
}
371-
cw = new ClassWriter(cr, 0);
372-
ClassVisitor cv = new ClassVisitor(Opcodes.ASM7, cw) {
373-
@Override
374-
public MethodVisitor visitMethod(int access, String name, String desc, String descriptor, String[] exceptions) {
375-
System.out.println("Method: " +name);
376-
MethodVisitor mv = super.visitMethod(access, name, desc, descriptor, exceptions);
377-
return new CallTracer(aClass, name, desc, mv, calls);
378-
}
379-
};
380-
cr.accept(cv, 0);
381383

384+
clm.methods().forEach(mm -> {
385+
System.out.println("Method: " + mm.methodName().stringValue());
386+
mm.code().ifPresent(com -> {
387+
MethodDesc caller = new MethodDesc(
388+
clm.thisClass().asSymbol(),
389+
mm.methodName().stringValue(),
390+
mm.methodTypeSymbol()
391+
);
392+
int offset = 0;
393+
for (var ce : com.elements()) {
394+
if (ce instanceof Instruction ins) {
395+
if (ins instanceof InvokeInstruction inv) {
396+
calls.add(new Call(caller, new MethodDesc(
397+
inv.owner().asSymbol(),
398+
inv.name().stringValue(),
399+
inv.typeSymbol()
400+
), offset));
401+
}
402+
offset += ins.sizeInBytes();
403+
}
404+
}
405+
});
406+
});
382407
return calls;
383408
}
384-
385-
private static class CallTracer extends MethodVisitor {
386-
private final MethodDesc caller;
387-
private Collection<Call> calls;
388-
389-
public CallTracer(Class<?> aClass, String name, String desc, MethodVisitor mv, Collection<Call> calls) {
390-
super(Opcodes.ASM7, mv);
391-
caller = new MethodDesc(aClass.getName(), name, desc);
392-
this.calls = calls;
393-
}
394-
395-
@Override
396-
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
397-
Label label = new Label();
398-
visitLabel(label);
399-
super.visitMethodInsn(opcode, owner, name, desc, itf);
400-
calls.add(new Call(caller, new MethodDesc(owner, name, desc), label.getOffset()));
401-
}
402-
}
403409
}

0 commit comments

Comments
 (0)