MopFuzzer is a tool for automated testing of the JDK, utilizing various optimization evoking mutators and profile data-based guidance to rigorously test JVM JIT compilers by maximizing optimization interactions. Our artifact includes the source code of MopFuzzer, the mutation seed files required during the execution of MopFuzzer, and a README file describing the installation process and the bugs discovered by the tool.
In this work, we designed 13 Optimization Evoking Mutators, which aim to trigger primarily the following optimization behaviors respectively: LoopUnrolling, LockElimination, LockCoarsening, Inlining, DeReflection, LoopPeeling, LoopUnswitching, Deoptimization, AutoboxElimination, RedundantStoreElimination, AlgebraicSimplification, EscapeAnalysis, DeadCodeElimination.
The remaining mutators can be found at the Supplementary Material of the paper.
MopFuzzer needs the debug build of JVM, so users should download the source code of JVM and set the debug flag. Here we take the OpenJDK (mainline) as an example.
# git clone https://github.com/openjdk/jdk.git
# cd jdk
# bash configure --enable-debug
# make images JOBS=40
To use MopFuzzer, users should specify the target test case, the path of the debug build of JVM (at least one), We will check whether the outputs of these JDKs are consistant (if perform differential testing). The following is Parameters of running MopFuzzer.
usage: help [-jdk <arg>] [-project_path <arg>] [-target_case <arg>] [-line_number <arg>] [-is_use_jtreg <arg>] [-max_iter <arg>] [-?] [-enable_profile_guide <arg>]
-?,--help Print this help message
--project_path <arg> source code root path. e.g., /home/user/benchmark/jtreg17. Necessary.
--target_case <arg> target java file. e.g., a.b.c denotes a/b/c.java. Necessary.
--use_gc_options use gc options? e.g., true. Default is false.
--use_jit_options use JIT options? e.g., true. Default is false.
--enable_profile_guide <arg> enable profile guidance?
Recommend false for faster testing. Default is
false.
--is_use_jtreg <arg> use Jtreg? e.g., true. Default is false
--jdk <arg> the jdk directory, path to bin/. At least one JDK. Necessary
We will check whether the outputs of these JDKs are consistent.
--line_number <arg> line number of target file to be mutated. e.g., 10. Default is null.
--max_iter <arg> max iteration times.. e.g., 100. Default is 50
Example Command:
# differential testing of two target jdks
path/to/java17/bin/java -jar MopFuzzer.jar --project_path benchmarks/JavaFuzzer/tests/ --target_case Test0001 --jdk path/to/targetJDK1/bin/,path/to/targetJDK2/bin/ --enable_profile_guide true
# Testing a single jdk using jtreg seeds
path/to/java17/bin/java -jar MopFuzzer.jar --project_path benchmarks/jtreg17/ --target_case compiler.codegen.TestBooleanVect --jdk path/to/targetJDK/bin/ --enable_profile_guide true
JDK-8322743
JDK-8322743: assert(held_monitor_count() == jni_monitor_count())
synchronized void write(char[] data, int offset, int length) throws IOException {
while (--length >= 0) {
synchronized (new Test8267042()) {
int var1 = 0;
while (var1 < 100000) {
if (var1 == 50000) {
getZeroOnStack(offset);
}
var1++;
}
}
// original code
// getZeroOnStack(offset);
write(data[offset++]);
}
}
The cause of this bug lies in improper operations during the Just-In-Time (JIT) compiler's escape analysis and On-Stack Replacement (OSR) transformation.
This bug involves optimization processes including escape analysis and lock optimization. Specifically, JVM incorrectly identifies certain objects as non-escaping during escape analysis, leading to incorrect handling of these objects' lock states in the On-Stack Replacement (OSR) transformation, which triggers a crash.
JDK-8324174
JDK-8324174: assert(m->is_entered(current)) failed: invariant
public class Test {
public static final int CHUNK = 10000;
public static ArrayList<Object> arr = new ArrayList<>();
public static void main(String[] args) {
while (true) {
synchronized (Test.class) {
synchronized (new Test()) {
synchronized (Test.class) {
arr.add(new byte[CHUNK]);
}
}
}
}
}
}
The cause of this bug is improper handling of nested synchronized locks during the deoptimization process. The bug involves optimization processes related to deoptimization and the maintenance of synchronized locks.
JVM attempts to eliminate nested locks and locks on non-escaping allocations in the C2 compiler optimization behavior, but during deoptimization, it handles the unlocking and relocking sequence improperly (starting from the inner frame instead of the outer frame), leading to a crash during the deoptimization process.
OpenJ9 Issue #18756
Issue #18756 · eclipse-openj9/openj9 (github.com)
public class Test {
public static final int N = 400;
public static long instanceCount = 3L;
public static int[] iArrFld = new int[N];
public void mainTest(String[] strArr1) {
for (int i0 = 0; i0 < N; i0++) {
Test.iArrFld[i0] = -1;
}
for (int i14 = 343; i14 > 21; --i14) {
Test.instanceCount += (i14 ^ Test.instanceCount);
}
for (int i1 = 0; i1 < N; ++i1) {
for (int var6 = 0; var6 < 10000; ++var6) {
if (var6 == 4) {
}
}
int[] tmp = new int[N];
for (int i2 = 0; i2 < N; i2++) {
tmp[i2] = 9;
}
Test.iArrFld = tmp;
for (int i18 = 3; i18 < 63; i18++) {
Test.iArrFld[i18 - 1] <<= (int) Test.instanceCount;
}
}
long sum = 0;
for (int i : Test.iArrFld) {
sum += i;
}
System.out.println("sum: " + sum);
}
public static void main(String[] strArr) {
Test _instance = new Test();
_instance.mainTest(strArr);
}
}
The cause of this bug is the improper handling of shift operation codes by the JVM during automatic SIMD (Single Instruction, Multiple Data) optimization, leading to behavior inconsistent with Java semantics. This bug involves the optimization process of automatic SIMD optimization. Specifically, the JVM improperly handled the VSHL (Vector Shift Left) operation code during the execution of automatic SIMD optimization.
JVM Flags and the Corresponding Regular Expression Rules for Profiling Optimization Behaviors
JVM Flags | Optimization Behavior Types | Regular Rules |
---|---|---|
TraceLoopOpts | B1: Loop Unrolling | Unroll [0-9]+ |
B2: Loop Peeling | (Partial)?Peel\s{2} |
|
B3: Parallel Induction Variables | Parallel IV: [0-9]+ |
|
B4: Split if | ^SplitIf$ |
|
TraceLoopUnswitching | B5: Loop Unswitching | Loop unswitching orig: [0-9]+ @ [0-9]+ new: |
PrintCEE | B6: Conditional Expression Elimination | [0-9]+\. CEE in B[0-9]+ (B[0-9]+ B[0-9]+) |
PrintInlining | B7: Function Inlining | inline(\s\(hot\))?$ |
TraceDeoptimization | B8: Deoptimization | Uncommon trap |
PrintEscapeAnalysis | B9: Escape Analysis | (UnknownEscape|NoEscape|GlobalEscape|ArgEscape) |
PrintEliminateLocks | B10: Eliminate Locks | (Eliminated: [0-9]+ (Lock|Unlock)|unique_lock) |
B11: Locks Coarsening | (Coarsened [0-9]+ unlocks|unbalanced coarsened) |
|
PrintOptoStatistics | B12: Conditional Constant Propagation | CCP: [0-9]+ |
PrintEliminateAllocations | B13: Eliminate Autobox | Eliminated: [0-9]+ (Allocate|AllocateArray)* |
PrintBlockElimination | B14: Block Elimination | (replaced If and IfOp|merged B[0-9]+) |
PrintPhiFunctions | B15: simplify Phi Function | try_merge for block B[0-9]+ successful |
PrintCanonicalization | B16: Canonicalization | ^canonicalized to:$ |
PrintNullCheckElimination | B17: Null Check Elimination | Done with null check elimination for method |
TraceRangeCheckElimination | B18: Range Check Elimination | Range check for instruction [0-9]+ eliminated |
PrintOptimizePtrCompare | B19: Optimize Ptr Compare | \+\+\+\+ Replaced: [0-9]+ |
Since unconfirmed bugs cannot be shown in Java Bug System(JBS), we only show the bugs that are confirmed by developers.
Issue ID | Link |
---|---|
Issue #18756 | eclipse-openj9/openj9#18756 |
Issue #18765 | eclipse-openj9/openj9#18765 |
Issue #18777 | eclipse-openj9/openj9#18777 |
Issue #18919 | eclipse-openj9/openj9#18919 |
Issue #18860 | eclipse-openj9/openj9#18860 |
Issue #18836 | eclipse-openj9/openj9#18836 |
Issue #18834 | eclipse-openj9/openj9#18834 |
Issue #18955 | eclipse-openj9/openj9#18955 |
Issue #19220 | eclipse-openj9/openj9#19220 |
Issue #19079 | eclipse-openj9/openj9#19079 |
Issue #19012 | eclipse-openj9/openj9#19012 |
Issue #19013 | eclipse-openj9/openj9#19013 |
Issue #19218 | eclipse-openj9/openj9#19218 |
Issue #19080 | eclipse-openj9/openj9#19080 |