mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8274299: Make Method/Constructor/Field accessors @Stable
Reviewed-by: redestad, mchung
This commit is contained in:
parent
1459180f35
commit
7ad74d82d7
13 changed files with 748 additions and 85 deletions
|
@ -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;
|
||||
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
|
||||
fieldAccessor = accessor;
|
||||
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);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue