public class Test {
    static int[] iArrFld = new int[400];
    static int counter;

    public static void main(String[] args) throws Throwable {
        if (args.length != 0) {
            try {
                test();
            } catch (Exception e) {
                // Expected to terminate
            }
            return;
        }
        runInSeparateVM();
    }

    static void runInSeparateVM() throws Throwable {
        String separator = System.getProperty("file.separator");
        String path = System.getProperty("java.home") + separator + "bin" + separator + "java";

        // Javac compile
        String javaFile = Test.class.getProtectionDomain().getCodeSource().getLocation().getPath();
        ProcessBuilder processBuilder = new ProcessBuilder(path + "c", javaFile);
        Process process = processBuilder.inheritIO().start();
        processBuilder.redirectErrorStream(true);
        process.waitFor();

        // Run
        String classpath = javaFile.replace("Test.java", "");
        processBuilder = new ProcessBuilder(path, "-cp", classpath, "-XX:-TieredCompilation", "-Xbatch", "-XX:CompileCommand=compileonly,*::test", Test.class.getCanonicalName(), "run");
        process = processBuilder.inheritIO().start();
        processBuilder.redirectErrorStream(true);
        process.waitFor();
        if (process.exitValue() != 0) {
            throw new RuntimeException("Test failed");
        }
    }

    static int doStuff() {
        int[] more = {94};
        java.util.function.Predicate<Integer> check = m -> m == 0;
        java.util.function.IntConsumer decrement = x -> more[0]--;
        java.util.function.BooleanSupplier innerLoop = () -> {
            while (!check.test(more[0])) {
                decrement.accept(0);
            }
            return true;
        };
        counter++;
        if (counter == 10000000) {
            // Ensure termination
            throw new RuntimeException();
        }
        innerLoop.getAsBoolean();
        java.util.function.BooleanSupplier process = () -> check.test(more[0]);
        while (!process.getAsBoolean()) {
        }


        return 0;
    }

    static void test() {
        int i14 = 1;
        do {
            iArrFld[i14] = 211;
            for (int i15 = 1; i15 < 4; ++i15) {
                i14 = Test.doStuff();
            }
        } while (i14 < 5);
    }
}

