< prev index next >

src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java

Print this page

734               .with(StackMapTableAttribute.of(stackMapFrames));
735             DirectCodeBuilder.withMaxs(cb, 3, locals.size()); // enum labels use 3 stack, others use 2
736         };
737     }
738 
739     private static boolean isNotValidPair(Class<?> selectorType, Object caseLabel) {
740         return (selectorType == boolean.class && caseLabel != boolean.class && caseLabel != Boolean.class) ||
741                (selectorType != boolean.class && selectorType.isPrimitive() && (caseLabel == boolean.class || caseLabel == Boolean.class));
742     }
743 
744     /*
745      * Construct the method handle that represents the method int typeSwitch(Object, int, BiPredicate, List)
746      */
747     private static MethodHandle generateTypeSwitch(MethodHandles.Lookup caller, Class<?> selectorType, Object[] labelConstants) {
748         boolean addExtraInfo = needsExtraInfo(selectorType, labelConstants);
749         List<EnumDesc<?>> enumDescs = addExtraInfo ? new ArrayList<>() : null;
750         List<Class<?>> extraClassLabels = addExtraInfo ? new ArrayList<>() : null;
751 
752         byte[] classBytes = ClassFile.of(ClassFile.StackMapsOption.DROP_STACK_MAPS).build(ConstantUtils.binaryNameToDesc(typeSwitchClassName(caller.lookupClass())),
753                 clb -> {
754                     clb.withFlags(AccessFlag.FINAL, AccessFlag.SUPER, AccessFlag.SYNTHETIC)
755                        .withMethodBody("typeSwitch",
756                                        addExtraInfo ? MTD_TYPE_SWITCH_EXTRA : MTD_TYPE_SWITCH,
757                                        ClassFile.ACC_FINAL | ClassFile.ACC_PUBLIC | ClassFile.ACC_STATIC,
758                                        generateTypeSwitchSkeleton(selectorType, labelConstants, enumDescs, extraClassLabels));
759         });
760 
761         try {
762             // this class is linked at the indy callsite; so define a hidden nestmate
763             MethodHandles.Lookup lookup;
764             lookup = caller.defineHiddenClass(classBytes, true, NESTMATE, STRONG);
765             MethodHandle typeSwitch = lookup.findStatic(lookup.lookupClass(),
766                                                         "typeSwitch",
767                                                         addExtraInfo ? MT_TYPE_SWITCH_EXTRA : MT_TYPE_SWITCH);
768             if (addExtraInfo) {
769                 typeSwitch = MethodHandles.insertArguments(typeSwitch, 2, new ResolvedEnumLabels(caller, enumDescs.toArray(new EnumDesc<?>[0])),
770                         List.copyOf(extraClassLabels));
771             }
772             return typeSwitch;
773         } catch (Throwable t) {
774             throw new IllegalArgumentException(t);

734               .with(StackMapTableAttribute.of(stackMapFrames));
735             DirectCodeBuilder.withMaxs(cb, 3, locals.size()); // enum labels use 3 stack, others use 2
736         };
737     }
738 
739     private static boolean isNotValidPair(Class<?> selectorType, Object caseLabel) {
740         return (selectorType == boolean.class && caseLabel != boolean.class && caseLabel != Boolean.class) ||
741                (selectorType != boolean.class && selectorType.isPrimitive() && (caseLabel == boolean.class || caseLabel == Boolean.class));
742     }
743 
744     /*
745      * Construct the method handle that represents the method int typeSwitch(Object, int, BiPredicate, List)
746      */
747     private static MethodHandle generateTypeSwitch(MethodHandles.Lookup caller, Class<?> selectorType, Object[] labelConstants) {
748         boolean addExtraInfo = needsExtraInfo(selectorType, labelConstants);
749         List<EnumDesc<?>> enumDescs = addExtraInfo ? new ArrayList<>() : null;
750         List<Class<?>> extraClassLabels = addExtraInfo ? new ArrayList<>() : null;
751 
752         byte[] classBytes = ClassFile.of(ClassFile.StackMapsOption.DROP_STACK_MAPS).build(ConstantUtils.binaryNameToDesc(typeSwitchClassName(caller.lookupClass())),
753                 clb -> {
754                     clb.withFlags(AccessFlag.FINAL, (PreviewFeatures.isEnabled())  ? AccessFlag.IDENTITY : AccessFlag.SUPER, AccessFlag.SYNTHETIC)
755                        .withMethodBody("typeSwitch",
756                                        addExtraInfo ? MTD_TYPE_SWITCH_EXTRA : MTD_TYPE_SWITCH,
757                                        ClassFile.ACC_FINAL | ClassFile.ACC_PUBLIC | ClassFile.ACC_STATIC,
758                                        generateTypeSwitchSkeleton(selectorType, labelConstants, enumDescs, extraClassLabels));
759         });
760 
761         try {
762             // this class is linked at the indy callsite; so define a hidden nestmate
763             MethodHandles.Lookup lookup;
764             lookup = caller.defineHiddenClass(classBytes, true, NESTMATE, STRONG);
765             MethodHandle typeSwitch = lookup.findStatic(lookup.lookupClass(),
766                                                         "typeSwitch",
767                                                         addExtraInfo ? MT_TYPE_SWITCH_EXTRA : MT_TYPE_SWITCH);
768             if (addExtraInfo) {
769                 typeSwitch = MethodHandles.insertArguments(typeSwitch, 2, new ResolvedEnumLabels(caller, enumDescs.toArray(new EnumDesc<?>[0])),
770                         List.copyOf(extraClassLabels));
771             }
772             return typeSwitch;
773         } catch (Throwable t) {
774             throw new IllegalArgumentException(t);
< prev index next >