< prev index next >

make/langtools/src/classes/build/tools/symbolgenerator/CreateSymbols.java

Print this page
rev 51104 : imported patch ct.sym-upgrade-code

@@ -118,10 +118,12 @@
 import com.sun.tools.classfile.Module_attribute;
 import com.sun.tools.classfile.Module_attribute.ExportsEntry;
 import com.sun.tools.classfile.Module_attribute.OpensEntry;
 import com.sun.tools.classfile.Module_attribute.ProvidesEntry;
 import com.sun.tools.classfile.Module_attribute.RequiresEntry;
+import com.sun.tools.classfile.NestHost_attribute;
+import com.sun.tools.classfile.NestMembers_attribute;
 import com.sun.tools.classfile.RuntimeAnnotations_attribute;
 import com.sun.tools.classfile.RuntimeInvisibleAnnotations_attribute;
 import com.sun.tools.classfile.RuntimeInvisibleParameterAnnotations_attribute;
 import com.sun.tools.classfile.RuntimeParameterAnnotations_attribute;
 import com.sun.tools.classfile.RuntimeVisibleAnnotations_attribute;

@@ -132,11 +134,24 @@
 import com.sun.tools.javac.util.Assert;
 import com.sun.tools.javac.util.Context;
 import com.sun.tools.javac.util.Pair;
 
 /**
- * A tool for processing the .sym.txt files. It allows to:
+ * A tool for processing the .sym.txt files.
+ *
+ * To add historical data for JDK N, N >= 11, do the following:
+ *  * cd <open-jdk-checkout>/make/data/symbols
+ *  * <jdk-N>/bin/java --add-exports jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED \
+ *                     --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
+ *                     --add-exports jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED \
+ *                     --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \
+ *                     --add-modules jdk.jdeps \
+ *                     ../../../make/langtools/src/classes/build/tools/symbolgenerator/CreateSymbols.java \
+ *                     build-description-incremental symbols include.list
+ *  * sanity-check the new and updates files in make/data/symbols and commit them
+ *
+ * The tools allows to:
  *  * convert the .sym.txt into class/sig files for ct.sym
  *  * in cooperation with the adjacent history Probe, construct .sym.txt files for previous platforms
  *  * enhance existing .sym.txt files with a a new set .sym.txt for the current platform
  *
  * To convert the .sym.txt files to class/sig files from ct.sym, run:

@@ -184,23 +199,20 @@
  *                                                    8 OpenJDK8.classes '<none>'
  *                                                    7 OpenJDK7.classes 8
  *
  * Note: the versions are expected to be a single character.
  *
- * To enhance existing historical data with data for JDK N, run:
- *     <jdk-N>/bin/java build.tools.symbolgenerator.CreateSymbols build-description-incremental make/data/symbols/symbols make/data/symbols/include.list
- *
  */
 public class CreateSymbols {
 
     //<editor-fold defaultstate="collapsed" desc="ct.sym construction">
     /**Create sig files for ct.sym reading the classes description from the directory that contains
      * {@code ctDescriptionFile}, using the file as a recipe to create the sigfiles.
      */
     @SuppressWarnings("unchecked")
-    public void createSymbols(String ctDescriptionFile, String ctSymLocation, CtSymKind ctSymKind) throws IOException {
-        LoadDescriptions data = load(Paths.get(ctDescriptionFile), null);
+    public void createSymbols(String ctDescriptionFileExtra, String ctDescriptionFile, String ctSymLocation, CtSymKind ctSymKind) throws IOException {
+        LoadDescriptions data = load(Paths.get(ctDescriptionFileExtra), Paths.get(ctDescriptionFile), null);
 
         splitHeaders(data.classes);
 
         for (ModuleDescription md : data.modules.values()) {
             for (ModuleHeaderDescription mhd : md.header) {

@@ -235,27 +247,51 @@
         }
     }
 
     public static String EXTENSION = ".sig";
 
-    LoadDescriptions load(Path ctDescription, String deletePlatform) throws IOException {
-        List<PlatformInput> platforms = new ArrayList<>();
+    LoadDescriptions load(Path ctDescriptionWithExtraContent, Path ctDescriptionOpen, String deletePlatform) throws IOException {
+        Map<String, PlatformInput> platforms = new LinkedHashMap<>();
+
+        if (ctDescriptionWithExtraContent != null && Files.isRegularFile(ctDescriptionWithExtraContent)) {
+            try (LineBasedReader reader = new LineBasedReader(ctDescriptionWithExtraContent)) {
+                while (reader.hasNext()) {
+                    switch (reader.lineKey) {
+                        case "generate":
+                            //ignore
+                            reader.moveNext();
+                            break;
+                        case "platform":
+                            PlatformInput platform = PlatformInput.load(ctDescriptionWithExtraContent,
+                                                                        reader);
+                            if (!platform.version.equals(deletePlatform))
+                                platforms.put(platform.version, platform);
+                            reader.moveNext();
+                            break;
+                        default:
+                            throw new IllegalStateException("Unknown key: " + reader.lineKey);
+                    }
+                }
+            }
+        }
+
         Set<String> generatePlatforms = null;
 
-        try (LineBasedReader reader = new LineBasedReader(ctDescription)) {
+        try (LineBasedReader reader = new LineBasedReader(ctDescriptionOpen)) {
             while (reader.hasNext()) {
                 switch (reader.lineKey) {
                     case "generate":
                         String[] platformsAttr = reader.attributes.get("platforms").split(":");
                         generatePlatforms = new HashSet<>(List.of(platformsAttr));
                         generatePlatforms.remove(deletePlatform);
                         reader.moveNext();
                         break;
                     case "platform":
-                        PlatformInput platform = PlatformInput.load(reader);
-                        if (!platform.version.equals(deletePlatform))
-                            platforms.add(platform);
+                        PlatformInput platform = PlatformInput.load(ctDescriptionOpen, reader);
+                        if (!platform.version.equals(deletePlatform) &&
+                            !platforms.containsKey(platform.version))
+                            platforms.put(platform.version, platform);
                         reader.moveNext();
                         break;
                     default:
                         throw new IllegalStateException("Unknown key: " + reader.lineKey);
                 }

@@ -263,21 +299,21 @@
         }
 
         Map<String, ClassDescription> classes = new LinkedHashMap<>();
         Map<String, ModuleDescription> modules = new LinkedHashMap<>();
 
-        for (PlatformInput platform: platforms) {
+        for (PlatformInput platform : platforms.values()) {
             for (ClassDescription cd : classes.values()) {
                 addNewVersion(cd.header, platform.basePlatform, platform.version);
                 addNewVersion(cd.fields, platform.basePlatform, platform.version);
                 addNewVersion(cd.methods, platform.basePlatform, platform.version);
             }
             for (ModuleDescription md : modules.values()) {
                 addNewVersion(md.header, platform.basePlatform, platform.version);
             }
             for (String input : platform.files) {
-                Path inputFile = ctDescription.getParent().resolve(input);
+                Path inputFile = platform.ctDescription.getParent().resolve(input);
                 try (LineBasedReader reader = new LineBasedReader(inputFile)) {
                     while (reader.hasNext()) {
                         String nameAttr = reader.attributes.get("name");
                         switch (reader.lineKey) {
                             case "class": case "-class":

@@ -374,11 +410,11 @@
             }
 
             moduleList.put(desc.name, desc);
         }
 
-        return new LoadDescriptions(result, moduleList, platforms);
+        return new LoadDescriptions(result, moduleList, new ArrayList<>(platforms.values()));
     }
 
     static final class LoadDescriptions {
         public final ClassList classes;
         public final Map<String, ModuleDescription> modules;

@@ -460,18 +496,21 @@
 
     private static class PlatformInput {
         public final String version;
         public final String basePlatform;
         public final List<String> files;
-        public PlatformInput(String version, String basePlatform, List<String> files) {
+        public final Path ctDescription;
+        public PlatformInput(Path ctDescription, String version, String basePlatform, List<String> files) {
+            this.ctDescription = ctDescription;
             this.version = version;
             this.basePlatform = basePlatform;
             this.files = files;
         }
 
-        public static PlatformInput load(LineBasedReader in) throws IOException {
-            return new PlatformInput(in.attributes.get("version"),
+        public static PlatformInput load(Path ctDescription, LineBasedReader in) throws IOException {
+            return new PlatformInput(ctDescription,
+                                     in.attributes.get("version"),
                                      in.attributes.get("base"),
                                      List.of(in.attributes.get("files").split(":")));
         }
     }
 

@@ -815,10 +854,26 @@
     }
 
     private void addAttributes(ClassHeaderDescription header,
             List<CPInfo> constantPool, Map<String, Attribute> attributes) {
         addGenericAttributes(header, constantPool, attributes);
+        if (header.nestHost != null) {
+            int attributeString = addString(constantPool, Attribute.NestHost);
+            int nestHost = addClass(constantPool, header.nestHost);
+            attributes.put(Attribute.NestHost,
+                           new NestHost_attribute(attributeString, nestHost));
+        }
+        if (header.nestMembers != null && !header.nestMembers.isEmpty()) {
+            int attributeString = addString(constantPool, Attribute.NestMembers);
+            int[] nestMembers = new int[header.nestMembers.size()];
+            int i = 0;
+            for (String intf : header.nestMembers) {
+                nestMembers[i++] = addClass(constantPool, intf);
+            }
+            attributes.put(Attribute.NestMembers,
+                           new NestMembers_attribute(attributeString, nestMembers));
+        }
         addInnerClassesAttribute(header, constantPool, attributes);
     }
 
     private void addInnerClassesAttribute(HeaderDescription header,
             List<CPInfo> constantPool, Map<String, Attribute> attributes) {

@@ -1149,11 +1204,12 @@
             loadVersionClasses(classes, modules, classFileData, excludesIncludes, desc.version);
         }
 
         List<PlatformInput> platforms =
                 versions.stream()
-                        .map(desc -> new PlatformInput(desc.version,
+                        .map(desc -> new PlatformInput(null,
+                                                       desc.version,
                                                        desc.primaryBaseline,
                                                        null))
                         .collect(Collectors.toList());
 
         dumpDescriptions(classes, modules, platforms, descDest.resolve("symbols"), args);

@@ -1292,10 +1348,20 @@
                 continue;
             }
 
             ClassHeaderDescription header = clazz.header.get(0);
 
+            if (header.nestMembers != null) {
+                Iterator<String> nestMemberIt = header.nestMembers.iterator();
+
+                while(nestMemberIt.hasNext()) {
+                    String member = nestMemberIt.next();
+                    if (!includedClasses.contains(member))
+                        nestMemberIt.remove();
+                }
+            }
+
             if (header.innerClasses != null) {
                 Iterator<InnerClassInfo> innerClassIt = header.innerClasses.iterator();
 
                 while(innerClassIt.hasNext()) {
                     InnerClassInfo ici = innerClassIt.next();

@@ -1353,18 +1419,23 @@
                                   String[] args) throws IOException {
         classes.sort();
 
         Map<String, String> package2Modules = new HashMap<>();
 
+        versions.stream()
+                .filter(v -> "9".compareTo(v.version) <= 0)
+                .sorted((v1, v2) -> v1.version.compareTo(v2.version))
+                .forEach(v -> {
         for (ModuleDescription md : modules.values()) {
             md.header
               .stream()
-              .filter(h -> h.versions.contains("9"))
+                  .filter(h -> h.versions.contains(v.version))
               .flatMap(h -> h.exports.stream())
               .map(p -> p.replace('/', '.'))
-              .forEach(p -> package2Modules.put(p, md.name));
+                  .forEach(p -> package2Modules.putIfAbsent(p, md.name));
         }
+        });
 
         package2Modules.put("java.awt.dnd.peer", "java.desktop");
         package2Modules.put("java.awt.peer", "java.desktop");
         package2Modules.put("jdk", "java.base");
 

@@ -1478,11 +1549,11 @@
         String specVersion = System.getProperty("java.specification.version");
         String currentVersion =
                 Integer.toString(Integer.parseInt(specVersion), Character.MAX_RADIX);
         currentVersion = currentVersion.toUpperCase(Locale.ROOT);
         Path ctDescriptionPath = Paths.get(ctDescriptionFile).toAbsolutePath();
-        LoadDescriptions data = load(ctDescriptionPath, currentVersion);
+        LoadDescriptions data = load(null, ctDescriptionPath, currentVersion);
 
         ClassList classes = data.classes;
         Map<String, ModuleDescription> modules = data.modules;
         List<PlatformInput> versions = data.versions;
 

@@ -1502,11 +1573,11 @@
                                .findFirst()
                                .get()
                                .version;
         }
 
-        versions.add(new PlatformInput(currentVersion, baseline, null));
+        versions.add(new PlatformInput(null, currentVersion, baseline, null));
         dumpDescriptions(classes, modules, versions, ctDescriptionPath, args);
     }
 
     private List<byte[]> dumpCurrentClasses() throws IOException {
         JavacTool tool = JavacTool.create();

@@ -1880,10 +1951,26 @@
                 break;
             }
             case Attribute.ModulePackages:
             case Attribute.ModuleHashes:
                 break;
+            case Attribute.NestHost: {
+                assert feature instanceof ClassHeaderDescription;
+                NestHost_attribute nestHost = (NestHost_attribute) attr;
+                ClassHeaderDescription chd = (ClassHeaderDescription) feature;
+                chd.nestHost = nestHost.getNestTop(cf.constant_pool).getName();
+                break;
+            }
+            case Attribute.NestMembers: {
+                assert feature instanceof ClassHeaderDescription;
+                NestMembers_attribute nestMembers = (NestMembers_attribute) attr;
+                ClassHeaderDescription chd = (ClassHeaderDescription) feature;
+                chd.nestMembers = Arrays.stream(nestMembers.members_indexes)
+                                        .mapToObj(i -> getClassName(cf, i))
+                                        .collect(Collectors.toList());
+                break;
+            }
             default:
                 throw new IllegalStateException("Unhandled attribute: " +
                                                 attrName);
         }
 

@@ -2660,16 +2747,20 @@
     }
 
     static class ClassHeaderDescription extends HeaderDescription {
         String extendsAttr;
         List<String> implementsAttr;
+        String nestHost;
+        List<String> nestMembers;
 
         @Override
         public int hashCode() {
             int hash = super.hashCode();
             hash = 17 * hash + Objects.hashCode(this.extendsAttr);
             hash = 17 * hash + Objects.hashCode(this.implementsAttr);
+            hash = 17 * hash + Objects.hashCode(this.nestHost);
+            hash = 17 * hash + Objects.hashCode(this.nestMembers);
             return hash;
         }
 
         @Override
         public boolean equals(Object obj) {

@@ -2684,10 +2775,16 @@
                 return false;
             }
             if (!Objects.equals(this.implementsAttr, other.implementsAttr)) {
                 return false;
             }
+            if (!Objects.equals(this.nestHost, other.nestHost)) {
+                return false;
+            }
+            if (!Objects.equals(this.nestMembers, other.nestMembers)) {
+                return false;
+            }
             return true;
         }
 
         @Override
         public void write(Appendable output, String baselineVersion, String version) throws IOException {

@@ -2697,10 +2794,14 @@
             output.append("header");
             if (extendsAttr != null)
                 output.append(" extends " + extendsAttr);
             if (implementsAttr != null && !implementsAttr.isEmpty())
                 output.append(" implements " + serializeList(implementsAttr));
+            if (nestHost != null)
+                output.append(" nestHost " + nestHost);
+            if (nestMembers != null && !nestMembers.isEmpty())
+                output.append(" nestMembers " + serializeList(nestMembers));
             writeAttributes(output);
             output.append("\n");
             writeInnerClasses(output, baselineVersion, version);
         }
 

@@ -2711,10 +2812,14 @@
 
             extendsAttr = reader.attributes.get("extends");
             String elementsList = reader.attributes.get("implements");
             implementsAttr = deserializeList(elementsList);
 
+            nestHost = reader.attributes.get("nestHost");
+            String nestMembersList = reader.attributes.get("nestMembers");
+            nestMembers = deserializeList(nestMembersList);
+
             readAttributes(reader);
             reader.moveNext();
             readInnerClasses(reader);
 
             return true;

@@ -3524,17 +3629,18 @@
 
                 new CreateSymbols().createIncrementalBaseLine(args[1], args[2], args);
                 break;
             }
             case "build-ctsym":
-                if (args.length != 3) {
+                if (args.length != 4) {
                     help();
                     return ;
                 }
 
                 new CreateSymbols().createSymbols(args[1],
                                                   args[2],
+                                                  args[3],
                                                   CtSymKind.JOINED_VERSIONS);
                 break;
         }
     }
 
< prev index next >