changeset 3285:ce45cc7d0b52

Enhancement: consolidate options to generate generic pool forms into a single flag The new flag -XDgenericClassFile superseded the old -XDpoolModes flag. The new flag also enables alternate generic method translation.
author mcimadamore
date Tue, 19 Jan 2016 15:23:34 +0000
parents de66408690d1
children e48d890d4788
files src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/SpecializeTypes.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Items.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolWriter.java src/jdk.compiler/share/classes/com/sun/tools/javac/sym/CreateSymbols.java test/tools/javac/valhalla/typespec/GenericPool01.java
diffstat 8 files changed, 122 insertions(+), 74 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Fri Jan 15 18:19:42 2016 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Tue Jan 19 15:23:34 2016 +0000
@@ -4001,8 +4001,6 @@
                    v.name != names._class;
         }
 
-    Warner noteWarner = new Warner();
-
     /**
      * Check that method arguments conform to its instantiation.
      **/
@@ -4051,7 +4049,7 @@
                 log.error(env.tree.pos(), "illegal.static.intf.meth.call", site);
             }
         }
-
+        Warner noteWarner = new Warner();
         // Compute the identifier's instantiated type.
         // For methods, we need to compute the instance type by
         // Resolve.instantiate from the symbol's type as well as
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/SpecializeTypes.java	Fri Jan 15 18:19:42 2016 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/SpecializeTypes.java	Tue Jan 19 15:23:34 2016 +0000
@@ -138,7 +138,7 @@
         compileStates = CompileStates.instance(context);
         log = Log.instance(context);
         Options options = Options.instance(context);
-        desugarGenericMethods = options.isSet("desugarGenericMethods");
+        desugarGenericMethods = options.isSet("desugarGenericMethods") || options.isSet("genericClassFile");
     }
 
     /** class currently being specialized. */
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Fri Jan 15 18:19:42 2016 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Tue Jan 19 15:23:34 2016 +0000
@@ -26,7 +26,6 @@
 package com.sun.tools.javac.jvm;
 
 import java.io.*;
-import java.util.EnumSet;
 import java.util.Map;
 import java.util.Iterator;
 
@@ -38,10 +37,8 @@
 import com.sun.tools.javac.code.Attribute.RetentionPolicy;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.code.Type.*;
-import com.sun.tools.javac.code.Types.UnaryVisitor;
 import com.sun.tools.javac.file.BaseFileObject;
 import com.sun.tools.javac.jvm.Gen.Descriptor;
-import com.sun.tools.javac.jvm.Gen.PoolMode;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.Tuple.Tuple2;
 
@@ -145,8 +142,8 @@
     /** Sole signature generator */
     private final CWSignatureGenerator signatureGen;
 
-    /** pool modes */
-    private final EnumSet<PoolMode> poolModes;
+    /** Switch: new constant pool mode support */
+    private final boolean genericClassFile;
 
     /** The tags and constants used in compressed stackmap. */
     static final int SAME_FRAME_SIZE = 64;
@@ -187,7 +184,7 @@
         emitSourceFile = options.isUnset(G_CUSTOM) ||
                             options.isSet(G_CUSTOM, "source");
 
-        poolModes = Gen.PoolMode.getPoolMode(options);
+        genericClassFile = options.isSet("genericClassFile");
 
         String dumpModFlags = options.get("dumpmodifiers");
         dumpClassModifiers =
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java	Fri Jan 15 18:19:42 2016 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java	Tue Jan 19 15:23:34 2016 +0000
@@ -128,7 +128,7 @@
         debugCode = options.isSet("debugcode");
         allowInvokedynamic = target.hasInvokedynamic() || options.isSet("invokedynamic");
         allowBetterNullChecks = target.hasObjects();
-        poolModes = PoolMode.getPoolMode(options);
+        genericClassFile = options.isSet("genericClassFile");
 
         // ignore cldc because we cannot have both stackmap formats
         this.stackMap = StackMapFormat.JSR202;
