changeset 52961:90ac24b3de53 intrinsics-project

Generic invoke for folding
author jlaskey
date Fri, 02 Nov 2018 15:16:09 -0300
parents b649a12d455d
children 33ed69942349
files src/java.base/share/classes/java/lang/String.java src/jdk.compiler/share/classes/com/sun/tools/javac/intrinsics/Intrinsics.java src/jdk.compiler/share/classes/com/sun/tools/javac/intrinsics/StringProcessorFactory.java
diffstat 3 files changed, 75 insertions(+), 69 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/lang/String.java	Fri Nov 02 13:50:55 2018 -0300
+++ b/src/java.base/share/classes/java/lang/String.java	Fri Nov 02 15:16:09 2018 -0300
@@ -2929,6 +2929,7 @@
      *
      * @since 12
      */
+    @IntrinsicCandidate
     public String align() {
         return align(0);
     }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/intrinsics/Intrinsics.java	Fri Nov 02 13:50:55 2018 -0300
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/intrinsics/Intrinsics.java	Fri Nov 02 15:16:09 2018 -0300
@@ -30,6 +30,9 @@
 import java.lang.constant.ConstantDescs;
 import java.lang.constant.MethodTypeDesc;
 import java.lang.invoke.MethodHandles;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
@@ -58,15 +61,6 @@
         }
     }
 
-    static ClassDesc[] describeConstables(Class<?>[] types) {
-        int length = types.length;
-        ClassDesc[] classDescs = new ClassDesc[length];
-        for (int i = 0; i < length; i++) {
-            classDescs[i] = types[i].describeConstable().get();
-        }
-        return classDescs;
-    }
-
     static class EntryKey {
         final ClassDesc owner;
         final String methodName;
@@ -114,6 +108,15 @@
         }
     }
 
