< prev index next >

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

Print this page

710             }
711             stackMapFrames.add(StackMapFrameInfo.of(dflt, locals, List.of()));
712             cb.labelBinding(dflt)
713               .loadConstant(labelConstants.length)
714               .ireturn()
715               .with(StackMapTableAttribute.of(stackMapFrames));
716             DirectCodeBuilder.withMaxs(cb, 3, locals.size()); // enum labels use 3 stack, others use 2
717         };
718     }
719 
720     /*
721      * Construct the method handle that represents the method int typeSwitch(Object, int, BiPredicate, List)
722      */
723     private static MethodHandle generateTypeSwitch(MethodHandles.Lookup caller, Class<?> selectorType, Object[] labelConstants) {
724         boolean addExtraInfo = needsExtraInfo(selectorType, labelConstants);
725         List<EnumDesc<?>> enumDescs = addExtraInfo ? new ArrayList<>() : null;
726         List<Class<?>> extraClassLabels = addExtraInfo ? new ArrayList<>() : null;
727 
728         byte[] classBytes = ClassFile.of(ClassFile.StackMapsOption.DROP_STACK_MAPS).build(ConstantUtils.binaryNameToDesc(typeSwitchClassName(caller.lookupClass())),
729                 clb -> {
730                     clb.withFlags(AccessFlag.FINAL, AccessFlag.SUPER, AccessFlag.SYNTHETIC)
731                        .withMethodBody("typeSwitch",
732                                        addExtraInfo ? MTD_TYPE_SWITCH_EXTRA : MTD_TYPE_SWITCH,
733                                        ClassFile.ACC_FINAL | ClassFile.ACC_PUBLIC | ClassFile.ACC_STATIC,
734                                        generateTypeSwitchSkeleton(selectorType, labelConstants, enumDescs, extraClassLabels));
735         });
736 
737         try {
738             // this class is linked at the indy callsite; so define a hidden nestmate
739             MethodHandles.Lookup lookup;
740             lookup = caller.defineHiddenClass(classBytes, true, NESTMATE, STRONG);
741             MethodHandle typeSwitch = lookup.findStatic(lookup.lookupClass(),
742                                                         "typeSwitch",
743                                                         addExtraInfo ? MT_TYPE_SWITCH_EXTRA : MT_TYPE_SWITCH);
744             if (addExtraInfo) {
745                 typeSwitch = MethodHandles.insertArguments(typeSwitch, 2, new ResolvedEnumLabels(caller, enumDescs.toArray(new EnumDesc<?>[0])),
746                         List.copyOf(extraClassLabels));
747             }
748             return typeSwitch;
749         } catch (Throwable t) {
750             throw new IllegalArgumentException(t);

710             }
711             stackMapFrames.add(StackMapFrameInfo.of(dflt, locals, List.of()));
712             cb.labelBinding(dflt)
713               .loadConstant(labelConstants.length)
714               .ireturn()
715               .with(StackMapTableAttribute.of(stackMapFrames));
716             DirectCodeBuilder.withMaxs(cb, 3, locals.size()); // enum labels use 3 stack, others use 2
717         };
718     }
719 
720     /*
721      * Construct the method handle that represents the method int typeSwitch(Object, int, BiPredicate, List)
722      */
723     private static MethodHandle generateTypeSwitch(MethodHandles.Lookup caller, Class<?> selectorType, Object[] labelConstants) {
724         boolean addExtraInfo = needsExtraInfo(selectorType, labelConstants);
725         List<EnumDesc<?>> enumDescs = addExtraInfo ? new ArrayList<>() : null;
726         List<Class<?>> extraClassLabels = addExtraInfo ? new ArrayList<>() : null;
727 
728         byte[] classBytes = ClassFile.of(ClassFile.StackMapsOption.DROP_STACK_MAPS).build(ConstantUtils.binaryNameToDesc(typeSwitchClassName(caller.lookupClass())),
729                 clb -> {
730                     clb.withFlags(AccessFlag.FINAL, (PreviewFeatures.isEnabled())  ? AccessFlag.IDENTITY : AccessFlag.SUPER, AccessFlag.SYNTHETIC)
731                        .withMethodBody("typeSwitch",
732                                        addExtraInfo ? MTD_TYPE_SWITCH_EXTRA : MTD_TYPE_SWITCH,
733                                        ClassFile.ACC_FINAL | ClassFile.ACC_PUBLIC | ClassFile.ACC_STATIC,
734                                        generateTypeSwitchSkeleton(selectorType, labelConstants, enumDescs, extraClassLabels));
735         });
736 
737         try {
738             // this class is linked at the indy callsite; so define a hidden nestmate
739             MethodHandles.Lookup lookup;
740             lookup = caller.defineHiddenClass(classBytes, true, NESTMATE, STRONG);
741             MethodHandle typeSwitch = lookup.findStatic(lookup.lookupClass(),
742                                                         "typeSwitch",
743                                                         addExtraInfo ? MT_TYPE_SWITCH_EXTRA : MT_TYPE_SWITCH);
744             if (addExtraInfo) {
745                 typeSwitch = MethodHandles.insertArguments(typeSwitch, 2, new ResolvedEnumLabels(caller, enumDescs.toArray(new EnumDesc<?>[0])),
746                         List.copyOf(extraClassLabels));
747             }
748             return typeSwitch;
749         } catch (Throwable t) {
750             throw new IllegalArgumentException(t);
< prev index next >