JDK-6707044 : uncommon_trap of ifnull bytecode leaves garbage on expression stack
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 6
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: linux
  • CPU: x86
  • Submitted: 2008-05-26
  • Updated: 2011-03-08
  • Resolved: 2011-03-08
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7 Other
6u10Fixed 7Fixed hs11Fixed
Related Reports
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0_06"
Java(TM) SE Runtime Environment (build 1.6.0_06-b02)
Java HotSpot(TM) Server VM (build 10.0-b22, mixed mode)

FULL OS VERSION :
Linux 2.6.22.1 #7 SMP PREEMPT Tue Mar 18 18:22:09 EDT 2008 i686 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
On the Apache Lucene project, we've now had 4 users hit by an apparent
JRE bug.  When this bug strikes, it silently corrupts the search
index, which is very costly to the user (makes the index unusable).
Details are here:

  https://issues.apache.org/jira/browse/LUCENE-1282

I can reliably reproduce the bug, but only on a very large (19 GB)
search index.  But I narrowed down one variant of the bug to attached
test case.

THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: No

THE PROBLEM WAS REPRODUCIBLE WITH -server FLAG: Yes

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the attached code (Crash.java), with -Xbatch and it should fail (ie, throw the
RuntimeException, incorrectly).  It should pass without -Xbatch.


EXPECTED VERSUS ACTUAL BEHAVIOR :
Expected is no RuntimeException should be thrown.  Actual is it is thrown.
REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class Crash {

  public static void main(String[] args) {
    new Crash().crash();
  }

  private Object alwaysNull;

  final void crash() throws Throwable {
    for (int r = 0; r < 3; r++) {
      for (int docNum = 0; docNum < 10000;) {
        if (r < 2) {
          for(int j=0;j<3000;j++)
            docNum++;
        } else {
          docNum++;
          doNothing(getNothing());
          if (alwaysNull != null) {
            throw new RuntimeException("BUG: checkAbort is always null: r=" + r + " of 3; docNum=" + docNum);
          }
        }
      }
    }
  }

  Object getNothing() {
    return this;
  }

  int x;
  void doNothing(Object o) {
    x++;
  }
}


---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Don't specify -Xbatch.  You can also tweak the code to have it pass the test.  Reducing the 10000
or 3000 low enough makes it pass.  Changing the doNothing(...)  line
to assign the result of getNothing() to an intermediate variable
first, also passes (this is the approach we plan to use for Lucene). Removing the x++ also passes.

Comments
EVALUATION http://hg.openjdk.java.net/jdk7/hotspot-comp/hotspot/rev/9b66e6287f4a
16-07-2008

SUGGESTED FIX Remove the call to repush_if_args() in Parse::do_ifnull(). The parser has not popped the argument yet, so a "repush" just puts garbage on the stack.
15-07-2008

EVALUATION When an ifnull or ifnonnull bytecode that has never been reached is compiled by the JIT, it is turned into an uncommon_trap. The path along that uncommon_trap mistakenly leaves an extra, dirty, element on the top of JVM expression stack, causing havoc down the line.
15-07-2008

EVALUATION -Xbatch is not the problem, but it simply causes the interpreter to pause so that the incorrectly generated code can be installed and run. The crashtest.log on apache.org site implies that the problem occurs with -client and -Xint. This is incorrect as the crashtest script has a bug of its own that fails to pass those options to the JVM. The bug is a specific to the server compiler.
10-07-2008