< prev index next >
src/java.base/share/classes/java/lang/reflect/AccessibleObject.java
Print this page
*** 310,335 ****
// The simple security check for Constructor is to see if
// the caller has already been seen, verified, and cached.
// (See also Class.newInstance(), which uses a similar method.)
//
// A more complicated security check cache is needed for Method and Field
! // The cache can be either null (empty cache), a 2-array of {caller,target},
! // or a caller (with target implicitly equal to this.clazz).
! // In the 2-array case, the target is always different from the clazz.
volatile Object securityCheckCache;
! void checkAccess(Class<?> caller, Class<?> clazz, Object obj, int modifiers)
throws IllegalAccessException
{
! if (caller == clazz) { // quick check
return; // ACCESS IS OK
}
Object cache = securityCheckCache; // read volatile
! Class<?> targetClass = clazz;
! if (obj != null
&& Modifier.isProtected(modifiers)
! && ((targetClass = obj.getClass()) != clazz)) {
// Must match a 2-list of { caller, targetClass }.
if (cache instanceof Class[]) {
Class<?>[] cache2 = (Class<?>[]) cache;
if (cache2[1] == targetClass &&
cache2[0] == caller) {
--- 310,335 ----
// The simple security check for Constructor is to see if
// the caller has already been seen, verified, and cached.
// (See also Class.newInstance(), which uses a similar method.)
//
// A more complicated security check cache is needed for Method and Field
! // The cache can be either null (empty cache), a 2-array of {caller,targetClass},
! // or a caller (with targetClass implicitly equal to memberClass).
! // In the 2-array case, the targetClass is always different from the memberClass.
volatile Object securityCheckCache;
! final void checkAccess(Class<?> caller, Class<?> memberClass,
! Class<?> targetClass, int modifiers)
throws IllegalAccessException
{
! if (caller == memberClass) { // quick check
return; // ACCESS IS OK
}
Object cache = securityCheckCache; // read volatile
! if (targetClass != null // instance member or constructor
&& Modifier.isProtected(modifiers)
! && targetClass != memberClass) {
// Must match a 2-list of { caller, targetClass }.
if (cache instanceof Class[]) {
Class<?>[] cache2 = (Class<?>[]) cache;
if (cache2[1] == targetClass &&
cache2[0] == caller) {
*** 337,365 ****
}
// (Test cache[1] first since range check for [1]
// subsumes range check for [0].)
}
} else if (cache == caller) {
! // Non-protected case (or obj.class == this.clazz).
return; // ACCESS IS OK
}
// If no return, fall through to the slow path.
! slowCheckMemberAccess(caller, clazz, obj, modifiers, targetClass);
}
// Keep all this slow stuff out of line:
! void slowCheckMemberAccess(Class<?> caller, Class<?> clazz, Object obj, int modifiers,
! Class<?> targetClass)
throws IllegalAccessException
{
! Reflection.ensureMemberAccess(caller, clazz, obj, modifiers);
// Success: Update the cache.
! Object cache = ((targetClass == clazz)
! ? caller
! : new Class<?>[] { caller, targetClass });
// Note: The two cache elements are not volatile,
// but they are effectively final. The Java memory model
// guarantees that the initializing stores for the cache
// elements will occur before the volatile write.
--- 337,367 ----
}
// (Test cache[1] first since range check for [1]
// subsumes range check for [0].)
}
} else if (cache == caller) {
! // Non-protected case (or targetClass == memberClass or static member).
return; // ACCESS IS OK
}
// If no return, fall through to the slow path.
! slowCheckMemberAccess(caller, memberClass, targetClass, modifiers);
}
// Keep all this slow stuff out of line:
! void slowCheckMemberAccess(Class<?> caller, Class<?> memberClass,
! Class<?> targetClass, int modifiers)
throws IllegalAccessException
{
! Reflection.ensureMemberAccess(caller, memberClass, targetClass, modifiers);
// Success: Update the cache.
! Object cache = (targetClass != null
! && Modifier.isProtected(modifiers)
! && targetClass != memberClass)
! ? new Class<?>[] { caller, targetClass }
! : caller;
// Note: The two cache elements are not volatile,
// but they are effectively final. The Java memory model
// guarantees that the initializing stores for the cache
// elements will occur before the volatile write.
< prev index next >