RFR: Proposed jimage refresh for JDK9
Paul Sandoz
paul.sandoz at oracle.com
Mon May 18 17:07:25 UTC 2015
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);
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);
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();
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?
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())));
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?
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<>());
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