8238358: Implementation of JEP 371: Hidden Classes

Co-authored-by: Lois Foltan <lois.foltan@oracle.com>
Co-authored-by: David Holmes <david.holmes@oracle.com>
Co-authored-by: Harold Seigel <harold.seigel@oracle.com>
Co-authored-by: Serguei Spitsyn <serguei.spitsyn@oracle.com>
Co-authored-by: Alex Buckley <alex.buckley@oracle.com>
Co-authored-by: Jamsheed Mohammed C M <jamsheed.c.m@oracle.com>
Co-authored-by: Jan Lahoda <jan.lahoda@oracle.com>
Co-authored-by: Amy Lu <amy.lu@oracle.com>
Reviewed-by: alanb, cjplummer, coleenp, dholmes, dlong, forax, jlahoda, psandoz, plevart, sspitsyn, vromero
This commit is contained in:
Mandy Chung 2020-04-21 06:55:38 -07:00
parent 642041adbc
commit 7cc1371059
198 changed files with 9526 additions and 1575 deletions

View file

@ -27,7 +27,6 @@ package java.lang.invoke;
import jdk.internal.access.JavaLangInvokeAccess;
import jdk.internal.access.SharedSecrets;
import jdk.internal.org.objectweb.asm.AnnotationVisitor;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.reflect.CallerSensitive;
@ -40,6 +39,7 @@ import sun.invoke.util.ValueConversions;
import sun.invoke.util.VerifyType;
import sun.invoke.util.Wrapper;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.reflect.Array;
import java.nio.ByteOrder;
import java.util.Arrays;
@ -1157,10 +1157,24 @@ abstract class MethodHandleImpl {
return restoreToType(bccInvoker.bindTo(vamh), mh, hostClass);
}
private static MethodHandle makeInjectedInvoker(Class<?> hostClass) {
private static MethodHandle makeInjectedInvoker(Class<?> targetClass) {
try {
Class<?> invokerClass = UNSAFE.defineAnonymousClass(hostClass, INJECTED_INVOKER_TEMPLATE, null);
assert checkInjectedInvoker(hostClass, invokerClass);
/*
* The invoker class defined to the same class loader as the lookup class
* but in an unnamed package so that the class bytes can be cached and
* reused for any @CSM.
*
* @CSM must be public and exported if called by any module.
*/
String name = targetClass.getName() + "$$InjectedInvoker";
if (targetClass.isHidden()) {
// use the original class name
name = name.replace('/', '_');
}
Class<?> invokerClass = new Lookup(targetClass)
.makeHiddenClassDefiner(name, INJECTED_INVOKER_TEMPLATE)
.defineClass(true);
assert checkInjectedInvoker(targetClass, invokerClass);
return IMPL_LOOKUP.findStatic(invokerClass, "invoke_V", INVOKER_MT);
} catch (ReflectiveOperationException ex) {
throw uncaughtException(ex);
@ -1256,10 +1270,6 @@ abstract class MethodHandleImpl {
"(Ljava/lang/invoke/MethodHandle;[Ljava/lang/Object;)Ljava/lang/Object;",
null, null);
// Suppress invoker method in stack traces.
AnnotationVisitor av0 = mv.visitAnnotation(InvokerBytecodeGenerator.HIDDEN_SIG, true);
av0.visitEnd();
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 1);