changeset 52235:1b7fae44af66 lworld

8212563: [lworld] Javac should emit `Q' descriptors for value types.
author sadayapalam
date Wed, 17 Oct 2018 12:22:59 +0530
parents 2045f7495341
children 71fc0e24ac49
files src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassFile.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java src/jdk.jdeps/share/classes/com/sun/tools/classfile/Descriptor.java src/jdk.jdeps/share/classes/com/sun/tools/classfile/Signature.java src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/Pretty.java src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/scan/MethodSig.java test/langtools/tools/javac/valhalla/lworld-values/QTypeTest.java test/langtools/tools/javac/valhalla/lworld-values/QTypedValue.java
diffstat 10 files changed, 200 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java	Mon Oct 15 16:40:22 2018 +0530
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java	Wed Oct 17 12:22:59 2018 +0530
@@ -99,6 +99,7 @@
     final Name capturedName;
 
     public final Warner noWarnings;
+    public final boolean emitQtypes;
 
     // <editor-fold defaultstate="collapsed" desc="Instantiating">
     public static Types instance(Context context) {
@@ -121,7 +122,9 @@
         messages = JavacMessages.instance(context);
         diags = JCDiagnostic.Factory.instance(context);
         noWarnings = new Warner(null);
-        allowValueBasedClasses = Options.instance(context).isSet("allowValueBasedClasses");
+        Options options = Options.instance(context);
+        allowValueBasedClasses = options.isSet("allowValueBasedClasses");
+        emitQtypes = options.isSet("emitQtypes");
     }
     // </editor-fold>
 
@@ -5068,7 +5071,10 @@
                     if (type.isCompound()) {
                         throw new InvalidSignatureException(type);
                     }
-                    append('L');
+                    if (types.emitQtypes && types.isValue(type))
+                        append('Q');
+                    else
+                        append('L');
                     assembleClassSig(type);
                     append(';');
                     break;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassFile.java	Mon Oct 15 16:40:22 2018 +0530
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassFile.java	Wed Oct 17 12:22:59 2018 +0530
@@ -50,7 +50,7 @@
  *  <pre>{@literal
  *     type       ::= ... | classtype | methodtype | typevar
  *     classtype  ::= classsig { '.' classsig }
- *     classig    ::= 'L' name [typeargs] ';'
+ *     classig    ::= 'L' name [typeargs] ';' | 'Q' name [typeargs] ';'
  *     methodtype ::= [ typeparams ] '(' { type } ')' type
  *     typevar    ::= 'T' name ';'
  *     typeargs   ::= '<' type { type } '>'
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Mon Oct 15 16:40:22 2018 +0530
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Wed Oct 17 12:22:59 2018 +0530
@@ -740,6 +740,7 @@
         case 'J':
             sigp++;
             return syms.longType;
+        case 'Q':
         case 'L':
             {
                 // int oldsigp = sigp;
@@ -801,7 +802,7 @@
     /** Convert class signature to type, where signature is implicit.
      */
     Type classSigToType() {
-        if (signature[sigp] != 'L')
+        if (signature[sigp] != 'L' && signature[sigp] != 'Q') 
             throw badClassFile("bad.class.signature",
                                Convert.utf2string(signature, sigp, 10));
         sigp++;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Mon Oct 15 16:40:22 2018 +0530
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Wed Oct 17 12:22:59 2018 +0530
@@ -447,7 +447,7 @@
                 ClassSymbol c = (ClassSymbol)value;
                 if (c.owner.kind == TYP) pool.put(c.owner);
                 poolbuf.appendByte(CONSTANT_Class);
-                if (c.type.hasTag(ARRAY)) {
+                if (c.type.hasTag(ARRAY) || (types.emitQtypes && c.isValue())) {
                     poolbuf.appendChar(pool.put(typeSig(c.type)));
                 } else {
                     poolbuf.appendChar(pool.put(names.fromUtf(externalize(c.flatname))));
--- a/src/jdk.jdeps/share/classes/com/sun/tools/classfile/Descriptor.java	Mon Oct 15 16:40:22 2018 +0530
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/classfile/Descriptor.java	Wed Oct 17 12:22:59 2018 +0530
@@ -157,6 +157,7 @@
                     type = "long";
                     break;
 
+                case 'Q':
                 case 'L':
                     int sep = desc.indexOf(';', p);
                     if (sep == -1)
--- a/src/jdk.jdeps/share/classes/com/sun/tools/classfile/Signature.java	Mon Oct 15 16:40:22 2018 +0530
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/classfile/Signature.java	Wed Oct 17 12:22:59 2018 +0530
@@ -142,6 +142,7 @@
                 sigp++;
                 return new SimpleType("long");
 
+            case 'Q':
             case 'L':
                 return parseClassTypeSignature();
 
@@ -191,7 +192,7 @@
     }
 
     private Type parseClassTypeSignature() {
-        assert sig.charAt(sigp) == 'L';
+        assert sig.charAt(sigp) == 'L' || sig.charAt(sigp) == 'Q';
         sigp++;
         return parseClassTypeSignatureRest();
     }
--- a/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/Pretty.java	Mon Oct 15 16:40:22 2018 +0530
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/Pretty.java	Wed Oct 17 12:22:59 2018 +0530
@@ -149,6 +149,7 @@
             case 'V':
                 name = "void";
                 break;
+            case 'Q':
             case 'L':
                 int semi = desc.indexOf(';', pos);
                 if (semi == -1) {
--- a/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/scan/MethodSig.java	Mon Oct 15 16:40:22 2018 +0530
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/scan/MethodSig.java	Wed Oct 17 12:22:59 2018 +0530
@@ -135,6 +135,7 @@
                     p++;
                     break;
 
+                case 'Q':
                 case 'L':
                     int sep = desc.indexOf(';', p);
                     if (sep == -1 || sep >= end)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/lworld-values/QTypeTest.java	Wed Oct 17 12:22:59 2018 +0530
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * bug 8212563
+ * @summary Check that javac emits Q types for values as needed
+ * @modules jdk.compiler/com.sun.tools.javac.util jdk.jdeps/com.sun.tools.javap
+ * @compile -XDemitQtypes QTypedValue.java
+ * @run main/othervm -Xverify:none -XX:+EnableValhalla QTypeTest
+ * @modules jdk.compiler
+ */
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.file.Paths;
+
+public class QTypeTest {
+
+    public static void main(String[] args) {
+        new QTypeTest().run();
+    }
+
+    void run() {
+        String [] params = new String [] { "-v",
+                                            Paths.get(System.getProperty("test.classes"),
+                                                "QTypedValue.class").toString() };
+        runCheck(params, new String [] {
+                "final value class QQTypedValue;",
+                "  flags: (0x0130) ACC_FINAL, ACC_SUPER, ACC_VALUE",
+                "  this_class: #2                          // \"QQTypedValue;\"",
+                "   #2 = Class              #37            // \"QQTypedValue;\"",
+                "   #3 = Class              #38            // \"[[[[QQTypedValue;\"",
+                "   #5 = Fieldref           #2.#41         // \"QQTypedValue;\".x:[[[QQTypedValue;",
+                "   #7 = Methodref          #2.#44         // \"QQTypedValue;\".$makeValue$:()QQTypedValue;",
+                "   #8 = Methodref          #2.#45         // \"QQTypedValue;\".foo:(QQTypedValue;)V",
+                "  #17 = Utf8               [[[QQTypedValue;",
+                "  #23 = Utf8               (QQTypedValue;)V",
+                "  #33 = Utf8               ()QQTypedValue;",
+                "  #35 = Utf8               QTypedValue.java",
+                "  #37 = Utf8               QQTypedValue;",
+                "  #38 = Utf8               [[[[QQTypedValue;",
+                "  #41 = NameAndType        #14:#17        // x:[[[QQTypedValue;",
+                "  #44 = NameAndType        #32:#33        // $makeValue$:()QQTypedValue;",
+                "  #45 = NameAndType        #22:#23        // foo:(QQTypedValue;)V",
+                "{",
+                "  final QTypedValue[][][] x;",
+                "    descriptor: [[[QQTypedValue;",
+                "    flags: (0x0010) ACC_FINAL",
+                "",
+                "  QQTypedValue;();",
+                "    descriptor: ()V",
+                "    flags: (0x0000)",
+                "    Code:",
+                "      stack=1, locals=1, args_size=1",
+                "         0: aload_0",
+                "         1: invokespecial #1                  // Method java/lang/Object.\"<init>\":()V",
+                "         4: return",
+                "      LineNumberTable:",
+                "        line 24: 0",
+                "  void foo(QTypedValue);",
+                "    descriptor: (QQTypedValue;)V",
+                "    flags: (0x0000)",
+                "    Code:",
+                "      stack=4, locals=4, args_size=2",
+                "         0: bipush        10",
+                "         2: anewarray     #2                  // class \"QQTypedValue;\"",
+                "         5: astore_2",
+                "         6: bipush        10",
+                "         8: bipush        10",
+                "        10: bipush        10",
+                "        12: bipush        10",
+                "        14: multianewarray #3,  4             // class \"[[[[QQTypedValue;\"",
+                "        18: astore_2",
+                "        19: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;",
+                "        22: aload_0",
+                "        23: getfield      #5                  // Field x:[[[QQTypedValue;",
+                "        26: invokevirtual #6                  // Method java/io/PrintStream.println:(Ljava/lang/Object;)V",
+                "        29: aload_0",
+                "        30: invokestatic  #7                  // Method $makeValue$:()QQTypedValue;",
+                "        33: invokevirtual #8                  // Method foo:(QQTypedValue;)V",
+                "        36: aload_2",
+                "        37: checkcast     #3                  // class \"[[[[QQTypedValue;\"",
+                "        40: astore_3",
+                "        41: return",
+                "  static QTypedValue $makeValue$();",
+                "    descriptor: ()QQTypedValue;",
+                "    flags: (0x1008) ACC_STATIC, ACC_SYNTHETIC",
+                "    Code:",
+                "      stack=2, locals=1, args_size=0",
+                "         0: defaultvalue  #2                  // class \"QQTypedValue;\"",
+                "         3: astore_0",
+                "         4: aconst_null",
+                "         5: aload_0",
+                "         6: swap",
+                "         7: withfield     #5                  // Field x:[[[QQTypedValue;",
+                "        10: astore_0",
+                "        11: aload_0",
+                "        12: areturn",
+         }, new String [] {
+         });
+
+     }
+
+     void runCheck(String [] params, String [] expectedOut, String [] unexpectedOut) {
+        StringWriter s;
+        String out;
+
+        try (PrintWriter pw = new PrintWriter(s = new StringWriter())) {
+            com.sun.tools.javap.Main.run(params, pw);
+            out = s.toString();
+        }
+        int errors = 0;
+        for (String eo: expectedOut) {
+            if (!out.contains(eo)) {
+                System.err.println("Match not found for string: " + eo);
+                errors++;
+            }
+        }
+        for (String eo: unexpectedOut) {
+            if (out.contains(eo)) {
+                System.err.println("Unexpected output found for string: " + eo);
+                errors++;
+            }
+        }
+        if (errors > 0) {
+             throw new AssertionError("Unexpected javap output: " + out);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/lworld-values/QTypedValue.java	Wed Oct 17 12:22:59 2018 +0530
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+value class QTypedValue {
+    QTypedValue [][][] x = null;
+    void foo(QTypedValue x) {
+        Object o = new QTypedValue[10];
+        o = new QTypedValue[10][10][10][10];
+        System.out.println(this.x);
+        foo(new QTypedValue());
+        QTypedValue[][][][] xx = (QTypedValue[][][][]) o;
+    }
+}