8235521: Replacement API for Unsafe::ensureClassInitialized

Reviewed-by: alanb, chegar, psandoz
This commit is contained in:
Mandy Chung 2020-06-08 16:55:45 -07:00
parent 6fc6476da8
commit 71d646a160
22 changed files with 708 additions and 83 deletions

View file

@ -27,6 +27,7 @@ package java.lang.invoke;
import jdk.internal.access.JavaLangAccess;
import jdk.internal.access.SharedSecrets;
import jdk.internal.misc.Unsafe;
import jdk.internal.misc.VM;
import jdk.internal.module.IllegalAccessLogger;
import jdk.internal.org.objectweb.asm.ClassReader;
@ -2243,7 +2244,8 @@ public class MethodHandles {
Class<?> lookupClass = lookup.lookupClass();
ClassLoader loader = lookupClass.getClassLoader();
ProtectionDomain pd = (loader != null) ? lookup.lookupClassProtectionDomain() : null;
Class<?> c = JLA.defineClass(loader, lookupClass, name, bytes, pd, initialize, classFlags, classData);
Class<?> c = SharedSecrets.getJavaLangAccess()
.defineClass(loader, lookupClass, name, bytes, pd, initialize, classFlags, classData);
assert !isNestmate() || c.getNestHost() == lookupClass.getNestHost();
return c;
}
@ -2263,7 +2265,7 @@ public class MethodHandles {
private ProtectionDomain lookupClassProtectionDomain() {
ProtectionDomain pd = cachedProtectionDomain;
if (pd == null) {
cachedProtectionDomain = pd = JLA.protectionDomain(lookupClass);
cachedProtectionDomain = pd = SharedSecrets.getJavaLangAccess().protectionDomain(lookupClass);
}
return pd;
}
@ -2283,8 +2285,6 @@ public class MethodHandles {
*/
static final Lookup PUBLIC_LOOKUP = new Lookup(Object.class, null, UNCONDITIONAL);
static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
private static void checkUnprivilegedlookupClass(Class<?> lookupClass) {
String name = lookupClass.getName();
if (name.startsWith("java.lang.invoke."))
@ -2586,6 +2586,43 @@ assertEquals("[x, y, z]", pb.command().toString());
return accessClass(targetClass);
}
/**
* Ensures that {@code targetClass} has been initialized. The class
* to be initialized must be {@linkplain #accessClass accessible}
* to this {@code Lookup} object. This method causes {@code targetClass}
* to be initialized if it has not been already initialized,
* as specified in JVMS {@jvms 5.5}.
*
* @param targetClass the class to be initialized
* @return {@code targetClass} that has been initialized
*
* @throws IllegalArgumentException if {@code targetClass} is a primitive type or {@code void}
* or array class
* @throws IllegalAccessException if {@code targetClass} is not
* {@linkplain #accessClass accessible} to this lookup
* @throws ExceptionInInitializerError if the class initialization provoked
* by this method fails
* @throws SecurityException if a security manager is present and it
* <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
* @since 15
* @jvms 5.5 Initialization
*/
public Class<?> ensureInitialized(Class<?> targetClass) throws IllegalAccessException {
if (targetClass.isPrimitive())
throw new IllegalArgumentException(targetClass + " is a primitive class");
if (targetClass.isArray())
throw new IllegalArgumentException(targetClass + " is an array class");
if (!VerifyAccess.isClassAccessible(targetClass, lookupClass, prevLookupClass, allowedModes)) {
throw new MemberName(targetClass).makeAccessException("access violation", this);
}
checkSecurityManager(targetClass, null);
// ensure class initialization
Unsafe.getUnsafe().ensureClassInitialized(targetClass);
return targetClass;
}
/**
* Determines if a class can be accessed from the lookup context defined by
* this {@code Lookup} object. The static initializer of the class is not run.