8171373: Reduce copying during initialization of ModuleHashes
authorredestad
Sat, 17 Dec 2016 12:59:15 +0100
changeset 42752 844691c73832
parent 42751 38d28e784f44
child 42759 0ff64a5b3824
8171373: Reduce copying during initialization of ModuleHashes Reviewed-by: alanb, mchung, chegar
jdk/src/java.base/share/classes/jdk/internal/module/ModuleHashes.java
jdk/src/java.base/share/classes/jdk/internal/module/SystemModuleFinder.java
jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleHashes.java	Fri Dec 16 21:43:29 2016 -0800
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleHashes.java	Sat Dec 17 12:59:15 2016 +0100
@@ -149,9 +149,10 @@
      */
     public static class Builder {
         final String algorithm;
-        Map<String, byte[]> nameToHash;
+        final Map<String, byte[]> nameToHash;
 
-        Builder(String algorithm) {
+        Builder(String algorithm, int initialCapacity) {
+            this.nameToHash = new HashMap<>(initialCapacity);
             this.algorithm =  Objects.requireNonNull(algorithm);
         }
 
@@ -159,9 +160,6 @@
          * Sets the module hash for the given module name
          */
         public Builder hashForModule(String mn, byte[] hash) {
-            if (nameToHash == null)
-                nameToHash = new HashMap<>();
-
             nameToHash.put(mn, hash);
             return this;
         }
@@ -170,7 +168,7 @@
          * Builds a {@code ModuleHashes}.
          */
         public ModuleHashes build() {
-            if (nameToHash != null) {
+            if (!nameToHash.isEmpty()) {
                 return new ModuleHashes(algorithm, nameToHash);
             } else {
                 return null;
--- a/jdk/src/java.base/share/classes/jdk/internal/module/SystemModuleFinder.java	Fri Dec 16 21:43:29 2016 -0800
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/SystemModuleFinder.java	Sat Dec 17 12:59:15 2016 +0100
@@ -124,7 +124,7 @@
     private final Map<String, ModuleReference> nameToModule;
 
     // module name to hashes
-    private final Map<String, byte[]> hashes = new HashMap<>();
+    private final Map<String, byte[]> hashes;
 
     private SystemModuleFinder() {
         String[] names = moduleNames();
@@ -162,12 +162,24 @@
             }
         }
 
+        Map<String, byte[]> hashes = null;
+        boolean secondSeen = false;
         // record the hashes to build HashSupplier
         for (ModuleHashes mh : recordedHashes) {
             if (mh != null) {
-                hashes.putAll(mh.hashes());
+                // if only one module contain ModuleHashes, use it
+                if (hashes == null) {
+                    hashes = mh.hashes();
+                } else {
+                    if (!secondSeen) {
+                        hashes = new HashMap<>(hashes);
+                        secondSeen = true;
+                    }
+                    hashes.putAll(mh.hashes());
+                }
             }
         }
+        this.hashes = (hashes == null) ? Map.of() : hashes;
 
         ModuleReference[] mods = new ModuleReference[n];
 
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java	Fri Dec 16 21:43:29 2016 -0800
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java	Sat Dec 17 12:59:15 2016 +0100
@@ -967,8 +967,9 @@
                 hmv.visitTypeInsn(NEW, MODULE_HASHES_BUILDER);
                 hmv.visitInsn(DUP);
                 hmv.visitLdcInsn(recordedHashes.algorithm());
+                pushInt(hmv, ((4 * recordedHashes.names().size()) / 3) + 1);
                 hmv.visitMethodInsn(INVOKESPECIAL, MODULE_HASHES_BUILDER,
-                    "<init>", "(Ljava/lang/String;)V", false);
+                    "<init>", "(Ljava/lang/String;I)V", false);
                 hmv.visitVarInsn(ASTORE, BUILDER_VAR);
                 hmv.visitVarInsn(ALOAD, BUILDER_VAR);
             }