@@ -148,47 +148,6 @@
         annotate = Annotate.instance(context);
     }
 
-    public enum PoolMode {
-        TYPE1("type1"),
-        TYPE2("type2"),
-        TYPE3("type3"),
-        TYPE4("type4"), //not supported yet
-        SIGNATURES("signatures"),
-        SPECIALIZED("specialized");
-
-        final String opt;
-
-        PoolMode(String opt) {
-            this.opt = opt;
-        }
-
-        /**
-         * This method is used to parse the {@code poolModes} option.
-         * Possible modes are separated by colon; a mode can be excluded by
-         * prepending '-' to its name. Finally, the special mode 'all' can be used to
-         * add all modes to the resulting enum.
-         */
-        static EnumSet<PoolMode> getPoolMode(Options options) {
-            EnumSet<PoolMode> res = EnumSet.noneOf(PoolMode.class);
-            String modesOpt = options.get("poolModes");
-            if (modesOpt != null) {
-                String[] modes = modesOpt.split(",");
-                Collection<String> args = Arrays.asList(modes);
-                if (args.contains("all")) {
-                    res = EnumSet.allOf(PoolMode.class);
-                }
-                for (PoolMode mode : values()) {
-                    if (args.contains(mode.opt)) {
-                        res.add(mode);
-                    } else if (args.contains("-" + mode.opt)) {
-                        res.remove(mode);
-                    }
-                }
-            }
-            return res;
-        }
-    }
-
     /** Switches
      */
     private final boolean lineDebugInfo;
@@ -197,7 +156,7 @@
     private final boolean debugCode;
     private final boolean allowInvokedynamic;
     private final boolean allowBetterNullChecks;
-    private final EnumSet<PoolMode> poolModes;
+    private final boolean genericClassFile;
 
     /** Default limit of (approximate) size of finalizer to inline.
      *  Zero means always use jsr.  100 or greater means never use
@@ -707,7 +666,7 @@
                     case TYPE_0:
                         break;
                     case TYPE_1:
-                        if (poolModes.contains(PoolMode.TYPE1)) {
+                        if (genericClassFile) {
                             code.emitop2(typed, pool.putType(type));
                         } else {
                             code.markAny(pc, types.typeSig(type));
@@ -733,7 +692,7 @@
             if (needsMangling) {
                 switch (ok) {
                     case TYPE_2:
-                        if (!poolModes.contains(PoolMode.TYPE2)) {
+                        if (!genericClassFile) {
                             code.markAny(pc, types.bytecodeMappingSig(unerased));
                         }
                         break;
@@ -1197,7 +1156,7 @@
                                         syms,
                                         types,
                                         pool.pool);
-            items = new Items(pool, code, syms, types, names, poolModes);
+            items = new Items(pool, code, syms, types, names, genericClassFile);
             if (code.debugCode) {
                 System.err.println(meth + " for body " + tree);
             }
@@ -2637,7 +2596,7 @@
             ClassSymbol c = cdef.sym;
             this.toplevel = env.toplevel;
             this.endPosTable = toplevel.endPositions;
-            pool = c.poolWriter = new PoolWriter(types, poolModes);
+            pool = c.poolWriter = new PoolWriter(types, genericClassFile);
             /* method normalizeDefs() can add references to external classes into the constant pool
              */
             cdef.defs = normalizeDefs(cdef.defs, c);
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Items.java	Fri Jan 15 18:19:42 2016 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Items.java	Tue Jan 19 15:23:34 2016 +0000
@@ -31,14 +31,12 @@
 import com.sun.tools.javac.code.Type.*;
 import com.sun.tools.javac.jvm.Code.*;
 import com.sun.tools.javac.jvm.Gen.Descriptor;
