20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.lang.invoke;
27
28 import jdk.internal.loader.BootLoader;
29 import jdk.internal.org.objectweb.asm.ClassWriter;
30 import jdk.internal.org.objectweb.asm.FieldVisitor;
31 import jdk.internal.org.objectweb.asm.MethodVisitor;
32 import jdk.internal.vm.annotation.Stable;
33 import sun.invoke.util.BytecodeName;
34
35 import java.lang.reflect.Constructor;
36 import java.lang.reflect.Field;
37 import java.lang.reflect.Modifier;
38 import java.security.AccessController;
39 import java.security.PrivilegedAction;
40 import java.security.ProtectionDomain;
41 import java.util.ArrayList;
42 import java.util.Collections;
43 import java.util.List;
44 import java.util.Objects;
45 import java.util.concurrent.ConcurrentHashMap;
46 import java.util.function.Function;
47
48 import static java.lang.invoke.LambdaForm.*;
49 import static java.lang.invoke.MethodHandleNatives.Constants.REF_getStatic;
50 import static java.lang.invoke.MethodHandleNatives.Constants.REF_putStatic;
51 import static java.lang.invoke.MethodHandleStatics.*;
52 import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
53 import static jdk.internal.org.objectweb.asm.Opcodes.*;
54
55 /**
56 * Class specialization code.
57 * @param <T> top class under which species classes are created.
58 * @param <K> key which identifies individual specializations.
59 * @param <S> species data type.
60 */
561 * final TopClass copyWithExtendL(CT ctarg, ..., Object narg) {
562 * return BMH_SPECIES.transform(L_TYPE).invokeBasic(ctarg, ..., argL0, argL1, argI2, narg);
563 * }
564 * final TopClass copyWithExtendI(CT ctarg, ..., int narg) {
565 * return BMH_SPECIES.transform(I_TYPE).invokeBasic(ctarg, ..., argL0, argL1, argI2, narg);
566 * }
567 * }
568 * </pre>
569 *
570 * @param className of the species
571 * @param speciesData what species we are generating
572 * @return the generated concrete TopClass class
573 */
574 Class<? extends T> generateConcreteSpeciesCode(String className, ClassSpecializer<T,K,S>.SpeciesData speciesData) {
575 byte[] classFile = generateConcreteSpeciesCodeFile(className, speciesData);
576
577 // load class
578 InvokerBytecodeGenerator.maybeDump(classBCName(className), classFile);
579 Class<?> speciesCode;
580
581 ClassLoader cl = topClass().getClassLoader();
582 ProtectionDomain pd = null;
583 if (cl != null) {
584 pd = AccessController.doPrivileged(
585 new PrivilegedAction<>() {
586 @Override
587 public ProtectionDomain run() {
588 return topClass().getProtectionDomain();
589 }
590 });
591 }
592 try {
593 speciesCode = UNSAFE.defineClass(className, classFile, 0, classFile.length, cl, pd);
594 } catch (Exception ex) {
595 throw newInternalError(ex);
596 }
597
598 return speciesCode.asSubclass(topClass());
599 }
600
601 // These are named like constants because there is only one per specialization scheme:
602 private final String SPECIES_DATA = classBCName(metaType);
603 private final String SPECIES_DATA_SIG = classSig(SPECIES_DATA);
604 private final String SPECIES_DATA_NAME = sdAccessor.getName();
605 private final int SPECIES_DATA_MODS = sdAccessor.getModifiers();
606 private final List<String> TRANSFORM_NAMES; // derived from transformMethods
607 private final List<MethodType> TRANSFORM_TYPES;
608 private final List<Integer> TRANSFORM_MODS;
609 {
610 // Tear apart transformMethods to get the names, types, and modifiers.
611 List<String> tns = new ArrayList<>();
612 List<MethodType> tts = new ArrayList<>();
613 List<Integer> tms = new ArrayList<>();
614 for (int i = 0; i < transformMethods.size(); i++) {
615 MemberName tm = transformMethods.get(i);
616 tns.add(tm.getName());
617 final MethodType tt = tm.getMethodType();
|
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.lang.invoke;
27
28 import jdk.internal.loader.BootLoader;
29 import jdk.internal.org.objectweb.asm.ClassWriter;
30 import jdk.internal.org.objectweb.asm.FieldVisitor;
31 import jdk.internal.org.objectweb.asm.MethodVisitor;
32 import jdk.internal.vm.annotation.Stable;
33 import sun.invoke.util.BytecodeName;
34
35 import java.lang.reflect.Constructor;
36 import java.lang.reflect.Field;
37 import java.lang.reflect.Modifier;
38 import java.security.AccessController;
39 import java.security.PrivilegedAction;
40 import java.util.ArrayList;
41 import java.util.Collections;
42 import java.util.List;
43 import java.util.Objects;
44 import java.util.concurrent.ConcurrentHashMap;
45 import java.util.function.Function;
46
47 import static java.lang.invoke.LambdaForm.*;
48 import static java.lang.invoke.MethodHandleNatives.Constants.REF_getStatic;
49 import static java.lang.invoke.MethodHandleNatives.Constants.REF_putStatic;
50 import static java.lang.invoke.MethodHandleStatics.*;
51 import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
52 import static jdk.internal.org.objectweb.asm.Opcodes.*;
53
54 /**
55 * Class specialization code.
56 * @param <T> top class under which species classes are created.
57 * @param <K> key which identifies individual specializations.
58 * @param <S> species data type.
59 */
560 * final TopClass copyWithExtendL(CT ctarg, ..., Object narg) {
561 * return BMH_SPECIES.transform(L_TYPE).invokeBasic(ctarg, ..., argL0, argL1, argI2, narg);
562 * }
563 * final TopClass copyWithExtendI(CT ctarg, ..., int narg) {
564 * return BMH_SPECIES.transform(I_TYPE).invokeBasic(ctarg, ..., argL0, argL1, argI2, narg);
565 * }
566 * }
567 * </pre>
568 *
569 * @param className of the species
570 * @param speciesData what species we are generating
571 * @return the generated concrete TopClass class
572 */
573 Class<? extends T> generateConcreteSpeciesCode(String className, ClassSpecializer<T,K,S>.SpeciesData speciesData) {
574 byte[] classFile = generateConcreteSpeciesCodeFile(className, speciesData);
575
576 // load class
577 InvokerBytecodeGenerator.maybeDump(classBCName(className), classFile);
578 Class<?> speciesCode;
579
580 MethodHandles.Lookup lookup = IMPL_LOOKUP.in(topClass());
581 speciesCode = AccessController.doPrivileged(new PrivilegedAction<>() {
582 @Override
583 public Class<?> run() {
584 try {
585 return lookup.defineClass(classFile);
586 } catch (Exception ex) {
587 throw newInternalError(ex);
588 }
589 }
590 });
591 return speciesCode.asSubclass(topClass());
592 }
593
594 // These are named like constants because there is only one per specialization scheme:
595 private final String SPECIES_DATA = classBCName(metaType);
596 private final String SPECIES_DATA_SIG = classSig(SPECIES_DATA);
597 private final String SPECIES_DATA_NAME = sdAccessor.getName();
598 private final int SPECIES_DATA_MODS = sdAccessor.getModifiers();
599 private final List<String> TRANSFORM_NAMES; // derived from transformMethods
600 private final List<MethodType> TRANSFORM_TYPES;
601 private final List<Integer> TRANSFORM_MODS;
602 {
603 // Tear apart transformMethods to get the names, types, and modifiers.
604 List<String> tns = new ArrayList<>();
605 List<MethodType> tts = new ArrayList<>();
606 List<Integer> tms = new ArrayList<>();
607 for (int i = 0; i < transformMethods.size(); i++) {
608 MemberName tm = transformMethods.get(i);
609 tns.add(tm.getName());
610 final MethodType tt = tm.getMethodType();
|