--- old/src/java.base/share/classes/java/lang/invoke/ClassSpecializer.java 2018-10-02 13:26:14.000000000 -0700 +++ new/src/java.base/share/classes/java/lang/invoke/ClassSpecializer.java 2018-10-02 13:26:13.000000000 -0700 @@ -37,7 +37,6 @@ 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 @@ 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()); } --- old/src/java.base/share/classes/java/lang/reflect/Proxy.java 2018-10-02 13:26:15.000000000 -0700 +++ new/src/java.base/share/classes/java/lang/reflect/Proxy.java 2018-10-02 13:26:14.000000000 -0700 @@ -39,12 +39,11 @@ 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 @@ * 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 @@ 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) { --- old/src/java.base/share/classes/jdk/internal/reflect/ClassDefiner.java 2018-10-02 13:26:16.000000000 -0700 +++ new/src/java.base/share/classes/jdk/internal/reflect/ClassDefiner.java 2018-10-02 13:26:16.000000000 -0700 @@ -27,14 +27,16 @@ 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(); /**

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 @@ return new DelegatingClassLoader(parentClassLoader); } }); - return unsafe.defineClass(name, bytes, off, len, newLoader, null); + return JLA.defineClass(newLoader, name, bytes, null, "__ClassDefiner__"); } } --- old/src/jdk.jfr/share/classes/jdk/jfr/internal/EventClassBuilder.java 2018-10-02 13:26:18.000000000 -0700 +++ new/src/jdk.jfr/share/classes/jdk/jfr/internal/EventClassBuilder.java 2018-10-02 13:26:17.000000000 -0700 @@ -70,7 +70,7 @@ 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() { --- old/src/jdk.jfr/share/classes/jdk/jfr/internal/EventHandlerCreator.java 2018-10-02 13:26:19.000000000 -0700 +++ new/src/jdk.jfr/share/classes/jdk/jfr/internal/EventHandlerCreator.java 2018-10-02 13:26:18.000000000 -0700 @@ -134,7 +134,7 @@ 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 handlerClass, boolean registered, EventType eventType, EventControl eventControl) throws Error { --- old/src/jdk.jfr/share/classes/jdk/jfr/internal/SecuritySupport.java 2018-10-02 13:26:20.000000000 -0700 +++ new/src/jdk.jfr/share/classes/jdk/jfr/internal/SecuritySupport.java 2018-10-02 13:26:20.000000000 -0700 @@ -31,6 +31,7 @@ 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 @@ */ 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 @@ 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) { --- old/test/hotspot/jtreg/compiler/jsr292/NonInlinedCall/RedefineTest.java 2018-10-02 13:26:26.000000000 -0700 +++ new/test/hotspot/jtreg/compiler/jsr292/NonInlinedCall/RedefineTest.java 2018-10-02 13:26:24.000000000 -0700 @@ -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 @@ 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); + } } /** --- old/test/hotspot/jtreg/compiler/unsafe/UnsafeGetConstantField.java 2018-10-02 13:26:30.000000000 -0700 +++ new/test/hotspot/jtreg/compiler/unsafe/UnsafeGetConstantField.java 2018-10-02 13:26:28.000000000 -0700 @@ -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.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 @@ } 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); --- old/test/hotspot/jtreg/runtime/Dictionary/CleanProtectionDomain.java 2018-10-02 13:26:33.000000000 -0700 +++ new/test/hotspot/jtreg/runtime/Dictionary/CleanProtectionDomain.java 2018-10-02 13:26:32.000000000 -0700 @@ -57,11 +57,10 @@ 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 TestClassLoader() { super(); } + + public Class defineClass(String name, byte[] bytes, ProtectionDomain pd) { + return defineClass(name, bytes, 0, bytes.length, pd); + } } } }