Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8274299: Make Method/Constructor/Field accessors @Stable #5694

Closed
wants to merge 4 commits into from
Closed
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -30,6 +30,7 @@
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;
@@ -94,7 +95,8 @@ ConstructorRepository getGenericInfo() {
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 +493,7 @@ T newInstanceWithCaller(Object[] args, boolean checkAccess, Class<?> caller)
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 +534,8 @@ public boolean isSynthetic() {
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 +558,7 @@ ConstructorAccessor getConstructorAccessor() {
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.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,11 +66,13 @@
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;
private int modifiers;
private boolean trustedFinal;
@@ -79,8 +82,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 +426,10 @@ public Object get(Object obj)
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 +462,10 @@ public boolean getBoolean(Object obj)
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 +498,10 @@ public byte getByte(Object obj)
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 +536,10 @@ public char getChar(Object obj)
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 +574,10 @@ public short getShort(Object obj)
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 +612,10 @@ public int getInt(Object obj)
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 +650,10 @@ public long getLong(Object obj)
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 +688,10 @@ public float getFloat(Object obj)
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 +726,10 @@ public double getDouble(Object obj)
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 +818,10 @@ public void set(Object obj, Object value)
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 +857,10 @@ public void setBoolean(Object obj, boolean z)
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 +896,10 @@ public void setByte(Object obj, byte b)
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 +935,10 @@ public void setChar(Object obj, char c)
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 +974,10 @@ public void setShort(Object obj, short s)
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 +1013,10 @@ public void setInt(Object obj, int i)
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 +1052,10 @@ public void setLong(Object obj, long l)
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 +1091,10 @@ public void setFloat(Object obj, float f)
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 +1130,10 @@ public void setDouble(Object obj, double d)
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 +1146,69 @@ private void checkAccess(Class<?> caller, Object obj)
}

// 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;
}

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;
}

// Returns FieldAccessor for this Field object, not looking up
// the chain to the root
private FieldAccessor getFieldAccessor(boolean overrideFinalCheck) {
return (overrideFinalCheck)? overrideFieldAccessor : fieldAccessor;
// Sets the fieldAccessor for this Field object and
// (recursively) its root
private void setFieldAccessor(FieldAccessor accessor) {
fieldAccessor = accessor;
// Propagate up
Field root = this.root;
if (root != null) {
root.setFieldAccessor(accessor);
}
}

// Sets the FieldAccessor for this Field object and
// Sets the overrideFieldAccessor for this Field object and
// (recursively) its root
private void setFieldAccessor(FieldAccessor accessor, boolean overrideFinalCheck) {
if (overrideFinalCheck)
overrideFieldAccessor = accessor;
else
fieldAccessor = accessor;
private void setOverrideFieldAccessor(FieldAccessor accessor) {
overrideFieldAccessor = accessor;
// Propagate up
Field root = this.root;
if (root != null) {
root.setFieldAccessor(accessor, overrideFinalCheck);
root.setOverrideFieldAccessor(accessor);
}
}