Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 1.7/1.8 JIT Compiler broken?

I have a problem with some code from GlazedList 1.8 that causes a SIGSEGV when running under java 1.8_05/64 bit/FC20 & Windows 8.

I have the disassembled output (-XX:+UnlockDiagnosticVMOptions '-XX:CompileCommand=print,*BoyerMooreCaseInsensitiveTextSearchStrategy.indexOf' see below) but I no clue on how to debug it.

So any help with debugging the code or a hint to where to ask for help is appreciated.

The disassembled code is more than 30000 chars. long so you will have to go here https://java.net/jira/browse/GLAZEDLISTS-564?focusedCommentId=378982&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-378982 to read the code

A fatal error has been detected by the Java Runtime Environment:

SIGSEGV (0xb) at pc=0x00007fdc2d93bcfc, pid=12092, tid=140582414018304

JRE version: Java(TM) SE Runtime Environment (8.0_05-b13) (build 1.8.0_05-b13) Java VM: Java HotSpot(TM) 64-Bit Server VM (25.5-b02 mixed mode linux-amd64 compressed oops)

Problematic frame:

J 12756 C2

ca.odell.glazedlists.impl.filter.BoyerMooreCaseInsensitiveTextSearchStrategy.indexOf(Ljava/lang/String;)I (147 bytes) @ 0x00007fdc2d93bcfc [0x00007fdc2d93baa0+0x25c]

like image 587
cmadsen Avatar asked Aug 06 '14 12:08

cmadsen


People also ask

What will happen if JIT compiler is not present?

Without the JIT, the VM has to interpret the bytecodes itself - a process that requires extra CPU and memory. The JIT compiler doesn't compile every method that gets called because thousands of methods can be called at startup.

Does OpenJDK have a JIT?

The JIT compiler in OpenJDK. A Java-based JIT compiler takes . class files as input rather than Java code, which is consumed by javac . In this way, a JIT compiler differs from a compiler like GCC, which directly consumes the code that you produce.

Is Java JIT compiled?

The JIT compiler is enabled by default, and is activated when a Java method is called. The JIT compiler compiles the bytecodes of that method into native machine code, compiling it "just in time" to run. When a method has been compiled, the JVM calls the compiled code of that method directly instead of interpreting it.


1 Answers

This is indeed a JIT compiler bug. I've verified that it exists in JDK 7u67, 8u11 as well as in the latest JDK 9 sources. Here is the reduced test case:

public class CharArrayCrash {
    static char[] pattern0 = {0};
    static char[] pattern1 = {1};

    static void test(char[] array) {
        if (pattern1 == null) return;

        int i = 0;
        int pos = 0;
        char c = array[pos];

        while (i >= 0 && (c == pattern0[i] || c == pattern1[i])) {
            i--;
            pos--;
            if (pos != -1) {
                c = array[pos];
            }
        }
    }

    public static void main(String[] args) {
        for (int i = 0; i < 1000000; i++) {
            test(new char[1]);
        }
    }
}

The crash happens on array access instruction where the array offset is illegal (0xffffffff).
Seems like JIT incorrectly reorders decrement and array load instructions.

Anyway, I've submitted the bug report to Oracle: https://bugs.openjdk.java.net/browse/JDK-8054478

like image 124
apangin Avatar answered Oct 31 '22 07:10

apangin