8274299: Make Method/Constructor/Field accessors @Stable
Reviewed-by: redestad, mchung
This commit is contained in:
parent
1459180f35
commit
7ad74d82d7
@ -30,6 +30,7 @@ import jdk.internal.reflect.CallerSensitive;
|
||||
import jdk.internal.reflect.ConstructorAccessor;
|
||||
import jdk.internal.reflect.Reflection;
|
||||
import jdk.internal.vm.annotation.ForceInline;
|
||||
import jdk.internal.vm.annotation.Stable;
|
||||
import sun.reflect.annotation.TypeAnnotation;
|
||||
import sun.reflect.annotation.TypeAnnotationParser;
|
||||
import sun.reflect.generics.repository.ConstructorRepository;
|
||||
@ -62,10 +63,12 @@ import java.util.StringJoiner;
|
||||
* @since 1.1
|
||||
*/
|
||||
public final class Constructor<T> extends Executable {
|
||||
@Stable
|
||||
private Class<T> clazz;
|
||||
private int slot;
|
||||
private Class<?>[] parameterTypes;
|
||||
private Class<?>[] exceptionTypes;
|
||||
@Stable
|
||||
private int modifiers;
|
||||
// Generics and annotations support
|
||||
private transient String signature;
|
||||
@ -94,7 +97,8 @@ public final class Constructor<T> extends Executable {
|
||||
return genericInfo; //return cached repository
|
||||
}
|
||||
|
||||
private volatile ConstructorAccessor constructorAccessor;
|
||||
@Stable
|
||||
private ConstructorAccessor constructorAccessor;
|
||||
// For sharing of ConstructorAccessors. This branching structure
|
||||
// is currently only two levels deep (i.e., one root Constructor
|
||||
// and potentially many Constructor objects pointing to it.)
|
||||
@ -491,7 +495,7 @@ public final class Constructor<T> extends Executable {
|
||||
if ((clazz.getModifiers() & Modifier.ENUM) != 0)
|
||||
throw new IllegalArgumentException("Cannot reflectively create enum objects");
|
||||
|
||||
ConstructorAccessor ca = constructorAccessor; // read volatile
|
||||
ConstructorAccessor ca = constructorAccessor; // read @Stable
|
||||
if (ca == null) {
|
||||
ca = acquireConstructorAccessor();
|
||||
}
|
||||
@ -532,8 +536,8 @@ public final class Constructor<T> extends Executable {
|
||||
private ConstructorAccessor acquireConstructorAccessor() {
|
||||
// First check to see if one has been created yet, and take it
|
||||
// if so.
|
||||
ConstructorAccessor tmp = null;
|
||||
if (root != null) tmp = root.getConstructorAccessor();
|
||||
Constructor<?> root = this.root;
|
||||
ConstructorAccessor tmp = root == null ? null : root.getConstructorAccessor();
|
||||
if (tmp != null) {
|
||||
constructorAccessor = tmp;
|
||||
} else {
|
||||
@ -556,6 +560,7 @@ public final class Constructor<T> extends Executable {
|
||||
void setConstructorAccessor(ConstructorAccessor accessor) {
|
||||
constructorAccessor = accessor;
|
||||
// Propagate up
|
||||
Constructor<?> root = this.root;
|
||||
if (root != null) {
|
||||
root.setConstructorAccessor(accessor);
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ import jdk.internal.reflect.CallerSensitive;
|
||||
import jdk.internal.reflect.FieldAccessor;
|
||||
import jdk.internal.reflect.Reflection;
|
||||
import jdk.internal.vm.annotation.ForceInline;
|
||||
import jdk.internal.vm.annotation.Stable;
|
||||
import sun.reflect.generics.repository.FieldRepository;
|
||||
import sun.reflect.generics.factory.CoreReflectionFactory;
|
||||
import sun.reflect.generics.factory.GenericsFactory;
|
||||
@ -65,12 +66,15 @@ import sun.reflect.annotation.TypeAnnotationParser;
|
||||
public final
|
||||
class Field extends AccessibleObject implements Member {
|
||||
|
||||
@Stable
|
||||
private Class<?> clazz;
|
||||
private int slot;
|
||||
// This is guaranteed to be interned by the VM in the 1.4
|
||||
// reflection implementation
|
||||
private String name;
|
||||
@Stable
|
||||
private Class<?> type;
|
||||
@Stable
|
||||
private int modifiers;
|
||||
private boolean trustedFinal;
|
||||
// Generics and annotations support
|
||||
@ -79,8 +83,10 @@ class Field extends AccessibleObject implements Member {
|
||||
private transient FieldRepository genericInfo;
|
||||
private byte[] annotations;
|
||||
// Cached field accessor created without override
|
||||
@Stable
|
||||
private FieldAccessor fieldAccessor;
|
||||
// Cached field accessor created with override
|
||||
@Stable
|
||||
private FieldAccessor overrideFieldAccessor;
|
||||
// For sharing of FieldAccessors. This branching structure is
|
||||
// currently only two levels deep (i.e., one root Field and
|
||||
@ -421,8 +427,10 @@ class Field extends AccessibleObject implements Member {
|
||||
if (!override) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, obj);
|
||||
return getFieldAccessor().get(obj);
|
||||
} else {
|
||||
return getOverrideFieldAccessor().get(obj);
|
||||
}
|
||||
return getFieldAccessor(obj).get(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -455,8 +463,10 @@ class Field extends AccessibleObject implements Member {
|
||||
if (!override) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, obj);
|
||||
return getFieldAccessor().getBoolean(obj);
|
||||
} else {
|
||||
return getOverrideFieldAccessor().getBoolean(obj);
|
||||
}
|
||||
return getFieldAccessor(obj).getBoolean(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -489,8 +499,10 @@ class Field extends AccessibleObject implements Member {
|
||||
if (!override) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, obj);
|
||||
return getFieldAccessor().getByte(obj);
|
||||
} else {
|
||||
return getOverrideFieldAccessor().getByte(obj);
|
||||
}
|
||||
return getFieldAccessor(obj).getByte(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -525,8 +537,10 @@ class Field extends AccessibleObject implements Member {
|
||||
if (!override) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, obj);
|
||||
return getFieldAccessor().getChar(obj);
|
||||
} else {
|
||||
return getOverrideFieldAccessor().getChar(obj);
|
||||
}
|
||||
return getFieldAccessor(obj).getChar(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -561,8 +575,10 @@ class Field extends AccessibleObject implements Member {
|
||||
if (!override) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, obj);
|
||||
return getFieldAccessor().getShort(obj);
|
||||
} else {
|
||||
return getOverrideFieldAccessor().getShort(obj);
|
||||
}
|
||||
return getFieldAccessor(obj).getShort(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -597,8 +613,10 @@ class Field extends AccessibleObject implements Member {
|
||||
if (!override) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, obj);
|
||||
return getFieldAccessor().getInt(obj);
|
||||
} else {
|
||||
return getOverrideFieldAccessor().getInt(obj);
|
||||
}
|
||||
return getFieldAccessor(obj).getInt(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -633,8 +651,10 @@ class Field extends AccessibleObject implements Member {
|
||||
if (!override) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, obj);
|
||||
return getFieldAccessor().getLong(obj);
|
||||
} else {
|
||||
return getOverrideFieldAccessor().getLong(obj);
|
||||
}
|
||||
return getFieldAccessor(obj).getLong(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -669,8 +689,10 @@ class Field extends AccessibleObject implements Member {
|
||||
if (!override) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, obj);
|
||||
return getFieldAccessor().getFloat(obj);
|
||||
} else {
|
||||
return getOverrideFieldAccessor().getFloat(obj);
|
||||
}
|
||||
return getFieldAccessor(obj).getFloat(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -705,8 +727,10 @@ class Field extends AccessibleObject implements Member {
|
||||
if (!override) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, obj);
|
||||
return getFieldAccessor().getDouble(obj);
|
||||
} else {
|
||||
return getOverrideFieldAccessor().getDouble(obj);
|
||||
}
|
||||
return getFieldAccessor(obj).getDouble(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -795,8 +819,10 @@ class Field extends AccessibleObject implements Member {
|
||||
if (!override) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, obj);
|
||||
getFieldAccessor().set(obj, value);
|
||||
} else {
|
||||
getOverrideFieldAccessor().set(obj, value);
|
||||
}
|
||||
getFieldAccessor(obj).set(obj, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -832,8 +858,10 @@ class Field extends AccessibleObject implements Member {
|
||||
if (!override) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, obj);
|
||||
getFieldAccessor().setBoolean(obj, z);
|
||||
} else {
|
||||
getOverrideFieldAccessor().setBoolean(obj, z);
|
||||
}
|
||||
getFieldAccessor(obj).setBoolean(obj, z);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -869,8 +897,10 @@ class Field extends AccessibleObject implements Member {
|
||||
if (!override) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, obj);
|
||||
getFieldAccessor().setByte(obj, b);
|
||||
} else {
|
||||
getOverrideFieldAccessor().setByte(obj, b);
|
||||
}
|
||||
getFieldAccessor(obj).setByte(obj, b);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -906,8 +936,10 @@ class Field extends AccessibleObject implements Member {
|
||||
if (!override) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, obj);
|
||||
getFieldAccessor().setChar(obj, c);
|
||||
} else {
|
||||
getOverrideFieldAccessor().setChar(obj, c);
|
||||
}
|
||||
getFieldAccessor(obj).setChar(obj, c);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -943,8 +975,10 @@ class Field extends AccessibleObject implements Member {
|
||||
if (!override) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, obj);
|
||||
getFieldAccessor().setShort(obj, s);
|
||||
} else {
|
||||
getOverrideFieldAccessor().setShort(obj, s);
|
||||
}
|
||||
getFieldAccessor(obj).setShort(obj, s);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -980,8 +1014,10 @@ class Field extends AccessibleObject implements Member {
|
||||
if (!override) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, obj);
|
||||
getFieldAccessor().setInt(obj, i);
|
||||
} else {
|
||||
getOverrideFieldAccessor().setInt(obj, i);
|
||||
}
|
||||
getFieldAccessor(obj).setInt(obj, i);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1017,8 +1053,10 @@ class Field extends AccessibleObject implements Member {
|
||||
if (!override) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, obj);
|
||||
getFieldAccessor().setLong(obj, l);
|
||||
} else {
|
||||
getOverrideFieldAccessor().setLong(obj, l);
|
||||
}
|
||||
getFieldAccessor(obj).setLong(obj, l);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1054,8 +1092,10 @@ class Field extends AccessibleObject implements Member {
|
||||
if (!override) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, obj);
|
||||
getFieldAccessor().setFloat(obj, f);
|
||||
} else {
|
||||
getOverrideFieldAccessor().setFloat(obj, f);
|
||||
}
|
||||
getFieldAccessor(obj).setFloat(obj, f);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1091,8 +1131,10 @@ class Field extends AccessibleObject implements Member {
|
||||
if (!override) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, obj);
|
||||
getFieldAccessor().setDouble(obj, d);
|
||||
} else {
|
||||
getOverrideFieldAccessor().setDouble(obj, d);
|
||||
}
|
||||
getFieldAccessor(obj).setDouble(obj, d);
|
||||
}
|
||||
|
||||
// check access to field
|
||||
@ -1105,53 +1147,69 @@ class Field extends AccessibleObject implements Member {
|
||||
}
|
||||
|
||||
// security check is done before calling this method
|
||||
private FieldAccessor getFieldAccessor(Object obj)
|
||||
throws IllegalAccessException
|
||||
{
|
||||
boolean ov = override;
|
||||
FieldAccessor a = (ov) ? overrideFieldAccessor : fieldAccessor;
|
||||
return (a != null) ? a : acquireFieldAccessor(ov);
|
||||
private FieldAccessor getFieldAccessor() {
|
||||
FieldAccessor a = fieldAccessor;
|
||||
return (a != null) ? a : acquireFieldAccessor();
|
||||
}
|
||||
|
||||
private FieldAccessor getOverrideFieldAccessor() {
|
||||
FieldAccessor a = overrideFieldAccessor;
|
||||
return (a != null) ? a : acquireOverrideFieldAccessor();
|
||||
}
|
||||
|
||||
// NOTE that there is no synchronization used here. It is correct
|
||||
// (though not efficient) to generate more than one FieldAccessor
|
||||
// for a given Field. However, avoiding synchronization will
|
||||
// probably make the implementation more scalable.
|
||||
private FieldAccessor acquireFieldAccessor(boolean overrideFinalCheck) {
|
||||
private FieldAccessor acquireFieldAccessor() {
|
||||
// First check to see if one has been created yet, and take it
|
||||
// if so
|
||||
FieldAccessor tmp = null;
|
||||
if (root != null) tmp = root.getFieldAccessor(overrideFinalCheck);
|
||||
Field root = this.root;
|
||||
FieldAccessor tmp = root == null ? null : root.fieldAccessor;
|
||||
if (tmp != null) {
|
||||
if (overrideFinalCheck)
|
||||
overrideFieldAccessor = tmp;
|
||||
else
|
||||
fieldAccessor = tmp;
|
||||
} else {
|
||||
// Otherwise fabricate one and propagate it up to the root
|
||||
tmp = reflectionFactory.newFieldAccessor(this, overrideFinalCheck);
|
||||
setFieldAccessor(tmp, overrideFinalCheck);
|
||||
tmp = reflectionFactory.newFieldAccessor(this, false);
|
||||
setFieldAccessor(tmp);
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// Returns FieldAccessor for this Field object, not looking up
|
||||
// the chain to the root
|
||||
private FieldAccessor getFieldAccessor(boolean overrideFinalCheck) {
|
||||
return (overrideFinalCheck)? overrideFieldAccessor : fieldAccessor;
|
||||
private FieldAccessor acquireOverrideFieldAccessor() {
|
||||
// First check to see if one has been created yet, and take it
|
||||
// if so
|
||||
Field root = this.root;
|
||||
FieldAccessor tmp = root == null ? null : root.overrideFieldAccessor;
|
||||
if (tmp != null) {
|
||||
overrideFieldAccessor = tmp;
|
||||
} else {
|
||||
// Otherwise fabricate one and propagate it up to the root
|
||||
tmp = reflectionFactory.newFieldAccessor(this, true);
|
||||
setOverrideFieldAccessor(tmp);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// Sets the FieldAccessor for this Field object and
|
||||
// Sets the fieldAccessor for this Field object and
|
||||
// (recursively) its root
|
||||
private void setFieldAccessor(FieldAccessor accessor, boolean overrideFinalCheck) {
|
||||
if (overrideFinalCheck)
|
||||
overrideFieldAccessor = accessor;
|
||||
else
|
||||
private void setFieldAccessor(FieldAccessor accessor) {
|
||||
fieldAccessor = accessor;
|
||||
// Propagate up
|
||||
Field root = this.root;
|
||||
if (root != null) {
|
||||
root.setFieldAccessor(accessor, overrideFinalCheck);
|
||||
root.setFieldAccessor(accessor);
|
||||
}
|
||||
}
|
||||
|
||||
// Sets the overrideFieldAccessor for this Field object and
|
||||
// (recursively) its root
|
||||
private void setOverrideFieldAccessor(FieldAccessor accessor) {
|
||||
overrideFieldAccessor = accessor;
|
||||
// Propagate up
|
||||
Field root = this.root;
|
||||
if (root != null) {
|
||||
root.setOverrideFieldAccessor(accessor);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,8 @@ public final class Method extends Executable {
|
||||
private byte[] annotations;
|
||||
private byte[] parameterAnnotations;
|
||||
private byte[] annotationDefault;
|
||||
private volatile MethodAccessor methodAccessor;
|
||||
@Stable
|
||||
private MethodAccessor methodAccessor;
|
||||
// For sharing of MethodAccessors. This branching structure is
|
||||
// currently only two levels deep (i.e., one root Method and
|
||||
// potentially many Method objects pointing to it.)
|
||||
@ -665,8 +666,8 @@ public final class Method extends Executable {
|
||||
private MethodAccessor acquireMethodAccessor() {
|
||||
// First check to see if one has been created yet, and take it
|
||||
// if so
|
||||
MethodAccessor tmp = null;
|
||||
if (root != null) tmp = root.getMethodAccessor();
|
||||
Method root = this.root;
|
||||
MethodAccessor tmp = root == null ? null : root.getMethodAccessor();
|
||||
if (tmp != null) {
|
||||
methodAccessor = tmp;
|
||||
} else {
|
||||
@ -689,6 +690,7 @@ public final class Method extends Executable {
|
||||
void setMethodAccessor(MethodAccessor accessor) {
|
||||
methodAccessor = accessor;
|
||||
// Propagate up
|
||||
Method root = this.root;
|
||||
if (root != null) {
|
||||
root.setMethodAccessor(accessor);
|
||||
}
|
||||
|
@ -25,16 +25,25 @@
|
||||
|
||||
package jdk.internal.reflect;
|
||||
|
||||
import jdk.internal.vm.annotation.Stable;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Objects;
|
||||
|
||||
/** Delegates its invocation to another ConstructorAccessorImpl and can
|
||||
change its delegate at run time. */
|
||||
|
||||
class DelegatingConstructorAccessorImpl extends ConstructorAccessorImpl {
|
||||
private ConstructorAccessorImpl delegate;
|
||||
// initial non-null delegate
|
||||
@Stable
|
||||
private final ConstructorAccessorImpl initialDelegate;
|
||||
// alternative delegate: starts as null;
|
||||
// only single change from null -> non-null is guaranteed
|
||||
@Stable
|
||||
private ConstructorAccessorImpl altDelegate;
|
||||
|
||||
DelegatingConstructorAccessorImpl(ConstructorAccessorImpl delegate) {
|
||||
setDelegate(delegate);
|
||||
initialDelegate = Objects.requireNonNull(delegate);
|
||||
}
|
||||
|
||||
public Object newInstance(Object[] args)
|
||||
@ -42,10 +51,15 @@ class DelegatingConstructorAccessorImpl extends ConstructorAccessorImpl {
|
||||
IllegalArgumentException,
|
||||
InvocationTargetException
|
||||
{
|
||||
return delegate.newInstance(args);
|
||||
return delegate().newInstance(args);
|
||||
}
|
||||
|
||||
private ConstructorAccessorImpl delegate() {
|
||||
var d = altDelegate;
|
||||
return d != null ? d : initialDelegate;
|
||||
}
|
||||
|
||||
void setDelegate(ConstructorAccessorImpl delegate) {
|
||||
this.delegate = delegate;
|
||||
altDelegate = Objects.requireNonNull(delegate);
|
||||
}
|
||||
}
|
||||
|
@ -25,25 +25,38 @@
|
||||
|
||||
package jdk.internal.reflect;
|
||||
|
||||
import jdk.internal.vm.annotation.Stable;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Objects;
|
||||
|
||||
/** Delegates its invocation to another MethodAccessorImpl and can
|
||||
change its delegate at run time. */
|
||||
|
||||
class DelegatingMethodAccessorImpl extends MethodAccessorImpl {
|
||||
private MethodAccessorImpl delegate;
|
||||
// initial non-null delegate
|
||||
@Stable private final MethodAccessorImpl initialDelegate;
|
||||
// alternative delegate: starts as null;
|
||||
// only single change from null -> non-null is guaranteed
|
||||
@Stable private MethodAccessorImpl altDelegate;
|
||||
|
||||
DelegatingMethodAccessorImpl(MethodAccessorImpl delegate) {
|
||||
setDelegate(delegate);
|
||||
initialDelegate = Objects.requireNonNull(delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(Object obj, Object[] args)
|
||||
throws IllegalArgumentException, InvocationTargetException
|
||||
{
|
||||
return delegate.invoke(obj, args);
|
||||
return delegate().invoke(obj, args);
|
||||
}
|
||||
|
||||
private MethodAccessorImpl delegate() {
|
||||
var d = altDelegate;
|
||||
return d != null ? d : initialDelegate;
|
||||
}
|
||||
|
||||
void setDelegate(MethodAccessorImpl delegate) {
|
||||
this.delegate = delegate;
|
||||
altDelegate = Objects.requireNonNull(delegate);
|
||||
}
|
||||
}
|
||||
|
@ -25,12 +25,23 @@
|
||||
|
||||
package jdk.internal.reflect;
|
||||
|
||||
import jdk.internal.vm.annotation.Stable;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/** Package-private implementation of the FieldAccessor interface
|
||||
which has access to all classes and all fields, regardless of
|
||||
language restrictions. See MagicAccessorImpl. */
|
||||
|
||||
abstract class FieldAccessorImpl extends MagicAccessorImpl
|
||||
implements FieldAccessor {
|
||||
@Stable
|
||||
protected final Field field;
|
||||
|
||||
FieldAccessorImpl(Field field) {
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
/** Matches specification in {@link java.lang.reflect.Field} */
|
||||
public abstract Object get(Object obj)
|
||||
throws IllegalArgumentException;
|
||||
|
@ -25,8 +25,6 @@
|
||||
|
||||
package jdk.internal.reflect;
|
||||
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
|
||||
@ -39,12 +37,13 @@ class NativeConstructorAccessorImpl extends ConstructorAccessorImpl {
|
||||
= U.objectFieldOffset(NativeConstructorAccessorImpl.class, "generated");
|
||||
|
||||
private final Constructor<?> c;
|
||||
private DelegatingConstructorAccessorImpl parent;
|
||||
private final DelegatingConstructorAccessorImpl parent;
|
||||
private int numInvocations;
|
||||
private volatile int generated;
|
||||
|
||||
NativeConstructorAccessorImpl(Constructor<?> c) {
|
||||
this.c = c;
|
||||
this.parent = new DelegatingConstructorAccessorImpl(this);
|
||||
}
|
||||
|
||||
public Object newInstance(Object[] args)
|
||||
@ -77,8 +76,8 @@ class NativeConstructorAccessorImpl extends ConstructorAccessorImpl {
|
||||
return newInstance0(c, args);
|
||||
}
|
||||
|
||||
void setParent(DelegatingConstructorAccessorImpl parent) {
|
||||
this.parent = parent;
|
||||
DelegatingConstructorAccessorImpl getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
private static native Object newInstance0(Constructor<?> c, Object[] args)
|
||||
|
@ -25,8 +25,6 @@
|
||||
|
||||
package jdk.internal.reflect;
|
||||
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
|
||||
@ -39,12 +37,13 @@ class NativeMethodAccessorImpl extends MethodAccessorImpl {
|
||||
= U.objectFieldOffset(NativeMethodAccessorImpl.class, "generated");
|
||||
|
||||
private final Method method;
|
||||
private DelegatingMethodAccessorImpl parent;
|
||||
private final DelegatingMethodAccessorImpl parent;
|
||||
private int numInvocations;
|
||||
private volatile int generated;
|
||||
|
||||
NativeMethodAccessorImpl(Method method) {
|
||||
this.method = method;
|
||||
this.parent = new DelegatingMethodAccessorImpl(this);
|
||||
}
|
||||
|
||||
public Object invoke(Object obj, Object[] args)
|
||||
@ -77,8 +76,8 @@ class NativeMethodAccessorImpl extends MethodAccessorImpl {
|
||||
return invoke0(method, obj, args);
|
||||
}
|
||||
|
||||
void setParent(DelegatingMethodAccessorImpl parent) {
|
||||
this.parent = parent;
|
||||
DelegatingMethodAccessorImpl getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
private static native Object invoke0(Method m, Object obj, Object[] args);
|
||||
|
@ -44,7 +44,6 @@ import java.util.Properties;
|
||||
import jdk.internal.access.JavaLangReflectAccess;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import jdk.internal.misc.VM;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
import sun.security.util.SecurityConstants;
|
||||
|
||||
@ -210,12 +209,8 @@ public class ReflectionFactory {
|
||||
method.getExceptionTypes(),
|
||||
method.getModifiers());
|
||||
} else {
|
||||
NativeMethodAccessorImpl acc =
|
||||
new NativeMethodAccessorImpl(method);
|
||||
DelegatingMethodAccessorImpl res =
|
||||
new DelegatingMethodAccessorImpl(acc);
|
||||
acc.setParent(res);
|
||||
return res;
|
||||
NativeMethodAccessorImpl acc = new NativeMethodAccessorImpl(method);
|
||||
return acc.getParent();
|
||||
}
|
||||
}
|
||||
|
||||
@ -252,12 +247,8 @@ public class ReflectionFactory {
|
||||
c.getExceptionTypes(),
|
||||
c.getModifiers());
|
||||
} else {
|
||||
NativeConstructorAccessorImpl acc =
|
||||
new NativeConstructorAccessorImpl(c);
|
||||
DelegatingConstructorAccessorImpl res =
|
||||
new DelegatingConstructorAccessorImpl(acc);
|
||||
acc.setParent(res);
|
||||
return res;
|
||||
NativeConstructorAccessorImpl acc = new NativeConstructorAccessorImpl(c);
|
||||
return acc.getParent();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ package jdk.internal.reflect;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
import jdk.internal.vm.annotation.Stable;
|
||||
|
||||
/** Base class for jdk.internal.misc.Unsafe-based FieldAccessors. The
|
||||
observation is that there are only nine types of fields from the
|
||||
@ -39,12 +40,12 @@ import jdk.internal.misc.Unsafe;
|
||||
abstract class UnsafeFieldAccessorImpl extends FieldAccessorImpl {
|
||||
static final Unsafe unsafe = Unsafe.getUnsafe();
|
||||
|
||||
protected final Field field;
|
||||
@Stable
|
||||
protected final long fieldOffset;
|
||||
protected final boolean isFinal;
|
||||
|
||||
UnsafeFieldAccessorImpl(Field field) {
|
||||
this.field = field;
|
||||
super(field);
|
||||
if (Modifier.isStatic(field.getModifiers()))
|
||||
fieldOffset = unsafe.staticFieldOffset(field);
|
||||
else
|
||||
|
@ -31,6 +31,7 @@ import java.security.AccessController;
|
||||
import java.util.Set;
|
||||
|
||||
import jdk.internal.misc.Unsafe;
|
||||
import jdk.internal.vm.annotation.Stable;
|
||||
|
||||
/** Base class for jdk.internal.misc.Unsafe-based FieldAccessors for static
|
||||
fields. The observation is that there are only nine types of
|
||||
@ -45,6 +46,7 @@ abstract class UnsafeStaticFieldAccessorImpl extends UnsafeFieldAccessorImpl {
|
||||
Set.of("base"));
|
||||
}
|
||||
|
||||
@Stable
|
||||
protected final Object base; // base
|
||||
|
||||
UnsafeStaticFieldAccessorImpl(Field field) {
|
||||
|
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.openjdk.bench.java.lang.reflect;
|
||||
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Fork;
|
||||
import org.openjdk.jmh.annotations.Level;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.infra.Blackhole;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Benchmark measuring cold-start of reflective method invocation.
|
||||
*/
|
||||
@BenchmarkMode(Mode.SingleShotTime)
|
||||
@OutputTimeUnit(TimeUnit.MICROSECONDS)
|
||||
@State(Scope.Benchmark)
|
||||
@Fork(value = 30, warmups = 10)
|
||||
public class ReflectionColdstartBenchmark {
|
||||
|
||||
static class Nested {
|
||||
static Object m00(Object p) {return p;}
|
||||
|
||||
static Object m01(Object p) {return p;}
|
||||
|
||||
static Object m02(Object p) {return p;}
|
||||
|
||||
static Object m03(Object p) {return p;}
|
||||
|
||||
static Object m04(Object p) {return p;}
|
||||
|
||||
static Object m05(Object p) {return p;}
|
||||
|
||||
static Object m06(Object p) {return p;}
|
||||
|
||||
static Object m07(Object p) {return p;}
|
||||
|
||||
static Object m08(Object p) {return p;}
|
||||
|
||||
static Object m09(Object p) {return p;}
|
||||
|
||||
static Object m0A(Object p) {return p;}
|
||||
|
||||
static Object m0B(Object p) {return p;}
|
||||
|
||||
static Object m0C(Object p) {return p;}
|
||||
|
||||
static Object m0D(Object p) {return p;}
|
||||
|
||||
static Object m0E(Object p) {return p;}
|
||||
|
||||
static Object m0F(Object p) {return p;}
|
||||
|
||||
static Object m10(Object p) {return p;}
|
||||
|
||||
static Object m11(Object p) {return p;}
|
||||
|
||||
static Object m12(Object p) {return p;}
|
||||
|
||||
static Object m13(Object p) {return p;}
|
||||
|
||||
static Object m14(Object p) {return p;}
|
||||
|
||||
static Object m15(Object p) {return p;}
|
||||
|
||||
static Object m16(Object p) {return p;}
|
||||
|
||||
static Object m17(Object p) {return p;}
|
||||
|
||||
static Object m18(Object p) {return p;}
|
||||
|
||||
static Object m19(Object p) {return p;}
|
||||
|
||||
static Object m1A(Object p) {return p;}
|
||||
|
||||
static Object m1B(Object p) {return p;}
|
||||
|
||||
static Object m1C(Object p) {return p;}
|
||||
|
||||
static Object m1D(Object p) {return p;}
|
||||
|
||||
static Object m1E(Object p) {return p;}
|
||||
|
||||
static Object m1F(Object p) {return p;}
|
||||
}
|
||||
|
||||
private Method[] methods;
|
||||
private Object arg;
|
||||
|
||||
@Setup(Level.Trial)
|
||||
public void setup() {
|
||||
methods = Nested.class.getDeclaredMethods();
|
||||
arg = new Object();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void invokeMethods(Blackhole bh) throws ReflectiveOperationException {
|
||||
for (Method m : methods) {
|
||||
bh.consume(m.invoke(null, arg));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,439 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.openjdk.bench.java.lang.reflect;
|
||||
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Fork;
|
||||
import org.openjdk.jmh.annotations.Level;
|
||||
import org.openjdk.jmh.annotations.Measurement;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.Warmup;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Benchmark measuring field access and method invocation using different conditions:
|
||||
* <ul>
|
||||
* <li>Const - Method/Field is constant-foldable</li>
|
||||
* <li>Var - Method/Field is single-instance but not constant-foldable</li>
|
||||
* <li>Poly - multiple Method/Field instances used at single call-site</li>
|
||||
* </ul>
|
||||
*/
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@Warmup(iterations = 10, time = 1, batchSize = 10)
|
||||
@Measurement(iterations = 10, time = 1, batchSize = 10)
|
||||
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||
@State(Scope.Thread)
|
||||
@Fork(value = 1, warmups = 0)
|
||||
public class ReflectionSpeedBenchmark {
|
||||
|
||||
static final Method staticMethodConst;
|
||||
static final Method instanceMethodConst;
|
||||
static final Field staticFieldConst;
|
||||
static final Field instanceFieldConst;
|
||||
static final Constructor<?> constructorConst;
|
||||
static final Object[] constructorArgs;
|
||||
|
||||
static Method staticMethodVar;
|
||||
static Method instanceMethodVar;
|
||||
static Field staticFieldVar;
|
||||
static Field instanceFieldVar;
|
||||
static Constructor<?> constructorVar;
|
||||
|
||||
static Method[] staticMethodsPoly;
|
||||
static Method[] instanceMethodsPoly;
|
||||
static Field[] staticFieldsPoly;
|
||||
static Field[] instanceFieldsPoly;
|
||||
static Constructor<?>[] constructorsPoly;
|
||||
static Object[][] constructorsArgsPoly;
|
||||
|
||||
static {
|
||||
try {
|
||||
staticMethodConst = staticMethodVar = ReflectionSpeedBenchmark.class.getDeclaredMethod("sumStatic", int.class, int.class);
|
||||
instanceMethodConst = instanceMethodVar = ReflectionSpeedBenchmark.class.getDeclaredMethod("sumInstance", int.class, int.class);
|
||||
|
||||
staticFieldConst = staticFieldVar = ReflectionSpeedBenchmark.class.getDeclaredField("staticField");
|
||||
instanceFieldConst = instanceFieldVar = ReflectionSpeedBenchmark.class.getDeclaredField("instanceField");
|
||||
|
||||
constructorConst = constructorVar = NestedConstruction.class.getDeclaredConstructor();
|
||||
constructorArgs = new Object[0];
|
||||
|
||||
staticMethodsPoly = NestedStatic.class.getDeclaredMethods();
|
||||
staticFieldsPoly = NestedStatic.class.getDeclaredFields();
|
||||
instanceMethodsPoly = NestedInstance.class.getDeclaredMethods();
|
||||
instanceFieldsPoly = NestedInstance.class.getDeclaredFields();
|
||||
|
||||
constructorsPoly = NestedConstruction.class.getDeclaredConstructors();
|
||||
constructorsArgsPoly = new Object[constructorsPoly.length][];
|
||||
for (int i = 0; i < constructorsPoly.length; i++) {
|
||||
constructorsArgsPoly[i] = new Object[constructorsPoly[i].getParameterCount()];
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new NoSuchMethodError(e.getMessage());
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new NoSuchFieldError(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public static class NestedStatic {
|
||||
// # of fields must be 2^N
|
||||
public static Object
|
||||
f00, f01, f02, f03, f04, f05, f06, f07, f08, f09, f0A, f0B, f0C, f0D, f0E, f0F,
|
||||
f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f1A, f1B, f1C, f1D, f1E, f1F;
|
||||
|
||||
// # of methods must be 2^N
|
||||
public static Object m00(Object p) {return p;}
|
||||
|
||||
public static Object m01(Object p) {return p;}
|
||||
|
||||
public static Object m02(Object p) {return p;}
|
||||
|
||||
public static Object m03(Object p) {return p;}
|
||||
|
||||
public static Object m04(Object p) {return p;}
|
||||
|
||||
public static Object m05(Object p) {return p;}
|
||||
|
||||
public static Object m06(Object p) {return p;}
|
||||
|
||||
public static Object m07(Object p) {return p;}
|
||||
|
||||
public static Object m08(Object p) {return p;}
|
||||
|
||||
public static Object m09(Object p) {return p;}
|
||||
|
||||
public static Object m0A(Object p) {return p;}
|
||||
|
||||
public static Object m0B(Object p) {return p;}
|
||||
|
||||
public static Object m0C(Object p) {return p;}
|
||||
|
||||
public static Object m0D(Object p) {return p;}
|
||||
|
||||
public static Object m0E(Object p) {return p;}
|
||||
|
||||
public static Object m0F(Object p) {return p;}
|
||||
|
||||
public static Object m10(Object p) {return p;}
|
||||
|
||||
public static Object m11(Object p) {return p;}
|
||||
|
||||
public static Object m12(Object p) {return p;}
|
||||
|
||||
public static Object m13(Object p) {return p;}
|
||||
|
||||
public static Object m14(Object p) {return p;}
|
||||
|
||||
public static Object m15(Object p) {return p;}
|
||||
|
||||
public static Object m16(Object p) {return p;}
|
||||
|
||||
public static Object m17(Object p) {return p;}
|
||||
|
||||
public static Object m18(Object p) {return p;}
|
||||
|
||||
public static Object m19(Object p) {return p;}
|
||||
|
||||
public static Object m1A(Object p) {return p;}
|
||||
|
||||
public static Object m1B(Object p) {return p;}
|
||||
|
||||
public static Object m1C(Object p) {return p;}
|
||||
|
||||
public static Object m1D(Object p) {return p;}
|
||||
|
||||
public static Object m1E(Object p) {return p;}
|
||||
|
||||
public static Object m1F(Object p) {return p;}
|
||||
}
|
||||
|
||||
public static class NestedInstance {
|
||||
// # of fields must be 2^N
|
||||
public Object
|
||||
f00, f01, f02, f03, f04, f05, f06, f07, f08, f09, f0A, f0B, f0C, f0D, f0E, f0F,
|
||||
f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f1A, f1B, f1C, f1D, f1E, f1F;
|
||||
|
||||
// # of methods must be 2^N
|
||||
public Object m00(Object p) {return p;}
|
||||
|
||||
public Object m01(Object p) {return p;}
|
||||
|
||||
public Object m02(Object p) {return p;}
|
||||
|
||||
public Object m03(Object p) {return p;}
|
||||
|
||||
public Object m04(Object p) {return p;}
|
||||
|
||||
public Object m05(Object p) {return p;}
|
||||
|
||||
public Object m06(Object p) {return p;}
|
||||
|
||||
public Object m07(Object p) {return p;}
|
||||
|
||||
public Object m08(Object p) {return p;}
|
||||
|
||||
public Object m09(Object p) {return p;}
|
||||
|
||||
public Object m0A(Object p) {return p;}
|
||||
|
||||
public Object m0B(Object p) {return p;}
|
||||
|
||||
public Object m0C(Object p) {return p;}
|
||||
|
||||
public Object m0D(Object p) {return p;}
|
||||
|
||||
public Object m0E(Object p) {return p;}
|
||||
|
||||
public Object m0F(Object p) {return p;}
|
||||
|
||||
public Object m10(Object p) {return p;}
|
||||
|
||||
public Object m11(Object p) {return p;}
|
||||
|
||||
public Object m12(Object p) {return p;}
|
||||
|
||||
public Object m13(Object p) {return p;}
|
||||
|
||||
public Object m14(Object p) {return p;}
|
||||
|
||||
public Object m15(Object p) {return p;}
|
||||
|
||||
public Object m16(Object p) {return p;}
|
||||
|
||||
public Object m17(Object p) {return p;}
|
||||
|
||||
public Object m18(Object p) {return p;}
|
||||
|
||||
public Object m19(Object p) {return p;}
|
||||
|
||||
public Object m1A(Object p) {return p;}
|
||||
|
||||
public Object m1B(Object p) {return p;}
|
||||
|
||||
public Object m1C(Object p) {return p;}
|
||||
|
||||
public Object m1D(Object p) {return p;}
|
||||
|
||||
public Object m1E(Object p) {return p;}
|
||||
|
||||
public Object m1F(Object p) {return p;}
|
||||
}
|
||||
|
||||
public static class NestedConstruction {
|
||||
// # of constructors must be 2^N
|
||||
public NestedConstruction() {}
|
||||
|
||||
public NestedConstruction(Void p1) {}
|
||||
|
||||
public NestedConstruction(Void p1, Void p2) {}
|
||||
|
||||
public NestedConstruction(Void p1, Void p2, Void p3) {}
|
||||
|
||||
public NestedConstruction(Void p1, Void p2, Void p3, Void p4) {}
|
||||
|
||||
public NestedConstruction(Void p1, Void p2, Void p3, Void p4, Void p5) {}
|
||||
|
||||
public NestedConstruction(Void p1, Void p2, Void p3, Void p4, Void p5, Void p6) {}
|
||||
|
||||
public NestedConstruction(Void p1, Void p2, Void p3, Void p4, Void p5, Void p6, Void p7) {}
|
||||
}
|
||||
|
||||
private int rnd = 0;
|
||||
private int a, b;
|
||||
private Object o;
|
||||
private NestedInstance instance;
|
||||
|
||||
private int nextRnd() {
|
||||
return rnd += 7;
|
||||
}
|
||||
|
||||
@Setup(Level.Iteration)
|
||||
public void setup() {
|
||||
a = nextRnd();
|
||||
b = nextRnd();
|
||||
o = new Object();
|
||||
instance = new NestedInstance();
|
||||
}
|
||||
|
||||
public static int sumStatic(int a, int b) {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
public int sumInstance(int a, int b) {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
public static int staticField;
|
||||
public int instanceField;
|
||||
|
||||
// methods
|
||||
|
||||
@Benchmark
|
||||
public int staticMethodConst() {
|
||||
try {
|
||||
return (Integer) staticMethodConst.invoke(null, a, b);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public int instanceMethodConst() {
|
||||
try {
|
||||
return (Integer) instanceMethodConst.invoke(this, a, b);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public int staticMethodVar() {
|
||||
try {
|
||||
return (Integer) staticMethodVar.invoke(null, a, b);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public int instanceMethodVar() {
|
||||
try {
|
||||
return (Integer) instanceMethodVar.invoke(this, a, b);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object staticMethodPoly() {
|
||||
try {
|
||||
return staticMethodsPoly[nextRnd() & (staticMethodsPoly.length - 1)].invoke(null, o);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object instanceMethodPoly() {
|
||||
try {
|
||||
return instanceMethodsPoly[nextRnd() & (instanceMethodsPoly.length - 1)].invoke(instance, o);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
// fields
|
||||
|
||||
@Benchmark
|
||||
public int staticFieldConst() {
|
||||
try {
|
||||
return staticFieldConst.getInt(null);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public int instanceFieldConst() {
|
||||
try {
|
||||
return instanceFieldConst.getInt(this);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public int staticFieldVar() {
|
||||
try {
|
||||
return staticFieldVar.getInt(null);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public int instanceFieldVar() {
|
||||
try {
|
||||
return instanceFieldVar.getInt(this);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object staticFieldPoly() {
|
||||
try {
|
||||
return staticFieldsPoly[nextRnd() & (staticFieldsPoly.length - 1)].get(null);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object instanceFieldPoly() {
|
||||
try {
|
||||
return instanceFieldsPoly[nextRnd() & (instanceFieldsPoly.length - 1)].get(instance);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
// constructors
|
||||
|
||||
@Benchmark
|
||||
public Object constructorConst() {
|
||||
try {
|
||||
return constructorConst.newInstance(constructorArgs);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object constructorVar() {
|
||||
try {
|
||||
return constructorVar.newInstance(constructorArgs);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object constructorPoly() {
|
||||
try {
|
||||
int i = nextRnd() & (constructorsPoly.length - 1);
|
||||
return constructorsPoly[i].newInstance(constructorsArgsPoly[i]);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user