8168915: [JVMCI] use MethodParameters attribute instead of depending on -g option for sanity checks
Reviewed-by: kvn
This commit is contained in:
parent
dd45be3f41
commit
47096d7dd1
@ -33,8 +33,10 @@ import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
|
|||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.Executable;
|
import java.lang.reflect.Executable;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -459,6 +461,22 @@ final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSp
|
|||||||
return constantPool;
|
return constantPool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Parameter[] getParameters() {
|
||||||
|
Executable javaMethod = toJava();
|
||||||
|
if (javaMethod == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
java.lang.reflect.Parameter[] javaParameters = javaMethod.getParameters();
|
||||||
|
Parameter[] res = new Parameter[javaParameters.length];
|
||||||
|
for (int i = 0; i < res.length; i++) {
|
||||||
|
java.lang.reflect.Parameter src = javaParameters[i];
|
||||||
|
res[i] = new Parameter(src.getName(), src.getModifiers(), this, i);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Annotation[][] getParameterAnnotations() {
|
public Annotation[][] getParameterAnnotations() {
|
||||||
Executable javaMethod = toJava();
|
Executable javaMethod = toJava();
|
||||||
@ -529,13 +547,31 @@ final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSp
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Method searchMethods(Method[] methods, String name, Class<?> returnType, Class<?>[] parameterTypes) {
|
||||||
|
for (Method m : methods) {
|
||||||
|
if (m.getName().equals(name) && returnType.equals(m.getReturnType()) && Arrays.equals(m.getParameterTypes(), parameterTypes)) {
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private Executable toJava() {
|
private Executable toJava() {
|
||||||
if (toJavaCache != null) {
|
if (toJavaCache != null) {
|
||||||
return toJavaCache;
|
return toJavaCache;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Class<?>[] parameterTypes = signatureToTypes();
|
Class<?>[] parameterTypes = signatureToTypes();
|
||||||
Executable result = isConstructor() ? holder.mirror().getDeclaredConstructor(parameterTypes) : holder.mirror().getDeclaredMethod(name, parameterTypes);
|
Class<?> returnType = ((HotSpotResolvedJavaType) getSignature().getReturnType(holder).resolve(holder)).mirror();
|
||||||
|
|
||||||
|
Executable result;
|
||||||
|
if (isConstructor()) {
|
||||||
|
result = holder.mirror().getDeclaredConstructor(parameterTypes);
|
||||||
|
} else {
|
||||||
|
// Do not use Method.getDeclaredMethod() as it can return a bridge method
|
||||||
|
// when this.isBridge() is false and vice versa.
|
||||||
|
result = searchMethods(holder.mirror().getDeclaredMethods(), name, returnType, parameterTypes);
|
||||||
|
}
|
||||||
toJavaCache = result;
|
toJavaCache = result;
|
||||||
return result;
|
return result;
|
||||||
} catch (NoSuchMethodException | NoClassDefFoundError e) {
|
} catch (NoSuchMethodException | NoClassDefFoundError e) {
|
||||||
|
@ -26,6 +26,7 @@ import java.lang.annotation.Annotation;
|
|||||||
import java.lang.reflect.AnnotatedElement;
|
import java.lang.reflect.AnnotatedElement;
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -173,6 +174,133 @@ public interface ResolvedJavaMethod extends JavaMethod, InvokeTarget, ModifiersP
|
|||||||
*/
|
*/
|
||||||
ConstantPool getConstantPool();
|
ConstantPool getConstantPool();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@code Parameter} provides information about method parameters.
|
||||||
|
*/
|
||||||
|
public static class Parameter implements AnnotatedElement {
|
||||||
|
private final String name;
|
||||||
|
private final ResolvedJavaMethod method;
|
||||||
|
private final int modifiers;
|
||||||
|
private final int index;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for {@code Parameter}.
|
||||||
|
*
|
||||||
|
* @param name the name of the parameter
|
||||||
|
* @param modifiers the modifier flags for the parameter
|
||||||
|
* @param method the method which defines this parameter
|
||||||
|
* @param index the index of the parameter
|
||||||
|
*/
|
||||||
|
public Parameter(String name,
|
||||||
|
int modifiers,
|
||||||
|
ResolvedJavaMethod method,
|
||||||
|
int index) {
|
||||||
|
this.name = name;
|
||||||
|
this.modifiers = modifiers;
|
||||||
|
this.method = method;
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the name of the parameter.
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the method declaring the parameter.
|
||||||
|
*/
|
||||||
|
public ResolvedJavaMethod getDeclaringMethod() {
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the modifier flags for the parameter
|
||||||
|
*/
|
||||||
|
public int getModifiers() {
|
||||||
|
return modifiers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the kind of the parameter.
|
||||||
|
*/
|
||||||
|
public JavaKind getKind() {
|
||||||
|
return method.getSignature().getParameterKind(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the formal type of the parameter.
|
||||||
|
*/
|
||||||
|
public Type getParameterizedType() {
|
||||||
|
return method.getGenericParameterTypes()[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the type of the parameter.
|
||||||
|
*/
|
||||||
|
public JavaType getType() {
|
||||||
|
return method.getSignature().getParameterType(index, method.getDeclaringClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the parameter represents a variable argument list.
|
||||||
|
*/
|
||||||
|
public boolean isVarArgs() {
|
||||||
|
return method.isVarArgs() && index == method.getSignature().getParameterCount(false) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
|
||||||
|
return method.getParameterAnnotations(annotationClass)[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
public Annotation[] getAnnotations() {
|
||||||
|
return method.getParameterAnnotations()[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
public Annotation[] getDeclaredAnnotations() {
|
||||||
|
return getAnnotations();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
Type type = getParameterizedType();
|
||||||
|
String typename = type.getTypeName();
|
||||||
|
if (isVarArgs()) {
|
||||||
|
typename = typename.replaceFirst("\\[\\]$", "...");
|
||||||
|
}
|
||||||
|
|
||||||
|
final StringBuilder sb = new StringBuilder(Modifier.toString(getModifiers()));
|
||||||
|
if (sb.length() != 0) {
|
||||||
|
sb.append(' ');
|
||||||
|
}
|
||||||
|
return sb.append(typename).append(' ').append(getName()).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj instanceof Parameter) {
|
||||||
|
Parameter other = (Parameter) obj;
|
||||||
|
return (other.method.equals(method) && other.index == index);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return method.hashCode() ^ index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of {@code Parameter} objects that represent all the parameters to this
|
||||||
|
* method. Returns an array of length 0 if this method has no parameters. Returns {@code null}
|
||||||
|
* if the parameter information is unavailable.
|
||||||
|
*/
|
||||||
|
default Parameter[] getParameters() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of arrays that represent the annotations on the formal parameters, in
|
* Returns an array of arrays that represent the annotations on the formal parameters, in
|
||||||
* declaration order, of this method.
|
* declaration order, of this method.
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
package jdk.vm.ci.runtime.test;
|
package jdk.vm.ci.runtime.test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
@ -60,6 +61,7 @@ import org.junit.Test;
|
|||||||
import jdk.vm.ci.meta.ConstantPool;
|
import jdk.vm.ci.meta.ConstantPool;
|
||||||
import jdk.vm.ci.meta.ExceptionHandler;
|
import jdk.vm.ci.meta.ExceptionHandler;
|
||||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||||
|
import jdk.vm.ci.meta.ResolvedJavaMethod.Parameter;
|
||||||
import jdk.vm.ci.meta.ResolvedJavaType;
|
import jdk.vm.ci.meta.ResolvedJavaType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -266,6 +268,26 @@ public class TestResolvedJavaMethod extends MethodUniverse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getParametersTest() {
|
||||||
|
for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
|
||||||
|
java.lang.reflect.Parameter[] expected = e.getKey().getParameters();
|
||||||
|
Parameter[] actual = e.getValue().getParameters();
|
||||||
|
assertEquals(actual.length, expected.length);
|
||||||
|
for (int i = 0; i < actual.length; i++) {
|
||||||
|
java.lang.reflect.Parameter exp = expected[i];
|
||||||
|
Parameter act = actual[i];
|
||||||
|
assertEquals(exp.getName(), act.getName());
|
||||||
|
assertEquals(exp.getModifiers(), act.getModifiers());
|
||||||
|
assertEquals(exp.getModifiers(), act.getModifiers());
|
||||||
|
assertArrayEquals(exp.getAnnotations(), act.getAnnotations());
|
||||||
|
assertEquals(exp.getType().getName(), act.getType().toClassName());
|
||||||
|
assertEquals(exp.getParameterizedType(), act.getParameterizedType());
|
||||||
|
assertEquals(metaAccess.lookupJavaMethod(exp.getDeclaringExecutable()), act.getDeclaringMethod());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target(ElementType.METHOD)
|
@Target(ElementType.METHOD)
|
||||||
@interface TestAnnotation {
|
@interface TestAnnotation {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user