+    static ClassDesc[] describeConstables(Class<?>[] types) {
+        int length = types.length;
+        ClassDesc[] classDescs = new ClassDesc[length];
+        for (int i = 0; i < length; i++) {
+            classDescs[i] = types[i].describeConstable().get();
+        }
+        return classDescs;
+    }
+
     static Class<?> getClass(ClassDesc classDesc) {
         try {
             return (Class<?>)classDesc.resolveConstantDesc(LOOKUP);
@@ -123,13 +126,15 @@
         return null;
     }
 
-    static Object getConstant(ConstantDesc constantDesc) {
-        try {
-            return constantDesc.resolveConstantDesc(LOOKUP);
-        } catch (ReflectiveOperationException ex) {
-            // Fall thru
+    static Class<?>[] getClasses(ClassDesc[] classDescs) {
+        int length = classDescs.length;
+        Class<?>[] classes = new Class<?>[length];
+
+        for (int i = 0; i < length; i++) {
+            classes[i] = getClass(classDescs[i]);
         }
-        return null;
+
+        return classes;
     }
 
     static Object getConstant(ClassDesc classDesc, ConstantDesc constantDesc) {
@@ -160,43 +165,29 @@
     }
 
     static Object[] getConstants(ClassDesc[] classDescs,
-                                 ConstantDesc[] constantDescs,
-                                 boolean skipReceiver) {
+                                 ConstantDesc[] constantDescs) {
         int length = constantDescs.length;
-        if (skipReceiver) {
-            Object[] constants = new Object[length - 1];
-            for (int i = 1; i < length; i++) {
-                constants[i - 1] = getConstant(classDescs[i], constantDescs[i]);
-            }
-            return constants;
-        } else {
-            Object[] constants = new Object[length];
-            for (int i = 0; i < length; i++) {
-                constants[i] = getConstant(classDescs[i], constantDescs[i]);
-            }
-            return constants;
+        Object[] constants = new Object[length];
+
+        for (int i = 0; i < length; i++) {
+            constants[i] = getConstant(classDescs[i], constantDescs[i]);
         }
+
+        return constants;
     }
 
-    static Object[] getConstants(ClassDesc[] classDescs,
-                                 ConstantDesc[] constantDescs) {
-        return getConstants(classDescs, constantDescs, false);
-    }
+     static boolean isAllConstants(ConstantDesc[] constantDescs) {
+        int length = constantDescs.length;
 
-    static boolean isAllConstants(ConstantDesc[] constantDescs, boolean skipReceiver) {
-        int length = constantDescs.length;
-        for (int i = skipReceiver ? 1 : 0; i < length; i++) {
+        for (int i = 0; i < length; i++) {
             if (constantDescs[i] == null) {
                 return false;
             }
         }
+
         return true;
     }
 
-    static boolean isAllConstants(ConstantDesc[] constantDescs) {
-        return isAllConstants(constantDescs, false);
-    }
-
     static boolean isArrayVarArg(ClassDesc[] argClassDescs, int i) {
         return i + 1 == argClassDescs.length && argClassDescs[i].isArray();
     }
@@ -224,6 +215,45 @@
         return true;
     }
 
+    static ConstantDesc invoke(Class<?> owner,
+                               String methodName,
+                               boolean isStatic,
+                               ClassDesc returnTypeDesc,
+                               ClassDesc[] argClassDescs,
+                               ConstantDesc[] constantArgs)
+            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+        Class<?>[] argTypes = getClasses(argClassDescs);
+        Object[] constants = getConstants(argClassDescs, constantArgs);
+        Object result;
+
+        if (isStatic) {
+            Method method = owner.getMethod(methodName, argTypes);
+            result = method.invoke(owner, constants);
+        } else {
+            argTypes = Arrays.copyOfRange(argTypes, 1, argTypes.length);
+            Method method = owner.getMethod(methodName, argTypes);
+            Object receiver = constants[0];
+            constants = Arrays.copyOfRange(constants, 1, constants.length);
+            result = method.invoke(receiver, constants);
+        }
+
+        if (result == null) {
+            return ConstantDescs.NULL;
+        } else if (result instanceof Boolean) {
+            return (Boolean)result ? 1 : 0;
+        } else if (result instanceof Byte) {
+            return ((Byte)result).intValue();
+        } else if (result instanceof Short) {
+            return ((Short)result).intValue();
+        } else if (result instanceof Character) {
+            return (int)(Character)result;
+        } else if (result instanceof ConstantDesc) {
+            return (ConstantDesc)result;
+        }
+
+        throw new RuntimeException("Unknown ConstantDesc");
+    }
+
     /**
      * <p><b>This is NOT part of any supported API.</b>
      * @param ownerDesc       method owner
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/intrinsics/StringProcessorFactory.java	Fri Nov 02 13:50:55 2018 -0300
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/intrinsics/StringProcessorFactory.java	Fri Nov 02 15:16:09 2018 -0300
@@ -102,35 +102,10 @@
                 // Fold when all arguments are constant
                 if (Intrinsics.isAllConstants(constantArgs)) {
                     try {
-                        String string = (String)constantArgs[0];
-
-                        switch (methodName) {
-                            case "align": {
-                                if (constantArgs.length == 2) {
-                                    return new Result.Ldc(string.align((Integer)constantArgs[1]));
-                                } else {
-                                    return new Result.Ldc(string.align());
-                                }
-                            }
-                            case "indent": {
-                                return new Result.Ldc(string.indent((Integer)constantArgs[1]));
-                            }
-                            case "length": {
-                                 return new Result.Ldc(string.length());
-                            }
-                            case "repeat": {
-                                return new Result.Ldc(string.repeat((Integer)constantArgs[1]));
-                            }
-                            case "strip": {
-                                return new Result.Ldc(string.strip());
-                            }
-                            case "stripLeading": {
-                                return new Result.Ldc(string.stripLeading());
-                            }
-                            case "stripTrailing": {
-                                return new Result.Ldc(string.stripTrailing());
-                            }
-                        }
+                        ConstantDesc value =
+                                Intrinsics.invoke(String.class, methodName, isStatic,
+                                        methodType.returnType(), argClassDescs, constantArgs);
+                        return new Result.Ldc(value);
                     } catch (Exception ex) {
                         return new Result.None();
                     }