src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java
changeset 52226 b4b932c6001f
parent 47753 a2008587c13f
child 52486 6f5948597697
equal deleted inserted replaced
52225:3c12f0c0a68c 52226:b4b932c6001f
     1 /*
     1 /*
     2  * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    83                 FOLD_ARGS = 11,
    83                 FOLD_ARGS = 11,
    84                 FOLD_ARGS_TO_VOID = 12,
    84                 FOLD_ARGS_TO_VOID = 12,
    85                 PERMUTE_ARGS = 13,
    85                 PERMUTE_ARGS = 13,
    86                 LOCAL_TYPES = 14,
    86                 LOCAL_TYPES = 14,
    87                 FOLD_SELECT_ARGS = 15,
    87                 FOLD_SELECT_ARGS = 15,
    88                 FOLD_SELECT_ARGS_TO_VOID = 16;
    88                 FOLD_SELECT_ARGS_TO_VOID = 16,
       
    89                 FILTER_SELECT_ARGS = 17;
    89 
    90 
    90         private static final boolean STRESS_TEST = false; // turn on to disable most packing
    91         private static final boolean STRESS_TEST = false; // turn on to disable most packing
    91         private static final int
    92         private static final int
    92                 PACKED_BYTE_SIZE = (STRESS_TEST ? 2 : 4),
    93                 PACKED_BYTE_SIZE = (STRESS_TEST ? 2 : 4),
    93                 PACKED_BYTE_MASK = (1 << PACKED_BYTE_SIZE) - 1,
    94                 PACKED_BYTE_MASK = (1 << PACKED_BYTE_SIZE) - 1,
   728         buf.renameParameter(0, newBaseAddress);
   729         buf.renameParameter(0, newBaseAddress);
   729 
   730 
   730         Name getCombiner = new Name(newData.getterFunction(oldData.fieldCount()), newBaseAddress);
   731         Name getCombiner = new Name(newData.getterFunction(oldData.fieldCount()), newBaseAddress);
   731         Object[] combinerArgs = new Object[1 + combinerArity];
   732         Object[] combinerArgs = new Object[1 + combinerArity];
   732         combinerArgs[0] = getCombiner;
   733         combinerArgs[0] = getCombiner;
   733         Name[] newParams;
   734         Name newParam = null;
   734         if (keepArguments) {
   735         if (keepArguments) {
   735             newParams = new Name[0];
       
   736             for (int i = 0; i < combinerArity; i++) {
   736             for (int i = 0; i < combinerArity; i++) {
   737                 combinerArgs[i + 1] = lambdaForm.parameter(1 + argPositions[i]);
   737                 combinerArgs[i + 1] = lambdaForm.parameter(1 + argPositions[i]);
   738                 assert (basicType(combinerType.parameterType(i)) == lambdaForm.parameterType(1 + argPositions[i]));
   738                 assert (basicType(combinerType.parameterType(i)) == lambdaForm.parameterType(1 + argPositions[i]));
   739             }
   739             }
   740         } else {
   740         } else {
   741             newParams = new Name[combinerArity];
   741             newParam = new Name(pos, BasicType.basicType(combinerType.returnType()));
   742             for (int i = 0; i < newParams.length; i++) {
   742             for (int i = 0; i < combinerArity; i++) {
   743                 newParams[i] = lambdaForm.parameter(1 + argPositions[i]);
   743                 int argPos = 1 + argPositions[i];
       
   744                 if (argPos == pos) {
       
   745                     combinerArgs[i + 1] = newParam;
       
   746                 } else {
       
   747                     combinerArgs[i + 1] = lambdaForm.parameter(argPos);
       
   748                 }
   744                 assert (basicType(combinerType.parameterType(i)) == lambdaForm.parameterType(1 + argPositions[i]));
   749                 assert (basicType(combinerType.parameterType(i)) == lambdaForm.parameterType(1 + argPositions[i]));
   745             }
   750             }
   746             System.arraycopy(newParams, 0,
       
   747                              combinerArgs, 1, combinerArity);
       
   748         }
   751         }
   749         Name callCombiner = new Name(combinerType, combinerArgs);
   752         Name callCombiner = new Name(combinerType, combinerArgs);
   750 
   753 
   751         // insert the two new expressions
   754         // insert the two new expressions
   752         int exprPos = lambdaForm.arity();
   755         int exprPos = lambdaForm.arity();
   753         buf.insertExpression(exprPos+0, getCombiner);
   756         buf.insertExpression(exprPos+0, getCombiner);
   754         buf.insertExpression(exprPos+1, callCombiner);
   757         buf.insertExpression(exprPos+1, callCombiner);
   755 
   758 
   756         // insert new arguments, if needed
   759         // insert new arguments, if needed
   757         int argPos = pos + resultArity;  // skip result parameter
   760         int argPos = pos + resultArity;  // skip result parameter
   758         for (Name newParam : newParams) {
   761         if (newParam != null) {
   759             buf.insertParameter(argPos++, newParam);
   762             buf.insertParameter(argPos++, newParam);
   760         }
   763             exprPos++;
   761         assert(buf.lastIndexOf(callCombiner) == exprPos+1+newParams.length);
   764         }
       
   765         assert(buf.lastIndexOf(callCombiner) == exprPos+1);
   762         if (!dropResult) {
   766         if (!dropResult) {
   763             buf.replaceParameterByCopy(pos, exprPos+1+newParams.length);
   767             buf.replaceParameterByCopy(pos, exprPos+1);
   764         }
   768         }
   765 
   769 
   766         return buf.endEdit();
   770         return buf.endEdit();
   767     }
   771     }
   768 
   772 
   843         }
   847         }
   844         form = makeArgumentCombinationForm(foldPos, combinerType, argPositions, true, dropResult);
   848         form = makeArgumentCombinationForm(foldPos, combinerType, argPositions, true, dropResult);
   845         return putInCache(key, form);
   849         return putInCache(key, form);
   846     }
   850     }
   847 
   851 
       
   852     LambdaForm filterArgumentsForm(int filterPos, MethodType combinerType, int ... argPositions) {
       
   853         byte kind = Transform.FILTER_SELECT_ARGS;
       
   854         int[] keyArgs = Arrays.copyOf(argPositions, argPositions.length + 1);
       
   855         keyArgs[argPositions.length] = filterPos;
       
   856         Transform key = Transform.of(kind, keyArgs);
       
   857         LambdaForm form = getInCache(key);
       
   858         if (form != null) {
       
   859             assert(form.arity == lambdaForm.arity);
       
   860             return form;
       
   861         }
       
   862         form = makeArgumentCombinationForm(filterPos, combinerType, argPositions, false, false);
       
   863         return putInCache(key, form);
       
   864     }
       
   865 
   848     LambdaForm permuteArgumentsForm(int skip, int[] reorder) {
   866     LambdaForm permuteArgumentsForm(int skip, int[] reorder) {
   849         assert(skip == 1);  // skip only the leading MH argument, names[0]
   867         assert(skip == 1);  // skip only the leading MH argument, names[0]
   850         int length = lambdaForm.names.length;
   868         int length = lambdaForm.names.length;
   851         int outArgs = reorder.length;
   869         int outArgs = reorder.length;
   852         int inTypes = 0;
   870         int inTypes = 0;