< prev index next >

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

Print this page
rev 15320 : 8163370: Reduce number of classes loaded by common usage of java.lang.invoke
Reviewed-by: igerasim, psandoz

@@ -58,29 +58,34 @@
         // It helps caching and customized LambdaForms reuse transformCache field to keep a link to uncustomized version.
         return new LambdaFormEditor(lambdaForm.uncustomize());
     }
 
     /** A description of a cached transform, possibly associated with the result of the transform.
-     *  The logical content is a sequence of byte values, starting with a Kind.ordinal value.
+     *  The logical content is a sequence of byte values, starting with a kind value.
      *  The sequence is unterminated, ending with an indefinite number of zero bytes.
      *  Sequences that are simple (short enough and with small enough values) pack into a 64-bit long.
      */
     private static final class Transform extends SoftReference<LambdaForm> {
         final long packedBytes;
         final byte[] fullBytes;
 
-        private enum Kind {
-            NO_KIND,  // necessary because ordinal must be greater than zero
-            BIND_ARG, ADD_ARG, DUP_ARG,
-            SPREAD_ARGS,
-            FILTER_ARG, FILTER_RETURN, FILTER_RETURN_TO_ZERO,
-            COLLECT_ARGS, COLLECT_ARGS_TO_VOID, COLLECT_ARGS_TO_ARRAY,
-            FOLD_ARGS, FOLD_ARGS_TO_VOID,
-            PERMUTE_ARGS,
-            LOCAL_TYPES
-            //maybe add more for guard with test, catch exception, pointwise type conversions
-        }
+        // maybe add more for guard with test, catch exception, pointwise type conversions
+        private static final byte
+                BIND_ARG = 1,
+                ADD_ARG = 2,
+                DUP_ARG = 3,
+                SPREAD_ARGS = 4,
+                FILTER_ARG = 5,
+                FILTER_RETURN = 6,
+                FILTER_RETURN_TO_ZERO = 7,
+                COLLECT_ARGS = 8,
+                COLLECT_ARGS_TO_VOID = 9,
+                COLLECT_ARGS_TO_ARRAY = 10,
+                FOLD_ARGS = 11,
+                FOLD_ARGS_TO_VOID = 12,
+                PERMUTE_ARGS = 13,
+                LOCAL_TYPES = 14;
 
         private static final boolean STRESS_TEST = false; // turn on to disable most packing
         private static final int
                 PACKED_BYTE_SIZE = (STRESS_TEST ? 2 : 4),
                 PACKED_BYTE_MASK = (1 << PACKED_BYTE_SIZE) - 1,

@@ -129,24 +134,10 @@
             }
             assert(packedBytes(bytes) == 0);
             return bytes;
         }
 
-        private byte byteAt(int i) {
-            long pb = packedBytes;
-            if (pb == 0) {
-                if (i >= fullBytes.length)  return 0;
-                return fullBytes[i];
-            }
-            assert(fullBytes == null);
-            if (i > PACKED_BYTE_MAX_LENGTH)  return 0;
-            int pos = (i * PACKED_BYTE_SIZE);
-            return (byte)((pb >>> pos) & PACKED_BYTE_MASK);
-        }
-
-        Kind kind() { return Kind.values()[byteAt(0)]; }
-
         private Transform(long packedBytes, byte[] fullBytes, LambdaForm result) {
             super(result);
             this.packedBytes = packedBytes;
             this.fullBytes = fullBytes;
         }

@@ -160,48 +151,43 @@
 
         private static byte bval(int b) {
             assert((b & 0xFF) == b);  // incoming value must fit in *unsigned* byte
             return (byte)b;
         }
