RFR: Proposed jimage refresh for JDK9

Jim Laskey (Oracle) james.laskey at oracle.com
Tue May 19 16:43:54 UTC 2015


> On May 18, 2015, at 2:07 PM, Paul Sandoz <paul.sandoz at oracle.com> wrote:
> 
> Hi Jim,
> 
> I reviewed the JDK code. There is quite a lot and i don't understand all the semantics but it generally looks ok.
> 
> Stuff below is mostly suggested API tweaks.
> 
> Paul.
> 
> jdk.internal.jimage.BasicImageReader
> --
> 
> 124     public String[] getEntryNames() {
> 125         int[] offsets = substrate.attributeOffsets();
> 126         List<String> list = new ArrayList<>();
> 127 
> 128         for (int offset : offsets) {
> 129             if (offset != 0) {
> 130                 ImageLocation location =
> 131                         ImageLocation.readFrom(this, offset);
> 132                 list.add(location.getFullNameString());
> 133             }
> 134         }
> 135 
> 136         String[] array = list.toArray(new String[0]);
> 137         Arrays.sort(array);
> 138 
> 139         return array;
> 140     }
> 
> You can do this instead:
> 
>  list.sort(null); // more idiomatic for Java 8
>  return list.toArray(new String[list.size()]);
> 
> It should be marginally more efficient just because the size information is passed to the array.
> 
> Alternatively you use a stream too, depending on your perf requirements:
> 
>  return IntStream.of(substrate.attributeOffsets())
>    .filter(o -> o != 0)
>    .mapToObj(o -> ImageLocation.readFrom(this, o).getFullNameString())
>    .sorted()
>    .toArray(String[]::new);

Done

> 
> Same applies to getAllLocations:
> 
>  return IntStream.of(substrate.attributeOffsets())
>    .filter(o -> o != 0)
>    .mapToObj(o -> ImageLocation.readFrom(this, o))
>    .sorted(Comparator.comparing(ImageLocation::getFullNameString)) // Use Comparator.comparing in any case for key extraction
>    .toArray(ImageLocation[]::new);
> 
> 

Done

> jdk.internal.jrtfs.JrtFileSystem.java
> --
> 
> 494     private Iterator<Path> nodesToIterator(Path path, String childPrefix, List<Node> childNodes) {
> 495         List<Path> childPaths;
> 496         if (childPrefix == null) {
> 497             childPaths = childNodes.stream()
> 498                 .map(child -> toJrtPath(child.getNameString()))
> 499                 .collect(Collectors.toCollection(ArrayList::new));
> 500         } else {
> 501             childPaths = childNodes.stream()
> 502                 .map(child -> toJrtPath(childPrefix + child.getNameString().substring(1)))
> 503                 .collect(Collectors.toCollection(ArrayList::new));
> 504         }
> 505         return childPaths.iterator();
> 506     }
> 
> Use Collectors.toList(). Could be marginally simplified as:
> 
>  Function<String, JrtPath> f = childPrefix == null
>     ? child -> toJrtPath(child.getNameString())
>      : child -> toJrtPath(childPrefix + child.getNameString().substring(1));
>  return childNodes.stream().map(f).collect(toList()).iterator();
> 
> 

Required:

       Function<Node, Path> f = childPrefix == null
                ? child -> toJrtPath(child.getNameString())
                : child -> toJrtPath(childPrefix + child.getNameString().substring(1));
         return childNodes.stream().map(f).collect(toList()).iterator();


> jdk.internal.jimage.ExternalFilesWriter
> 
>  93     private static String nativeDir(String filename) {
>  94         if (System.getProperty("os.name").startsWith("Windows")) {
>  95             if (filename.endsWith(".dll") || filename.endsWith(".diz")
>  96                 || filename.endsWith(".pdb") || filename.endsWith(".map")) {
>  97                 return "bin";
>  98             } else {
>  99                 return "lib";
> 100             }
> 101         } else {
> 102             return "lib";
> 103         }
> 104     }
> 
> Does that need to be performed in a doPriv block?
> 
> 

