OpenJDK / valhalla / valhalla
changeset 52235:1b7fae44af66 lworld
8212563: [lworld] Javac should emit `Q' descriptors for value types.
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; + } +}