On Mon, 12 Jun 2023 05:03:28 GMT, Alan Bateman <al...@openjdk.org> wrote:

>> Oliver Kopp has updated the pull request with a new target base due to a 
>> merge or a rebase. The incremental webrev excludes the unrelated changes 
>> brought in by the merge/rebase. The pull request contains five additional 
>> commits since the last revision:
>> 
>>  - Merge remote-tracking branch 'upstream/master' into fix-8240567
>>  - Merge remote-tracking branch 'upstream/master' into fix-8240567
>>  - Remove "final" at "enabled" - not part of the point of this PR
>>  - Remove comments
>>  - 8240567: MethodTooLargeException thrown while creating a jlink image
>>    
>>    Co-authored-by: Christoph Schwentker <siedlerkil...@gmail.com>
>
> @koppor Is this ready for review? The other PR went through a dozens or so 
> iterations before it was returned to draft. It seems like you were still 
> battling with verifier errors. The comment on this PR says you it was created 
> because a force-push so I can't tell if you the changes are ready or not.

@AlanBateman The diff to the "old" PR https://github.com/openjdk/jdk/pull/10704 
is as follows. Maybe this helps at reviewing? IMHO this diff shows very good 
the new passing of the locals required by the deduplication functionality.


diff --git 
a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java
 
