United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6799693 Server compiler leads to data corruption when expression throws an Exception
JDK-6799693 : Server compiler leads to data corruption when expression throws an Exception

Details
Type:
Bug
Submit Date:
2009-01-30
Status:
Closed
Updated Date:
2011-03-08
Project Name:
JDK
Resolved Date:
2011-03-08
Component:
hotspot
OS:
generic
Sub-Component:
compiler
CPU:
generic
Priority:
P2
Resolution:
Fixed
Affected Versions:
hs14
Fixed Versions:
hs15 (b02)

Related Reports
Backport:
Backport:
Duplicate:
Relates:

Sub Tasks

Description
The following test case results in different results when running in -Xcomp and -Xint or -Xmixed modes.

> java -server -Xint Tester
Got java.lang.NegativeArraySizeException
Tester.var_bad = 2 (expected 2)

> java -server -Xmixed Tester
Got java.lang.NegativeArraySizeException
Tester.var_bad = 2 (expected 2)

> java -server -Xcomp -XX:CompileOnly=Tester Tester
Got java.lang.NegativeArraySizeException
Tester.var_bad = 1 (expected 2)

=== Tester.java ===

public class Tester {
   static int var_bad = 1;

   public static void main(String[] args)
   {
      var_bad++;

      try {
         for (int i = 0; i < 10; i++) (new byte[((byte)-1 << i)])[0]  = 0;
      }
      catch (Exception e) { System.out.println("Got " + e); }

      System.out.println("Tester.var_bad = " +  var_bad + " (expected 2)\n");
   }
}

===================

The problem is server compiler specific (32 and 64 bit).

                                    

Comments
EVALUATION

The fix for 6711100 improved our ability to reason about negative array lengths which results in the normal allocation diamond collapsing completely.  The memory uses on the fast path side by the InitializeNode forced the evaluation of the memory effects before the allocation but once that side collapsed only raw memory was being consumed so the stores get lost.  The suggested fix of

  Node *mem;
  if (C->do_escape_analysis()) {
    mem = reset_memory();
    set_all_memory(mem);
  } else {
    //mem = memory(Compile::AliasIdxRaw);
    mem = merged_memory();
  }

seems reasonable though I'm unclear why escape analysis being on or off should effect how memory is handled here.  Can't it simply always be merged_memory()?  This will only occur with constant negative array sizes so it's unlikely to affect real programs.
                                     
2009-02-03
EVALUATION

http://hg.openjdk.java.net/jdk7/hotspot-comp/hotspot/rev/7fe62bb75bf4
                                     
2009-02-06
PUBLIC COMMENTS

Problem:
Both 6799693 and 6795161 bugs has the same cause.
A store can flow below the call on the slow path of an allocation
since an allocation consumes only raw memory slice.
As result when exception happened during the allocation call
the value of store's memory slice is incorrect.

Solution:
Use merged memory state for an allocation's slow path
and raw memory for the fast path.
                                     
2009-02-06



Hardware and Software, Engineered to Work Together