8181443: Replace usages of jdk.internal.misc.Unsafe with MethodHandles.Lookup.defineClass
Reviewed-by: alanb, egahlin
This commit is contained in:
parent
4af2374271
commit
73a6313038
src
java.base/share/classes
jdk.jfr/share/classes/jdk/jfr/internal
test/hotspot/jtreg
compiler
runtime/Dictionary
@ -37,7 +37,6 @@ import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@ -578,23 +577,17 @@ abstract class ClassSpecializer<T,K,S extends ClassSpecializer<T,K,S>.SpeciesDat
|
||||
InvokerBytecodeGenerator.maybeDump(classBCName(className), classFile);
|
||||
Class<?> speciesCode;
|
||||
|
||||
ClassLoader cl = topClass().getClassLoader();
|
||||
ProtectionDomain pd = null;
|
||||
if (cl != null) {
|
||||
pd = AccessController.doPrivileged(
|
||||
new PrivilegedAction<>() {
|
||||
@Override
|
||||
public ProtectionDomain run() {
|
||||
return topClass().getProtectionDomain();
|
||||
}
|
||||
});
|
||||
}
|
||||
try {
|
||||
speciesCode = UNSAFE.defineClass(className, classFile, 0, classFile.length, cl, pd);
|
||||
} catch (Exception ex) {
|
||||
throw newInternalError(ex);
|
||||
}
|
||||
|
||||
MethodHandles.Lookup lookup = IMPL_LOOKUP.in(topClass());
|
||||
speciesCode = AccessController.doPrivileged(new PrivilegedAction<>() {
|
||||
@Override
|
||||
public Class<?> run() {
|
||||
try {
|
||||
return lookup.defineClass(classFile);
|
||||
} catch (Exception ex) {
|
||||
throw newInternalError(ex);
|
||||
}
|
||||
}
|
||||
});
|
||||
return speciesCode.asSubclass(topClass());
|
||||
}
|
||||
|
||||
|
@ -39,12 +39,11 @@ import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import jdk.internal.loader.BootLoader;
|
||||
import jdk.internal.misc.JavaLangAccess;
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
import jdk.internal.module.Modules;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
import jdk.internal.misc.VM;
|
||||
import jdk.internal.reflect.CallerSensitive;
|
||||
import jdk.internal.reflect.Reflection;
|
||||
@ -468,7 +467,7 @@ public class Proxy implements java.io.Serializable {
|
||||
* in which the proxy class will be defined.
|
||||
*/
|
||||
private static final class ProxyBuilder {
|
||||
private static final Unsafe UNSAFE = Unsafe.getUnsafe();
|
||||
private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
|
||||
|
||||
// prefix for all proxy class names
|
||||
private static final String proxyClassNamePrefix = "$Proxy";
|
||||
@ -535,9 +534,8 @@ public class Proxy implements java.io.Serializable {
|
||||
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
|
||||
proxyName, interfaces.toArray(EMPTY_CLASS_ARRAY), accessFlags);
|
||||
try {
|
||||
Class<?> pc = UNSAFE.defineClass(proxyName, proxyClassFile,
|
||||
0, proxyClassFile.length,
|
||||
loader, null);
|
||||
Class<?> pc = JLA.defineClass(loader, proxyName, proxyClassFile,
|
||||
null, "__dynamic_proxy__");
|
||||
reverseProxyCache.sub(pc).putIfAbsent(loader, Boolean.TRUE);
|
||||
return pc;
|
||||
} catch (ClassFormatError e) {
|
||||
|
@ -27,14 +27,16 @@ package jdk.internal.reflect;
|
||||
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
|
||||
/** Utility class which assists in calling Unsafe.defineClass() by
|
||||
import jdk.internal.misc.JavaLangAccess;
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
|
||||
/** Utility class which assists in calling defineClass() by
|
||||
creating a new class loader which delegates to the one needed in
|
||||
order for proper resolution of the given bytecodes to occur. */
|
||||
|
||||
class ClassDefiner {
|
||||
static final Unsafe unsafe = Unsafe.getUnsafe();
|
||||
static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
|
||||
|
||||
/** <P> We define generated code into a new class loader which
|
||||
delegates to the defining loader of the target class. It is
|
||||
@ -60,7 +62,7 @@ class ClassDefiner {
|
||||
return new DelegatingClassLoader(parentClassLoader);
|
||||
}
|
||||
});
|
||||
return unsafe.defineClass(name, bytes, off, len, newLoader, null);
|
||||
return JLA.defineClass(newLoader, name, bytes, null, "__ClassDefiner__");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ public final class EventClassBuilder {
|
||||
endClass();
|
||||
byte[] bytes = classWriter.toByteArray();
|
||||
ASMToolkit.logASM(fullClassName, bytes);
|
||||
return SecuritySupport.defineClass(type.getInternalName(), bytes, Event.class.getClassLoader()).asSubclass(Event.class);
|
||||
return SecuritySupport.defineClass(Event.class, bytes).asSubclass(Event.class);
|
||||
}
|
||||
|
||||
private void endClass() {
|
||||
|
@ -134,7 +134,7 @@ final class EventHandlerCreator {
|
||||
buildWriteMethod();
|
||||
byte[] bytes = classWriter.toByteArray();
|
||||
ASMToolkit.logASM(className, bytes);
|
||||
return SecuritySupport.defineClass(className, bytes, Event.class.getClassLoader()).asSubclass(EventHandler.class);
|
||||
return SecuritySupport.defineClass(EventHandler.class, bytes).asSubclass(EventHandler.class);
|
||||
}
|
||||
|
||||
public static EventHandler instantiateEventHandler(Class<? extends EventHandler> handlerClass, boolean registered, EventType eventType, EventControl eventControl) throws Error {
|
||||
|
@ -31,6 +31,7 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.io.Reader;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
@ -71,6 +72,7 @@ import jdk.jfr.Recording;
|
||||
*/
|
||||
public final class SecuritySupport {
|
||||
private final static Unsafe unsafe = Unsafe.getUnsafe();
|
||||
private final static MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
|
||||
private final static Module JFR_MODULE = Event.class.getModule();
|
||||
public final static SafePath JFC_DIRECTORY = getPathInProperty("java.home", "lib/jfr");
|
||||
|
||||
@ -381,8 +383,17 @@ public final class SecuritySupport {
|
||||
unsafe.ensureClassInitialized(clazz);
|
||||
}
|
||||
|
||||
static Class<?> defineClass(String name, byte[] bytes, ClassLoader classLoader) {
|
||||
return unsafe.defineClass(name, bytes, 0, bytes.length, classLoader, null);
|
||||
static Class<?> defineClass(Class<?> lookupClass, byte[] bytes) {
|
||||
return AccessController.doPrivileged(new PrivilegedAction<>() {
|
||||
@Override
|
||||
public Class<?> run() {
|
||||
try {
|
||||
return MethodHandles.privateLookupIn(lookupClass, LOOKUP).defineClass(bytes);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new InternalError(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static Thread createThreadWitNoPermissions(String threadName, Runnable runnable) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2018, 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
|
||||
@ -48,7 +48,6 @@
|
||||
|
||||
package compiler.jsr292.NonInlinedCall;
|
||||
|
||||
import jdk.internal.misc.Unsafe;
|
||||
import jdk.internal.org.objectweb.asm.ClassWriter;
|
||||
import jdk.internal.org.objectweb.asm.MethodVisitor;
|
||||
import jdk.internal.vm.annotation.DontInline;
|
||||
@ -68,13 +67,15 @@ import static jdk.internal.org.objectweb.asm.Opcodes.IRETURN;
|
||||
|
||||
public class RedefineTest {
|
||||
static final MethodHandles.Lookup LOOKUP = MethodHandleHelper.IMPL_LOOKUP;
|
||||
static final Unsafe UNSAFE = Unsafe.getUnsafe();
|
||||
|
||||
static final String NAME = "compiler/jsr292/NonInlinedCall/RedefineTest$T";
|
||||
|
||||
static Class<?> getClass(int r) {
|
||||
byte[] classFile = getClassFile(r);
|
||||
return UNSAFE.defineClass(NAME, classFile, 0, classFile.length, null, null);
|
||||
try {
|
||||
return MethodHandles.lookup().defineClass(classFile);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -32,6 +32,9 @@
|
||||
* java.base/jdk.internal.vm.annotation
|
||||
* java.base/jdk.internal.misc
|
||||
*
|
||||
* @library ../jsr292/patches
|
||||
* @build java.base/java.lang.invoke.MethodHandleHelper
|
||||
*
|
||||
* @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions
|
||||
* -Xbatch -XX:-TieredCompilation
|
||||
* -XX:+FoldStableValues
|
||||
@ -64,6 +67,9 @@ import jdk.internal.vm.annotation.Stable;
|
||||
import jdk.test.lib.Asserts;
|
||||
import jdk.test.lib.Platform;
|
||||
|
||||
import java.lang.invoke.MethodHandleHelper;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodHandles.Lookup;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@ -393,8 +399,9 @@ public class UnsafeGetConstantField {
|
||||
}
|
||||
|
||||
Test generate() {
|
||||
Class<?> c = U.defineClass(className, classFile, 0, classFile.length, THIS_CLASS.getClassLoader(), null);
|
||||
try {
|
||||
Lookup lookup = MethodHandleHelper.IMPL_LOOKUP.in(MethodHandles.class);
|
||||
Class<?> c = lookup.defineClass(classFile);
|
||||
return (Test) c.newInstance();
|
||||
} catch(Exception e) {
|
||||
throw new Error(e);
|
||||
|
@ -57,11 +57,10 @@ public class CleanProtectionDomain {
|
||||
|
||||
static class Test {
|
||||
public static void test() throws Exception {
|
||||
Unsafe unsafe = Unsafe.getUnsafe();
|
||||
TestClassLoader classloader = new TestClassLoader();
|
||||
ProtectionDomain pd = new ProtectionDomain(null, null);
|
||||
byte klassbuf[] = InMemoryJavaCompiler.compile("TestClass", "class TestClass { }");
|
||||
Class klass = unsafe.defineClass(null, klassbuf, 0, klassbuf.length, classloader, pd);
|
||||
Class<?> klass = classloader.defineClass("TestClass", klassbuf, pd);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
@ -91,6 +90,10 @@ public class CleanProtectionDomain {
|
||||
public TestClassLoader() {
|
||||
super();
|
||||
}
|
||||
|
||||
public Class<?> defineClass(String name, byte[] bytes, ProtectionDomain pd) {
|
||||
return defineClass(name, bytes, 0, bytes.length, pd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user