-
Notifications
You must be signed in to change notification settings - Fork 147
Expand file tree
/
Copy pathRuntimeCompileTest.java
More file actions
93 lines (86 loc) · 3.77 KB
/
RuntimeCompileTest.java
File metadata and controls
93 lines (86 loc) · 3.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*
* Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0
*/
package mytest;
import net.openhft.compiler.CachedCompiler;
import net.openhft.compiler.CompilerUtils;
import org.junit.jupiter.api.Test;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.IntSupplier;
import static org.junit.jupiter.api.Assertions.*;
class RuntimeCompileTest {
private static String code = "package mytest;\n" +
"public class Test implements IntConsumer {\n" +
" public void accept(int num) {\n" +
" if ((byte) num != num)\n" +
" throw new IllegalArgumentException();\n" +
" }\n" +
"}\n";
@Test
void outOfBounds() throws Exception {
ClassLoader cl = new URLClassLoader(new URL[0]);
Class<?> aClass = CompilerUtils.CACHED_COMPILER.
loadFromJava(cl, "mytest.Test", code);
IntConsumer consumer = (IntConsumer) aClass.getDeclaredConstructor().newInstance();
consumer.accept(1); // ok
try {
consumer.accept(128); // no ok
fail();
} catch (IllegalArgumentException expected) {
}
}
@Test
void testMultiThread() throws Exception {
StringBuilder largeClass = new StringBuilder("package mytest;\n" +
"public class Test2 implements IntConsumer, java.util.function.IntSupplier {\n" +
" static final java.util.concurrent.atomic.AtomicInteger called = new java.util.concurrent.atomic.AtomicInteger(0);\n" +
" public int getAsInt() { return called.get(); }\n" +
" public void accept(int num) {\n" +
" called.incrementAndGet();\n" +
" }\n");
for (int j = 0; j < 1_000; j++) {
largeClass.append(" public void accept" + j + "(int num) {\n" +
" if ((byte) num != num)\n" +
" throw new IllegalArgumentException();\n" +
" }\n");
}
largeClass.append("}\n");
final String code2 = largeClass.toString();
final ClassLoader cl = new URLClassLoader(new URL[0]);
final CachedCompiler cc = new CachedCompiler(null, null);
final int nThreads = Runtime.getRuntime().availableProcessors();
System.out.println("nThreads = " + nThreads);
final AtomicInteger started = new AtomicInteger(0);
final ExecutorService executor = Executors.newFixedThreadPool(nThreads);
final List<Future<?>> futures = new ArrayList<>();
for (int i = 0; i < nThreads; i++) {
final int value = i;
futures.add(executor.submit(() -> {
started.incrementAndGet();
while (started.get() < nThreads)
;
try {
Class<?> aClass = cc.loadFromJava(cl, "mytest.Test2", code2);
IntConsumer consumer = (IntConsumer) aClass.getDeclaredConstructor().newInstance();
consumer.accept(value);
} catch (Exception e) {
throw new RuntimeException(e);
}
}));
}
executor.shutdown();
for (Future<?> f : futures)
f.get(10, TimeUnit.SECONDS);
Class<?> aClass = cc.loadFromJava(cl, "mytest.Test2", code2);
IntSupplier consumer = (IntSupplier) aClass.getDeclaredConstructor().newInstance();
assertEquals(nThreads, consumer.getAsInt());
}
}