-import com.sun.tools.javac.jvm.Gen.PoolMode;
 import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.util.Assert;
 import com.sun.tools.javac.util.ListBuffer;
 import com.sun.tools.javac.util.Name;
 import com.sun.tools.javac.util.Names;
 
-import java.util.EnumSet;
 import java.util.function.Function;
 import java.util.function.Predicate;
 import java.util.function.Supplier;
@@ -82,18 +80,18 @@
     Names names;
 
     /** Switch: new constant pool mode support */
-    EnumSet<PoolMode> poolModes;
+    boolean genericClassFile;
 
     /** Items that exist only once (flyweight pattern).
      */
     private final Item voidItem;
     private final Item[] stackItem = new Item[TypeCodeCount];
 
-    public Items(PoolWriter pool, Code code, Symtab syms, Types types, Names names, EnumSet<PoolMode> poolModes) {
+    public Items(PoolWriter pool, Code code, Symtab syms, Types types, Names names, boolean genericClassFile) {
         this.code = code;
         this.pool = pool;
         this.types = types;
-        this.poolModes = poolModes;
+        this.genericClassFile = genericClassFile;
         voidItem = new Item(VOIDcode) {
                 public String toString() { return "void"; }
             };
@@ -563,7 +561,7 @@
                     break;
                 case TYPE_1:
                     if (types.isSpecializableTypeVar(originalType)) {
-                        if (poolModes.contains(PoolMode.TYPE1)) {
+                        if (genericClassFile) {
                             //typed
                             code.emitop2(typed, pool.putType(originalType));
                         } else {
@@ -574,7 +572,7 @@
                     break;
                 case TYPE_3:
                     SymbolicItem symbolicItem = (SymbolicItem)delegatedItem;
-                    if (!poolModes.contains(PoolMode.TYPE3)) {
+                    if (!genericClassFile) {
                         if (types.needsMangling(symbolicItem.ownerType())) {
                             code.markAny(pc, names.fromString(String.join("::",
                                     types.bytecodeMappingSig(symbolicItem.ownerType()),
@@ -584,7 +582,7 @@
                     break;
                 case TYPE_4:
                     DynamicMethodSymbol dynSym = (DynamicMethodSymbol)((DynamicItem)delegatedItem).member;
-                    if (!poolModes.contains(PoolMode.TYPE4)) {
+                    if (!genericClassFile) {
                         Type indyType = dynSym.type;
                         ListBuffer<String> buf = new ListBuffer<>();
                         outer:
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolWriter.java	Fri Jan 15 18:19:42 2016 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolWriter.java	Tue Jan 19 15:23:34 2016 +0000
@@ -47,7 +47,6 @@
 import com.sun.tools.javac.jvm.ClassWriter.PoolOverflow;
 import com.sun.tools.javac.jvm.ClassWriter.StringOverflow;
 import com.sun.tools.javac.jvm.Gen.Descriptor;
-import com.sun.tools.javac.jvm.Gen.PoolMode;
 import com.sun.tools.javac.jvm.Pool.CompoundType;
 import com.sun.tools.javac.jvm.Pool.Constant;
 import com.sun.tools.javac.jvm.Pool.InvokeDynamic;
@@ -67,7 +66,6 @@
 import com.sun.tools.javac.util.Tuple.Tuple2;
 
 import java.util.Arrays;
-import java.util.EnumSet;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.Map;
@@ -97,8 +95,8 @@
 
     Types types;
 
-    /** Set of enabled pool modes. */
-    EnumSet<PoolMode> poolModes;
+    /** Switch: new constant pool mode support */
+    boolean genericClassFile;
 
     /** The inner classes to be written, as an ordered set (enclosing first). */
     LinkedHashSet<ClassSymbol> innerClasses = new LinkedHashSet<>();
@@ -109,10 +107,10 @@
     /** Did this class encoded any of the Valhalla-specific CP-forms? */
     boolean useNewCPForms = false;
 
-    public PoolWriter(Types types, EnumSet<PoolMode> poolModes) {
+    public PoolWriter(Types types, boolean genericClassFile) {
         this.pool = new Pool();
         this.types = types;
-        this.poolModes = poolModes;
+        this.genericClassFile = genericClassFile;
     }
 
     /**
@@ -374,7 +372,7 @@
      * Create a new entry entry from given type.
      */
     private Entry makeType(Type t, Function<Type, Name> typeNameFunction) {
-        TypeFactory tf = !poolModes.contains(PoolMode.SIGNATURES) ?
+        TypeFactory tf = !genericClassFile ?
                 legacyTypeFactory : genericTypeFactory;
         return t.accept(tf, typeNameFunction);
     }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/sym/CreateSymbols.java	Fri Jan 15 18:19:42 2016 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/sym/CreateSymbols.java	Tue Jan 19 15:23:34 2016 +0000
@@ -34,7 +34,6 @@
 import com.sun.tools.javac.code.Type;
 import com.sun.tools.javac.code.Types;
 import com.sun.tools.javac.jvm.ClassWriter;
-import com.sun.tools.javac.jvm.Gen.PoolMode;
 import com.sun.tools.javac.jvm.PoolWriter;
 import com.sun.tools.javac.processing.JavacProcessingEnvironment;
 import com.sun.tools.javac.util.DefinedBy;
@@ -204,7 +203,7 @@
 
         Type.moreInfo = true;
         Types types = Types.instance(task.getContext());
-        PoolWriter poolWriter = new PoolWriter(types, EnumSet.noneOf(PoolMode.class));
+        PoolWriter poolWriter = new PoolWriter(types, false);
         for (JavaFileObject file : fm.list(jarLocation, "", EnumSet.of(CLASS), true)) {
             String className = fm.inferBinaryName(jarLocation, file);
             int index = className.lastIndexOf('.');
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/valhalla/typespec/GenericPool01.java	Tue Jan 19 15:23:34 2016 +0000
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2016, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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
+ * @summary smoke test for generic constant pool forms
+ * @compile -XDgenericClassFile GenericPool01.java
+ */
+class GenericPool01<any X> {
+    X x;
+
+    void test(X x1, X x2) {
+        x1 = x2; //aload, astore
+    }
+
+    void test2(X[] xarr, X x) {
+        x = xarr[0]; //aaload
+        xarr[1] = x; //aastore
+    }
+
+    X test3(X x) {
+        return x; //areturn
+    }
+
+    void test4(X t1, X t2, X t3) {
+        t1 = (t2 = t3); //dup
+    }
+
+    X m(X x) { return x; }
+
+    void test5(X x) {
+        m(x); //pop
+    }
+
+    void test6(X t1, X t2) {
+        boolean b1 = t1 == t2; //if_acmpne
+        boolean b2 = t1 != t2; //if_acmpeq
+    }
+
+    void testLdc() {
+        Object o1 = GenericPool01<X>.class;
+    }
+
+    void testCast(Object o) {
+        X x = (X)o;
+        X[] x2 = (X[])o;
+        X[][] x3 = (X[][])o;
+    }
+
+    void testInstanceof(Object o) {
+        boolean b1 = o instanceof X;
+        boolean b2 = o instanceof X[];
+        boolean b3 = o instanceof X[][];
+    }
+
+    void testNew() {
+        new GenericPool01<X>();
+    }
+
+    void testNewArray() {
+        Object arr1 = new X[0];
+        Object arr2 = new X[0][0];
+        Object arr3 = new X[0][0][0];
+        Object arr4 = new GenericPool01<X>[0];
+        Object arr5 = new GenericPool01<X>[0][0];
+        Object arr6 = new GenericPool01<X>[0][0][0];
+    }
+
+    void testGetPutField() {
+        X x2 = x;
+        x = x2;
+    }
+
+    void testInvoke(X x) {
+        testInvoke(x);
+    }
+}