< prev index next >

src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java

Print this page
rev 15544 : imported patch fold_select
rev 15545 : imported patch noperm


  66      */
  67     private static final class Transform extends SoftReference<LambdaForm> {
  68         final long packedBytes;
  69         final byte[] fullBytes;
  70 
  71         // maybe add more for guard with test, catch exception, pointwise type conversions
  72         private static final byte
  73                 BIND_ARG = 1,
  74                 ADD_ARG = 2,
  75                 DUP_ARG = 3,
  76                 SPREAD_ARGS = 4,
  77                 FILTER_ARG = 5,
  78                 FILTER_RETURN = 6,
  79                 FILTER_RETURN_TO_ZERO = 7,
  80                 COLLECT_ARGS = 8,
  81                 COLLECT_ARGS_TO_VOID = 9,
  82                 COLLECT_ARGS_TO_ARRAY = 10,
  83                 FOLD_ARGS = 11,
  84                 FOLD_ARGS_TO_VOID = 12,
  85                 PERMUTE_ARGS = 13,
  86                 LOCAL_TYPES = 14;


  87 
  88         private static final boolean STRESS_TEST = false; // turn on to disable most packing
  89         private static final int
  90                 PACKED_BYTE_SIZE = (STRESS_TEST ? 2 : 4),
  91                 PACKED_BYTE_MASK = (1 << PACKED_BYTE_SIZE) - 1,
  92                 PACKED_BYTE_MAX_LENGTH = (STRESS_TEST ? 3 : 64 / PACKED_BYTE_SIZE);
  93 
  94         private static long packedBytes(byte[] bytes) {
  95             if (bytes.length > PACKED_BYTE_MAX_LENGTH)  return 0;
  96             long pb = 0;
  97             int bitset = 0;
  98             for (int i = 0; i < bytes.length; i++) {
  99                 int b = bytes[i] & 0xFF;
 100                 bitset |= b;
 101                 pb |= (long)b << (i * PACKED_BYTE_SIZE);
 102             }
 103             if (!inRange(bitset))
 104                 return 0;
 105             return pb;
 106         }


 678         Name callCombiner = new Name(combinerType, combinerArgs);
 679 
 680         // insert the two new expressions
 681         int exprPos = lambdaForm.arity();
 682         buf.insertExpression(exprPos+0, getCombiner);
 683         buf.insertExpression(exprPos+1, callCombiner);
 684 
 685         // insert new arguments, if needed
 686         int argPos = pos + resultArity;  // skip result parameter
 687         for (Name newParam : newParams) {
 688             buf.insertParameter(argPos++, newParam);
 689         }
 690         assert(buf.lastIndexOf(callCombiner) == exprPos+1+newParams.length);
 691         if (!dropResult) {
 692             buf.replaceParameterByCopy(pos, exprPos+1+newParams.length);
 693         }
 694 
 695         return buf.endEdit();
 696     }
 697 



































































 698     LambdaForm filterReturnForm(BasicType newType, boolean constantZero) {
 699         byte kind = (constantZero ? Transform.FILTER_RETURN_TO_ZERO : Transform.FILTER_RETURN);
 700         Transform key = Transform.of(kind, newType.ordinal());
 701         LambdaForm form = getInCache(key);
 702         if (form != null) {
 703             assert(form.arity == lambdaForm.arity);
 704             assert(form.returnType() == newType);
 705             return form;
 706         }
 707         LambdaFormBuffer buf = buffer();
 708         buf.startEdit();
 709 
 710         int insPos = lambdaForm.names.length;
 711         Name callFilter;
 712         if (constantZero) {
 713             // Synthesize a constant zero value for the given type.
 714             if (newType == V_TYPE)
 715                 callFilter = null;
 716             else
 717                 callFilter = new Name(constantZero(newType));


 739         }
 740 
 741         if (callFilter != null)
 742             buf.insertExpression(insPos++, callFilter);
 743         buf.setResult(callFilter);
 744 
 745         form = buf.endEdit();
 746         return putInCache(key, form);
 747     }
 748 
 749     LambdaForm foldArgumentsForm(int foldPos, boolean dropResult, MethodType combinerType) {
 750         int combinerArity = combinerType.parameterCount();
 751         byte kind = (dropResult ? Transform.FOLD_ARGS_TO_VOID : Transform.FOLD_ARGS);
 752         Transform key = Transform.of(kind, foldPos, combinerArity);
 753         LambdaForm form = getInCache(key);
 754         if (form != null) {
 755             assert(form.arity == lambdaForm.arity - (kind == Transform.FOLD_ARGS ? 1 : 0));
 756             return form;
 757         }
 758         form = makeArgumentCombinationForm(foldPos, combinerType, true, dropResult);















 759         return putInCache(key, form);
 760     }
 761 
 762     LambdaForm permuteArgumentsForm(int skip, int[] reorder) {
 763         assert(skip == 1);  // skip only the leading MH argument, names[0]
 764         int length = lambdaForm.names.length;
 765         int outArgs = reorder.length;
 766         int inTypes = 0;
 767         boolean nullPerm = true;
 768         for (int i = 0; i < reorder.length; i++) {
 769             int inArg = reorder[i];
 770             if (inArg != i)  nullPerm = false;
 771             inTypes = Math.max(inTypes, inArg+1);
 772         }
 773         assert(skip + reorder.length == lambdaForm.arity);
 774         if (nullPerm)  return lambdaForm;  // do not bother to cache
 775         Transform key = Transform.of(Transform.PERMUTE_ARGS, reorder);
 776         LambdaForm form = getInCache(key);
 777         if (form != null) {
 778             assert(form.arity == skip+inTypes) : form;




  66      */
  67     private static final class Transform extends SoftReference<LambdaForm> {
  68         final long packedBytes;
  69         final byte[] fullBytes;
  70 
  71         // maybe add more for guard with test, catch exception, pointwise type conversions
  72         private static final byte
  73                 BIND_ARG = 1,
  74                 ADD_ARG = 2,
  75                 DUP_ARG = 3,
  76                 SPREAD_ARGS = 4,
  77                 FILTER_ARG = 5,
  78                 FILTER_RETURN = 6,
  79                 FILTER_RETURN_TO_ZERO = 7,
  80                 COLLECT_ARGS = 8,
  81                 COLLECT_ARGS_TO_VOID = 9,
  82                 COLLECT_ARGS_TO_ARRAY = 10,
  83                 FOLD_ARGS = 11,
  84                 FOLD_ARGS_TO_VOID = 12,
  85                 PERMUTE_ARGS = 13,
  86                 LOCAL_TYPES = 14,
  87                 FOLD_SELECT_ARGS = 15,
  88                 FOLD_SELECT_ARGS_TO_VOID = 16;
  89 
  90         private static final boolean STRESS_TEST = false; // turn on to disable most packing
  91         private static final int
  92                 PACKED_BYTE_SIZE = (STRESS_TEST ? 2 : 4),
  93                 PACKED_BYTE_MASK = (1 << PACKED_BYTE_SIZE) - 1,
  94                 PACKED_BYTE_MAX_LENGTH = (STRESS_TEST ? 3 : 64 / PACKED_BYTE_SIZE);
  95 
  96         private static long packedBytes(byte[] bytes) {
  97             if (bytes.length > PACKED_BYTE_MAX_LENGTH)  return 0;
  98             long pb = 0;
  99             int bitset = 0;
 100             for (int i = 0; i < bytes.length; i++) {
 101                 int b = bytes[i] & 0xFF;
 102                 bitset |= b;
 103                 pb |= (long)b << (i * PACKED_BYTE_SIZE);
 104             }
 105             if (!inRange(bitset))
 106                 return 0;
 107             return pb;
 108         }


 680         Name callCombiner = new Name(combinerType, combinerArgs);
 681 
 682         // insert the two new expressions
 683         int exprPos = lambdaForm.arity();
 684         buf.insertExpression(exprPos+0, getCombiner);
 685         buf.insertExpression(exprPos+1, callCombiner);
 686 
 687         // insert new arguments, if needed
 688         int argPos = pos + resultArity;  // skip result parameter
 689         for (Name newParam : newParams) {
 690             buf.insertParameter(argPos++, newParam);
 691         }
 692         assert(buf.lastIndexOf(callCombiner) == exprPos+1+newParams.length);
 693         if (!dropResult) {
 694             buf.replaceParameterByCopy(pos, exprPos+1+newParams.length);
 695         }
 696 
 697         return buf.endEdit();
 698     }
 699 
 700     
 701     private LambdaForm makeArgumentCombinationForm(int pos,
 702                                                    MethodType combinerType,
 703                                                    int[] argPositions,
 704                                                    boolean keepArguments,
 705                                                    boolean dropResult) {
 706         LambdaFormBuffer buf = buffer();
 707         buf.startEdit();
 708         int combinerArity = combinerType.parameterCount();
 709         assert(combinerArity == argPositions.length);
 710 
 711         int resultArity = (dropResult ? 0 : 1);
 712 
 713         assert(pos <= lambdaForm.arity);
 714         assert(pos > 0);  // cannot filter the MH arg itself
 715         assert(combinerType == combinerType.basicType());
 716         assert(combinerType.returnType() != void.class || dropResult);
 717 
 718         BoundMethodHandle.SpeciesData oldData = oldSpeciesData();
 719         BoundMethodHandle.SpeciesData newData = newSpeciesData(L_TYPE);
 720 
 721         // The newly created LF will run with a different BMH.
 722         // Switch over any pre-existing BMH field references to the new BMH class.
 723         Name oldBaseAddress = lambdaForm.parameter(0);  // BMH holding the values
 724         buf.replaceFunctions(oldData.getterFunctions(), newData.getterFunctions(), oldBaseAddress);
 725         Name newBaseAddress = oldBaseAddress.withConstraint(newData);
 726         buf.renameParameter(0, newBaseAddress);
 727 
 728         Name getCombiner = new Name(newData.getterFunction(oldData.fieldCount()), newBaseAddress);
 729         Object[] combinerArgs = new Object[1 + combinerArity];
 730         combinerArgs[0] = getCombiner;
 731         Name[] newParams;
 732         if (keepArguments) {
 733             newParams = new Name[0];
 734             for (int i = 0; i < combinerArity; i++) {
 735                 combinerArgs[i + 1] = lambdaForm.parameter(1 + argPositions[i]);
 736                 assert (basicType(combinerType.parameterType(i)) == lambdaForm.parameterType(1 + argPositions[i]));
 737             }
 738         } else {
 739             newParams = new Name[combinerArity];
 740             for (int i = 0; i < newParams.length; i++) {
 741                 newParams[i] = lambdaForm.parameter(1 + argPositions[i]);
 742                 assert (basicType(combinerType.parameterType(i)) == lambdaForm.parameterType(1 + argPositions[i]));
 743             }
 744             System.arraycopy(newParams, 0,
 745                              combinerArgs, 1, combinerArity);
 746         }
 747         Name callCombiner = new Name(combinerType, combinerArgs);
 748 
 749         // insert the two new expressions
 750         int exprPos = lambdaForm.arity();
 751         buf.insertExpression(exprPos+0, getCombiner);
 752         buf.insertExpression(exprPos+1, callCombiner);
 753 
 754         // insert new arguments, if needed
 755         int argPos = pos + resultArity;  // skip result parameter
 756         for (Name newParam : newParams) {
 757             buf.insertParameter(argPos++, newParam);
 758         }
 759         assert(buf.lastIndexOf(callCombiner) == exprPos+1+newParams.length);
 760         if (!dropResult) {
 761             buf.replaceParameterByCopy(pos, exprPos+1+newParams.length);
 762         }
 763 
 764         return buf.endEdit();
 765     }
 766 
 767     LambdaForm filterReturnForm(BasicType newType, boolean constantZero) {
 768         byte kind = (constantZero ? Transform.FILTER_RETURN_TO_ZERO : Transform.FILTER_RETURN);
 769         Transform key = Transform.of(kind, newType.ordinal());
 770         LambdaForm form = getInCache(key);
 771         if (form != null) {
 772             assert(form.arity == lambdaForm.arity);
 773             assert(form.returnType() == newType);
 774             return form;
 775         }
 776         LambdaFormBuffer buf = buffer();
 777         buf.startEdit();
 778 
 779         int insPos = lambdaForm.names.length;
 780         Name callFilter;
 781         if (constantZero) {
 782             // Synthesize a constant zero value for the given type.
 783             if (newType == V_TYPE)
 784                 callFilter = null;
 785             else
 786                 callFilter = new Name(constantZero(newType));


 808         }
 809 
 810         if (callFilter != null)
 811             buf.insertExpression(insPos++, callFilter);
 812         buf.setResult(callFilter);
 813 
 814         form = buf.endEdit();
 815         return putInCache(key, form);
 816     }
 817 
 818     LambdaForm foldArgumentsForm(int foldPos, boolean dropResult, MethodType combinerType) {
 819         int combinerArity = combinerType.parameterCount();
 820         byte kind = (dropResult ? Transform.FOLD_ARGS_TO_VOID : Transform.FOLD_ARGS);
 821         Transform key = Transform.of(kind, foldPos, combinerArity);
 822         LambdaForm form = getInCache(key);
 823         if (form != null) {
 824             assert(form.arity == lambdaForm.arity - (kind == Transform.FOLD_ARGS ? 1 : 0));
 825             return form;
 826         }
 827         form = makeArgumentCombinationForm(foldPos, combinerType, true, dropResult);
 828         return putInCache(key, form);
 829     }
 830 
 831     LambdaForm foldArgumentsForm(int foldPos, boolean dropResult, MethodType combinerType, int ... argPositions) {
 832         byte kind = (dropResult ? Transform.FOLD_SELECT_ARGS_TO_VOID
 833                                 : Transform.FOLD_SELECT_ARGS);
 834         int[] keyArgs = Arrays.copyOf(argPositions, argPositions.length + 1);
 835         keyArgs[argPositions.length] = foldPos;
 836         Transform key = Transform.of(kind, keyArgs);
 837         LambdaForm form = getInCache(key);
 838         if (form != null) {
 839             assert(form.arity == lambdaForm.arity - (kind == Transform.FOLD_SELECT_ARGS ? 1 : 0));
 840             return form;
 841         }
 842         form = makeArgumentCombinationForm(foldPos, combinerType, argPositions, true, dropResult);
 843         return putInCache(key, form);
 844     }
 845 
 846     LambdaForm permuteArgumentsForm(int skip, int[] reorder) {
 847         assert(skip == 1);  // skip only the leading MH argument, names[0]
 848         int length = lambdaForm.names.length;
 849         int outArgs = reorder.length;
 850         int inTypes = 0;
 851         boolean nullPerm = true;
 852         for (int i = 0; i < reorder.length; i++) {
 853             int inArg = reorder[i];
 854             if (inArg != i)  nullPerm = false;
 855             inTypes = Math.max(inTypes, inArg+1);
 856         }
 857         assert(skip + reorder.length == lambdaForm.arity);
 858         if (nullPerm)  return lambdaForm;  // do not bother to cache
 859         Transform key = Transform.of(Transform.PERMUTE_ARGS, reorder);
 860         LambdaForm form = getInCache(key);
 861         if (form != null) {
 862             assert(form.arity == skip+inTypes) : form;


< prev index next >