Skip to content

Commit 188d585

Browse files
Refine Heavy Load Benchmark to scan and reference all public JavaAPI classes
- Updated `HeavyLoadBenchmarkTest` to scan `JavaAPI.jar` using ASM. - Generate `BenchmarkMain` referencing all detected public classes via `Class.forName`. - Use `@TempDir` for cleanup. - This increases the translation load significantly compared to a simple Hello World.
1 parent 4006469 commit 188d585

File tree

1 file changed

+67
-19
lines changed

1 file changed

+67
-19
lines changed

vm/tests/src/test/java/com/codename1/tools/translator/HeavyLoadBenchmarkTest.java

Lines changed: 67 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import org.junit.jupiter.api.Test;
55
import org.junit.jupiter.api.Assertions;
66
import org.junit.jupiter.api.io.TempDir;
7+
import org.objectweb.asm.ClassReader;
8+
import org.objectweb.asm.Opcodes;
79

810
import javax.tools.JavaCompiler;
911
import javax.tools.ToolProvider;
@@ -19,6 +21,8 @@
1921
import java.util.*;
2022
import java.util.concurrent.atomic.AtomicBoolean;
2123
import java.util.stream.Collectors;
24+
import java.util.zip.ZipEntry;
25+
import java.util.zip.ZipInputStream;
2226

2327
@Tag("benchmark")
2428
public class HeavyLoadBenchmarkTest {
@@ -45,26 +49,47 @@ public void benchmarkJavaAPITranslation() throws Exception {
4549
Files.createDirectories(srcDir);
4650
Files.createDirectories(classesDir);
4751

48-
// Create a heavy main class that references various parts of the API to force traversal
52+
// Scan JavaAPI for public classes to generate a heavy load
53+
List<String> publicClasses = scanPublicClasses(javaApiJar);
54+
System.out.println("Found " + publicClasses.size() + " public classes in JavaAPI.");
55+
56+
// Create a heavy main class that references these classes
4957
Path pkgDir = srcDir.resolve("com").resolve("benchmark");
5058
Files.createDirectories(pkgDir);
5159
Path javaFile = pkgDir.resolve("BenchmarkMain.java");
52-
String source = "package com.benchmark;\n" +
53-
"public class BenchmarkMain {\n" +
54-
" public static void main(String[] args) {\n" +
55-
" java.util.ArrayList l = new java.util.ArrayList();\n" +
56-
" l.add(\"Hello\");\n" +
57-
" java.util.HashMap m = new java.util.HashMap();\n" +
58-
" m.put(\"Key\", l);\n" +
59-
" System.out.println(m);\n" +
60-
" java.util.Vector v = new java.util.Vector();\n" +
61-
" v.addElement(new java.util.Date());\n" +
62-
" try {\n" +
63-
" Class.forName(\"java.util.TimeZone\");\n" +
64-
" } catch (Exception e) {}\n" +
65-
" }\n" +
66-
"}";
67-
Files.write(javaFile, source.getBytes());
60+
61+
StringBuilder source = new StringBuilder();
62+
source.append("package com.benchmark;\n");
63+
source.append("public class BenchmarkMain {\n");
64+
source.append(" public static void main(String[] args) {\n");
65+
source.append(" System.out.println(\"Starting benchmark...\");\n");
66+
67+
// Split into chunks to avoid method size limits
68+
int methodCount = 0;
69+
int chunkSize = 500;
70+
for (int i = 0; i < publicClasses.size(); i += chunkSize) {
71+
source.append(" loadChunk").append(methodCount++).append("();\n");
72+
}
73+
source.append(" }\n");
74+
75+
methodCount = 0;
76+
for (int i = 0; i < publicClasses.size(); i += chunkSize) {
77+
source.append(" private static void loadChunk").append(methodCount++).append("() {\n");
78+
source.append(" try {\n");
79+
source.append(" Class[] classes = new Class[] {\n");
80+
int end = Math.min(i + chunkSize, publicClasses.size());
81+
for (int j = i; j < end; j++) {
82+
String clsName = publicClasses.get(j);
83+
// Use Class.forName to avoid compilation issues with package-private classes/inner classes
84+
source.append(" Class.forName(\"").append(clsName).append("\"),\n");
85+
}
86+
source.append(" };\n");
87+
source.append(" } catch (Throwable t) {}\n");
88+
source.append(" }\n");
89+
}
90+
source.append("}\n");
91+
92+
Files.write(javaFile, source.toString().getBytes());
6893

6994
// Compile the benchmark main
7095
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
@@ -146,9 +171,32 @@ private void runTranslator(String classpath, Path outputDir) throws Exception {
146171
}
147172
}
148173

174+
private List<String> scanPublicClasses(Path jarFile) throws IOException {
175+
List<String> classes = new ArrayList<>();
176+
try (ZipInputStream zis = new ZipInputStream(Files.newInputStream(jarFile))) {
177+
ZipEntry ze;
178+
while ((ze = zis.getNextEntry()) != null) {
179+
if (ze.getName().endsWith(".class") && !ze.getName().startsWith("META-INF")) {
180+
try {
181+
ClassReader cr = new ClassReader(zis);
182+
if ((cr.getAccess() & Opcodes.ACC_PUBLIC) != 0) {
183+
String name = cr.getClassName().replace('/', '.');
184+
if (!name.contains("-") && !name.equals("module-info")) {
185+
classes.add(name);
186+
}
187+
}
188+
} catch (Exception e) {
189+
// ignore bad classes
190+
}
191+
}
192+
}
193+
}
194+
return classes;
195+
}
196+
149197
private void unzip(Path zipFile, Path outputDir) throws IOException {
150-
try (java.util.zip.ZipInputStream zis = new java.util.zip.ZipInputStream(Files.newInputStream(zipFile))) {
151-
java.util.zip.ZipEntry ze = zis.getNextEntry();
198+
try (ZipInputStream zis = new ZipInputStream(Files.newInputStream(zipFile))) {
199+
ZipEntry ze = zis.getNextEntry();
152200
while (ze != null) {
153201
Path newFile = outputDir.resolve(ze.getName());
154202
if (ze.isDirectory()) {

0 commit comments

Comments
 (0)