-        private static byte bval(Kind k) {
-            return bval(k.ordinal());
-        }
-        static Transform of(Kind k, int b1) {
+        static Transform of(byte k, int b1) {
             byte b0 = bval(k);
             if (inRange(b0 | b1))
                 return new Transform(packedBytes(b0, b1));
             else
                 return new Transform(fullBytes(b0, b1));
         }
-        static Transform of(Kind k, int b1, int b2) {
-            byte b0 = (byte) k.ordinal();
+        static Transform of(byte b0, int b1, int b2) {
             if (inRange(b0 | b1 | b2))
                 return new Transform(packedBytes(b0, b1, b2));
             else
                 return new Transform(fullBytes(b0, b1, b2));
         }
-        static Transform of(Kind k, int b1, int b2, int b3) {
-            byte b0 = (byte) k.ordinal();
+        static Transform of(byte b0, int b1, int b2, int b3) {
             if (inRange(b0 | b1 | b2 | b3))
                 return new Transform(packedBytes(b0, b1, b2, b3));
             else
                 return new Transform(fullBytes(b0, b1, b2, b3));
         }
         private static final byte[] NO_BYTES = {};
-        static Transform of(Kind k, int... b123) {
-            return ofBothArrays(k, b123, NO_BYTES);
+        static Transform of(byte kind, int... b123) {
+            return ofBothArrays(kind, b123, NO_BYTES);
         }
-        static Transform of(Kind k, int b1, byte[] b234) {
-            return ofBothArrays(k, new int[]{ b1 }, b234);
+        static Transform of(byte kind, int b1, byte[] b234) {
+            return ofBothArrays(kind, new int[]{ b1 }, b234);
         }
-        static Transform of(Kind k, int b1, int b2, byte[] b345) {
-            return ofBothArrays(k, new int[]{ b1, b2 }, b345);
+        static Transform of(byte kind, int b1, int b2, byte[] b345) {
+            return ofBothArrays(kind, new int[]{ b1, b2 }, b345);
         }
-        private static Transform ofBothArrays(Kind k, int[] b123, byte[] b456) {
+        private static Transform ofBothArrays(byte kind, int[] b123, byte[] b456) {
             byte[] fullBytes = new byte[1 + b123.length + b456.length];
             int i = 0;
-            fullBytes[i++] = bval(k);
+            fullBytes[i++] = bval(kind);
             for (int bv : b123) {
                 fullBytes[i++] = bval(bv);
             }
             for (byte bv : b456) {
                 fullBytes[i++] = bv;

@@ -447,11 +433,11 @@
 
     /// Editing methods for lambda forms.
     // Each editing method can (potentially) cache the edited LF so that it can be reused later.
 
     LambdaForm bindArgumentForm(int pos) {
-        Transform key = Transform.of(Transform.Kind.BIND_ARG, pos);
+        Transform key = Transform.of(Transform.BIND_ARG, pos);
         LambdaForm form = getInCache(key);
         if (form != null) {
             assert(form.parameterConstraint(0) == newSpeciesData(lambdaForm.parameterType(pos)));
             return form;
         }

@@ -482,11 +468,11 @@
         form = buf.endEdit();
         return putInCache(key, form);
     }
 
     LambdaForm addArgumentForm(int pos, BasicType type) {
-        Transform key = Transform.of(Transform.Kind.ADD_ARG, pos, type.ordinal());
+        Transform key = Transform.of(Transform.ADD_ARG, pos, type.ordinal());
         LambdaForm form = getInCache(key);
         if (form != null) {
             assert(form.arity == lambdaForm.arity+1);
             assert(form.parameterType(pos) == type);
             return form;

@@ -499,11 +485,11 @@
         form = buf.endEdit();
         return putInCache(key, form);
     }
 
     LambdaForm dupArgumentForm(int srcPos, int dstPos) {
-        Transform key = Transform.of(Transform.Kind.DUP_ARG, srcPos, dstPos);
+        Transform key = Transform.of(Transform.DUP_ARG, srcPos, dstPos);
         LambdaForm form = getInCache(key);
         if (form != null) {
             assert(form.arity == lambdaForm.arity-1);
             return form;
         }

@@ -528,11 +514,11 @@
         if (bt.basicTypeClass() != elementType) {
             if (elementType.isPrimitive()) {
                 elementTypeKey = TYPE_LIMIT + Wrapper.forPrimitiveType(elementType).ordinal();
             }
         }
-        Transform key = Transform.of(Transform.Kind.SPREAD_ARGS, pos, elementTypeKey, arrayLength);
+        Transform key = Transform.of(Transform.SPREAD_ARGS, pos, elementTypeKey, arrayLength);
         LambdaForm form = getInCache(key);
         if (form != null) {
             assert(form.arity == lambdaForm.arity - arrayLength + 1);
             return form;
         }

@@ -567,13 +553,13 @@
         boolean dropResult = (collectorType.returnType() == void.class);
         if (collectorArity == 1 && !dropResult) {
             return filterArgumentForm(pos, basicType(collectorType.parameterType(0)));
         }
         byte[] newTypes = BasicType.basicTypesOrd(collectorType.parameterArray());
-        Transform.Kind kind = (dropResult
-                ? Transform.Kind.COLLECT_ARGS_TO_VOID
-                : Transform.Kind.COLLECT_ARGS);
+        byte kind = (dropResult
+                ? Transform.COLLECT_ARGS_TO_VOID
+                : Transform.COLLECT_ARGS);
         if (dropResult && collectorArity == 0)  pos = 1;  // pure side effect
         Transform key = Transform.of(kind, pos, collectorArity, newTypes);
         LambdaForm form = getInCache(key);
         if (form != null) {
             assert(form.arity == lambdaForm.arity - (dropResult ? 0 : 1) + collectorArity);

@@ -596,11 +582,11 @@
             if (!elementType.isPrimitive())
                 return null;
             argTypeKey = TYPE_LIMIT + Wrapper.forPrimitiveType(elementType).ordinal();
         }
         assert(collectorType.parameterList().equals(Collections.nCopies(collectorArity, elementType)));
-        Transform.Kind kind = Transform.Kind.COLLECT_ARGS_TO_ARRAY;
+        byte kind = Transform.COLLECT_ARGS_TO_ARRAY;
         Transform key = Transform.of(kind, pos, collectorArity, argTypeKey);
         LambdaForm form = getInCache(key);
         if (form != null) {
             assert(form.arity == lambdaForm.arity - 1 + collectorArity);
             return form;

@@ -632,11 +618,11 @@
         form = buf.endEdit();
         return putInCache(key, form);
     }
 
     LambdaForm filterArgumentForm(int pos, BasicType newType) {
-        Transform key = Transform.of(Transform.Kind.FILTER_ARG, pos, newType.ordinal());
+        Transform key = Transform.of(Transform.FILTER_ARG, pos, newType.ordinal());
         LambdaForm form = getInCache(key);
         if (form != null) {
             assert(form.arity == lambdaForm.arity);
             assert(form.parameterType(pos) == newType);
             return form;

@@ -708,11 +694,11 @@
 
         return buf.endEdit();
     }
 
     LambdaForm filterReturnForm(BasicType newType, boolean constantZero) {
-        Transform.Kind kind = (constantZero ? Transform.Kind.FILTER_RETURN_TO_ZERO : Transform.Kind.FILTER_RETURN);
+        byte kind = (constantZero ? Transform.FILTER_RETURN_TO_ZERO : Transform.FILTER_RETURN);
         Transform key = Transform.of(kind, newType.ordinal());
         LambdaForm form = getInCache(key);
         if (form != null) {
             assert(form.arity == lambdaForm.arity);
             assert(form.returnType() == newType);

@@ -760,15 +746,15 @@
         return putInCache(key, form);
     }
 
     LambdaForm foldArgumentsForm(int foldPos, boolean dropResult, MethodType combinerType) {
         int combinerArity = combinerType.parameterCount();
-        Transform.Kind kind = (dropResult ? Transform.Kind.FOLD_ARGS_TO_VOID : Transform.Kind.FOLD_ARGS);
+        byte kind = (dropResult ? Transform.FOLD_ARGS_TO_VOID : Transform.FOLD_ARGS);
         Transform key = Transform.of(kind, foldPos, combinerArity);
         LambdaForm form = getInCache(key);
         if (form != null) {
-            assert(form.arity == lambdaForm.arity - (kind == Transform.Kind.FOLD_ARGS ? 1 : 0));
+            assert(form.arity == lambdaForm.arity - (kind == Transform.FOLD_ARGS ? 1 : 0));
             return form;
         }
         form = makeArgumentCombinationForm(foldPos, combinerType, true, dropResult);
         return putInCache(key, form);
     }

@@ -784,11 +770,11 @@
             if (inArg != i)  nullPerm = false;
             inTypes = Math.max(inTypes, inArg+1);
         }
         assert(skip + reorder.length == lambdaForm.arity);
         if (nullPerm)  return lambdaForm;  // do not bother to cache
-        Transform key = Transform.of(Transform.Kind.PERMUTE_ARGS, reorder);
+        Transform key = Transform.of(Transform.PERMUTE_ARGS, reorder);
         LambdaForm form = getInCache(key);
         if (form != null) {
             assert(form.arity == skip+inTypes) : form;
             return form;
         }

@@ -853,11 +839,11 @@
     LambdaForm noteLoopLocalTypesForm(int pos, BasicType[] localTypes) {
         assert(lambdaForm.isLoop(pos));
         int[] desc = BasicType.basicTypeOrds(localTypes);
         desc = Arrays.copyOf(desc, desc.length + 1);
         desc[desc.length - 1] = pos;
-        Transform key = Transform.of(Transform.Kind.LOCAL_TYPES, desc);
+        Transform key = Transform.of(Transform.LOCAL_TYPES, desc);
         LambdaForm form = getInCache(key);
         if (form != null) {
             return form;
         }
 
< prev index next >