b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java
old mode 100755
new mode 100644
index 8e98a5b94e2..a87fa84ebe2
--- 
a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java
+++ 
b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java
@@ -118,7 +118,7 @@ public final class SystemModulesPlugin extends 
AbstractPlugin {
             ClassDesc.ofInternalName("jdk/internal/module/SystemModules");
     private static final ClassDesc CD_SYSTEM_MODULES_MAP =
             ClassDesc.ofInternalName(SYSTEM_MODULES_MAP_CLASSNAME);
-    private final boolean enabled;
+    private boolean enabled;
 
     public SystemModulesPlugin() {
         super("system-modules");
@@ -519,7 +519,7 @@ public final class SystemModulesPlugin extends 
AbstractPlugin {
 
         private static final int MAX_LOCAL_VARS = 256;
 
-        private final int BUILDER_VAR    = 0;
+        private final int BUILDER_VAR    = MAX_LOCAL_VARS + 1;
         private final int MD_VAR         = 1;  // variable for ModuleDescriptor
         private final int MT_VAR         = 1;  // variable for ModuleTarget
         private final int MH_VAR         = 1;  // variable for ModuleHashes
@@ -666,7 +666,7 @@ public final class SystemModulesPlugin extends 
AbstractPlugin {
          * Generate bytecode for moduleDescriptors method
          */
         private void genModuleDescriptorsMethod(ClassBuilder clb) {
-            if (moduleInfos.size() <= 71) {
+            if (moduleInfos.size() <= 75) {
                 clb.withMethodBody(
                         "moduleDescriptors",
                         MethodTypeDesc.of(CD_MODULE_DESCRIPTOR.arrayType()),
@@ -688,71 +688,98 @@ public final class SystemModulesPlugin extends 
AbstractPlugin {
                 return;
             }
 
-            // split up module infos in "consumable" packages
             List<List<ModuleInfo>> splitModuleInfos = new ArrayList<>();
             List<ModuleInfo> currentModuleInfos = null;
             for (int index = 0; index < moduleInfos.size(); index++) {
-                // The method is "manually split" based on the heuristics that 
90 ModuleDescriptors are smaller than 64kb
-                // The number 10 is chosen "randomly" to be below the 64kb 
limit of a method
-                if (index % 10 == 0) {
-                    // Prepare new list
+                if (index % 50 == 0) {
                     currentModuleInfos = new ArrayList<>();
                     splitModuleInfos.add(currentModuleInfos);
                 }
                 currentModuleInfos.add(moduleInfos.get(index));
             }
-            // generate all helper methods
+
             final String helperMethodNamePrefix = "moduleDescriptorsSub";
+            final ClassDesc arrayListClassDesc = 
ClassDesc.ofInternalName("java/util/ArrayList");
+
+            final int firstVariableForDedup = nextLocalVar;
+
+            clb.withMethodBody(
+                    "moduleDescriptors",
+                    MethodTypeDesc.of(CD_MODULE_DESCRIPTOR.arrayType()),
+                    ACC_PUBLIC,
+                    cob -> {
+                        cob.constantInstruction(moduleInfos.size())
+                                .anewarray(CD_MODULE_DESCRIPTOR)
+                                .dup()
+                                .astore(MD_VAR);
+                        cob.new_(arrayListClassDesc)
+                           .dup()
+                           .invokespecial(arrayListClassDesc, "<init>", 
MethodTypeDesc.of(CD_void))
+                           .astore(nextLocalVar);
+                        cob.aload(0)
+                           .aload(MD_VAR)
+                           .aload(nextLocalVar)
+                           .invokevirtual(
+                                   this.classDesc,
+                                   helperMethodNamePrefix + "0",
+                                   MethodTypeDesc.of(CD_void, 
CD_MODULE_DESCRIPTOR.arrayType(), arrayListClassDesc)
+                           )
+                           .areturn();
+                    });
+
             final int[] globalCount = {0};
             for (final int[] index = {0}; index[0] < splitModuleInfos.size(); 
index[0]++) {
                 clb.withMethodBody(
                         helperMethodNamePrefix + index[0],
-                        MethodTypeDesc.of(CD_void, 
CD_MODULE_DESCRIPTOR.arrayType()),
+                        MethodTypeDesc.of(CD_void, 
CD_MODULE_DESCRIPTOR.arrayType(), arrayListClassDesc),
                         ACC_PUBLIC,
                         cob -> {
                             List<ModuleInfo> moduleInfosPackage = 
splitModuleInfos.get(index[0]);
-                            if (index[0] > 0) {
-                                // call last helper method
-                                cob.aload(0)
-                                   .aload(MD_VAR) // load first parameter, 
which is MD_VAR
-                                   .invokevirtual(
-                                           this.classDesc,
-                                           helperMethodNamePrefix + (index[0] 
- 1),
-                                           MethodTypeDesc.of(CD_void, 
CD_MODULE_DESCRIPTOR.arrayType())
-                                   );
+
+                            if (nextLocalVar > firstVariableForDedup) {
+                                for (int i = nextLocalVar-1; i >= 
firstVariableForDedup; i--) {
+                                    cob.aload(2)
+                                       
.constantInstruction(i-firstVariableForDedup)
+                                       .invokevirtual(arrayListClassDesc, 
"get", MethodTypeDesc.of(CD_Object, CD_int))
+                                       .astore(i);
+                                }
                             }
+
                             for (int j = 0; j < moduleInfosPackage.size(); 
j++) {
                                 ModuleInfo minfo = moduleInfosPackage.get(j);
-                                // executed after the call, thus it is OK to 
overwrite index 0 (BUILDER_VAR)
                                 new ModuleDescriptorBuilder(cob,
                                         minfo.descriptor(),
                                         minfo.packages(),
                                         globalCount[0]).build();
                                 globalCount[0]++;
                             }
+
+                            if (index[0] + 1 < (splitModuleInfos.size())) {
+                                if (nextLocalVar > firstVariableForDedup) {
+                                    cob.new_(arrayListClassDesc)
+                                       .dup()
+                                       .invokespecial(arrayListClassDesc, 
"<init>", MethodTypeDesc.of(CD_void))
+                                       .astore(nextLocalVar);
+                                    for (int i = firstVariableForDedup; i < 
nextLocalVar; i++) {
+                                        cob.aload(nextLocalVar)
+                                           .aload(i)
+                                           .invokevirtual(arrayListClassDesc, 
"add", MethodTypeDesc.of(CD_boolean, CD_Object))
+                                           .pop();
+                                    }
+                                }
+                                cob.aload(0)
+                                   .aload(MD_VAR)
+                                   .aload(nextLocalVar)
+                                   .invokevirtual(
+                                           this.classDesc,
+                                           helperMethodNamePrefix + (index[0] 
+ 1),
+                                           MethodTypeDesc.of(CD_void, 
CD_MODULE_DESCRIPTOR.arrayType(), arrayListClassDesc)
+                                   );
+                            }
+
                             cob.return_();
                         });
             }
-
-            // generate call to last helper method
-            clb.withMethodBody(
-                    "moduleDescriptors",
-                    MethodTypeDesc.of(CD_MODULE_DESCRIPTOR.arrayType()),
-                    ACC_PUBLIC,
-                    cob -> {
-                        cob.constantInstruction(moduleInfos.size())
-                           .anewarray(CD_MODULE_DESCRIPTOR)
-                           .astore(MD_VAR)
-                           .aload(MD_VAR) // storing for the return at the end
-                           .aload(0)
-                           .aload(MD_VAR)
-                           .invokevirtual(
-                                   this.classDesc,
-                                   helperMethodNamePrefix + 
(splitModuleInfos.size() - 1),
-                                   MethodTypeDesc.of(CD_void, 
CD_MODULE_DESCRIPTOR.arrayType())
-                           )
-                           .areturn();
-                    });
         }
 
         /**
diff --git a/test/jdk/tools/jlink/JLink100Modules.java 
b/test/jdk/tools/jlink/JLink100Modules.java
index 4a6111505d2..e71206c904f 100644
--- a/test/jdk/tools/jlink/JLink100Modules.java
+++ b/test/jdk/tools/jlink/JLink100Modules.java
@@ -27,8 +27,10 @@ import java.nio.file.Paths;
 import java.util.Arrays;
 import java.util.StringJoiner;
 import java.util.spi.ToolProvider;
+
 import tests.JImageGenerator;
 import tests.JImageGenerator.JLinkTask;
+
 /*
  * @test
  * @summary Make sure that 100 modules can be linked using jlink.
@@ -46,9 +48,9 @@ import tests.JImageGenerator.JLinkTask;
  */
 public class JLink100Modules {
     private static final ToolProvider JAVAC_TOOL = 
ToolProvider.findFirst("javac")
-                                                               .orElseThrow(() 
-> new RuntimeException("javac tool not found"));
+            .orElseThrow(() -> new RuntimeException("javac tool not found"));
     private static final ToolProvider JLINK_TOOL = 
ToolProvider.findFirst("jlink")
-                                                               .orElseThrow(() 
-> new RuntimeException("jlink tool not found"));
+            .orElseThrow(() -> new RuntimeException("jlink tool not found"));
 
     static void report(String command, String[] args) {
         System.out.println(command + " " + String.join(" ", 
Arrays.asList(args)));
@@ -77,9 +79,10 @@ public class JLink100Modules {
             StringBuilder builder = new StringBuilder("module ");
             builder.append(name).append(" {");
 
-            for (int j = 0; j < i; j++) {
-                builder.append("requires module" + j + "x;");
+            if (i != 0) {
+                builder.append("requires module0x;");
             }
+
             builder.append("}\n");
             Files.writeString(moduleDir.resolve("module-info.java"), 
builder.toString());
             mainModuleInfoContent.add(name);
@@ -106,7 +109,7 @@ public class JLink100Modules {
 
         String out = src.resolve("out").toString();
 
-        javac(new String[] {
+        javac(new String[]{
                 "-d", out,
                 "--module-source-path", src.toString(),
                 "--module", "bug8240567x"
@@ -116,6 +119,7 @@ public class JLink100Modules {
                 .modulePath(out)
                 .output(src.resolve("out-jlink"))
                 .addMods("bug8240567x")
-                .call().assertSuccess();
+                .call()
+                .assertSuccess();
     }
 }

-------------

PR Comment: https://git.openjdk.org/jdk/pull/14408#issuecomment-1594471485

Reply via email to