System.getProperty("os.name”) does not appear to be privileged.
permission java.util.PropertyPermission "os.name", "read”; in grant { } section


> jdk.internal.jimage.ImageFileCreator
> --
> 
> 108     private void readAllEntries(Map<String, Set<String>> modulePackagesMap,
> 109                                   Set<Archive> archives) {
> 110         archives.stream().forEach((archive) -> {
> 111             List<Entry> archiveResources = new ArrayList<>();
> 112             archive.visitEntries(x-> archiveResources.add(x));
> 113             String mn = archive.moduleName();
> 114             entriesForModule.put(mn, archiveResources);
> 115             // Extract package names
> 116             List<Entry> classes = archiveResources.stream()
> 117                     .filter(n -> n.type() == EntryType.CLASS_OR_RESOURCE)
> 118                     .collect(Collectors.toList());
> 119             Set<String> pkgs = classes.stream().map(Entry::name)
> 120                     .filter(n -> isResourcePackage(n))
> 121                     .map(ImageFileCreator::toPackage)
> 122                     .collect(Collectors.toSet());
> 123             modulePackagesMap.put(mn, pkgs);
> 124         });
> 125     }
> 
> Do not need to create the intermediate List<Entry>.
> 
> If archive.vistEntries was changed instead to:
> 
>  Stream<Entry> entries();
> 
> The code above might flow better and, off the top of my head, you could do something like:
> 
> archives.stream().forEach((archive) -> {
>    Map<Boolean, List<Entry>> es = archive.entries()
>            .collect(Collectors.partitioningBy(n -> n.type() == EntryType.CLASS_OR_RESOURCE));
> 
>    String mn = archive.moduleName();
>    entriesForModule.put(mn, es.get(false));
> 
>    // Extract package names
>    Set<String> pkgs = es.get(true).stream().map(Entry::name)
>            .filter(n -> isResourcePackage(n))
>            .map(ImageFileCreator::toPackage)
>            .collect(Collectors.toSet());
>    modulePackagesMap.put(mn, pkgs);
> });
> 
> For recreateJimage i think you can then do:
> 
> Map<String, List<Entry>> entriesForModule = archives.stream().collect(Collectors.toMap(
>        Archive::moduleName,
>        a -> a.entries().collect(Collectors.toList())
> ));
> 
> Or derive from Map<String, Archive>
> 
>  entriesForModule = nameToArchive.entrySet()
>        .stream()
>        .collect(Collectors.toMap(e -> e.getKey(), 
>                                  e -> e.getValue().entries().collect(Collectors.toList())));

Done, modified slightly.

> 
> 
> jdk.internal.jimage.ImageModuleDataWriter
> --
> 
>  69         Map<String, List<String>> modulePackages = new LinkedHashMap<>();
>  70         modules.stream().sorted().forEach((moduleName) -> {
>  71             List<String> localPackages = modulePackagesMap.get(moduleName).stream()
>  72                     .map(pn -> pn.replace('.', '/'))
>  73                     .sorted()
>  74                     .collect(Collectors.toList());
>  75             modulePackages.put(moduleName, localPackages);
>  76         });
> 
> can replace forEach with collect(Collectors.toMap(Functions.identity(),  n -> modulePackagesMap.get(n)...)); assuming no duplicate keys?
> 
> 

Done,  Functions -> Function


> jdk.internal.jimage.ResourcePoolImpl
> 
> 196             Set<String> pkgs = moduleToPackage.get(res.getModule());
> 197             if (pkgs == null) {
> 198                 pkgs = new HashSet<>();
> 199                 moduleToPackage.put(res.getModule(), pkgs);
> 200             }
> 
> use 
> 
>  Set<String> pkgs = moduleToPackage.computeIfAbsent(res.getModule(),k -> new HashSet<>());
> 

Done.


> Paul.
> 
> On May 15, 2015, at 5:45 PM, Jim Laskey (Oracle) <james.laskey at oracle.com> wrote:
> 
>> http://cr.openjdk.java.net/~jlaskey/jdk9-jimage/top/ <http://cr.openjdk.java.net/~jlaskey/jdk9-jimage/top/>
>> http://cr.openjdk.java.net/~jlaskey/jdk9-jimage/hotspot/ <http://cr.openjdk.java.net/~jlaskey/jdk9-jimage/hotspot/>
>> http://cr.openjdk.java.net/~jlaskey/jdk9-jimage/jdk/ <http://cr.openjdk.java.net/~jlaskey/jdk9-jimage/jdk/>
>> http://cr.openjdk.java.net/~jlaskey/jdk9-jimage/langtools/ <http://cr.openjdk.java.net/~jlaskey/jdk9-jimage/langtools/>
>> 
>> There are some issues with regard to the hotspot changes, but I’m working with Coleen and John R. to resolve those.
>> 
>> Cheers,
>> 
>> — Jim
>> 
> 



More information about the jigsaw-dev mailing list