United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6865031 Application gives bad result (throws bad exception) with compressed oops
JDK-6865031 : Application gives bad result (throws bad exception) with compressed oops

Details
Type:
Bug
Submit Date:
2009-07-27
Status:
Closed
Updated Date:
2011-03-08
Project Name:
JDK
Resolved Date:
2011-03-08
Component:
hotspot
OS:
linux,generic,solaris_10
Sub-Component:
compiler
CPU:
x86,generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
6u14,6u14p
Fixed Versions:
hs16 (b08)

Related Reports
Backport:
Backport:
Backport:
Backport:
Backport:
Backport:
Duplicate:
Duplicate:
Relates:
Relates:
Relates:

Sub Tasks

Description
FULL PRODUCT VERSION :
java 6 update 14

FULL OS VERSION :
Linux RHEL 5

A DESCRIPTION OF THE PROBLEM :
While testing the -XX:+UseCompressedOops option with 6u14, we found that one of our applications started giving bad results and incorrect runtime behaviour. We have reduced this to a test case. The problem doesn't happen if you run without the -XX:+UseCompressedOops flag but that flag is the major driver for moving to this release.

Note that this is *not* the same problem as http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6851282. We tried retrofitting that fix into the 6u14 source base and building a local libjvm.so. Although it fixes the test case in that bug report, we still get the same intermittent exception.

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.

I run it as

java -XX:+UseCompressedOops hello goodbye

EXPECTED VERSUS ACTUAL BEHAVIOR :
It should just return normally.

About one time in five (although it varies so you might need to run it more often to make it happen) it crashes with a stack trace. The stack trace is obviously wrong because it shows that the "this" and the argument are both instances of DoubletonList, but the class being accessed is an instance of SingletonList.

Here is the output:

THROWING RT EXC
concurrent modification of this:class DoubletonList:1414159026; that:class DoubletonList:1569228633; i:1
java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
 23     at SingletonList.get(ToS.java:74)
       WeakPool::       at AbstractMemoryEfficientList.equals(ToS.java:34)
ge      at java.util.AbstractList.equals(AbstractList.java:507)
tTable (9 bytes)
        at MultiSynonymKey.equals(ToS.java:544)
        at WeakPool.eq(ToS.java:154)
        at WeakPool.put(ToS.java:307)
        at ToS.main(ToS.java:607)

As you can see, both "this" and the input arg are instances of DoubletonList but the stack trace shows that SingletonList.get() has been called.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
THROWING RT EXC
concurrent modification of this:class DoubletonList:1414159026; that:class DoubletonList:1569228633; i:1
java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
 23     at SingletonList.get(ToS.java:74)
       WeakPool::       at AbstractMemoryEfficientList.equals(ToS.java:34)
ge      at java.util.AbstractList.equals(AbstractList.java:507)
tTable (9 bytes)
        at MultiSynonymKey.equals(ToS.java:544)
        at WeakPool.eq(ToS.java:154)
        at WeakPool.put(ToS.java:307)
        at ToS.main(ToS.java:607)



REPRODUCIBILITY :
This bug can be reproduced occasionally.

---------- BEGIN SOURCE ----------
Attached seperatly
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Turn off -XX:+UseCompressedOops, but we only really are using 6u14 to get compressed oops.

                                    

Comments
EVALUATION

The problem at the same place as in 6851282.
The new Phi narrow type is incorrect for the next case since it is based on the type of one of inputs
which could be subtype:

 2910   ConN    ===  0  [[ 2854 ]]  #narrowoop: precise klass DoubletonList: 0x00000000008101f8:Constant:exact *
 2911   ConN    ===  0  [[ 2853 ]]  #narrowoop: precise klass SingletonList: 0x0000000000810118:Constant:exact *
 2854   DecodeN === _  2910  [[ 2869 ]]  #klass AbstractMemoryEfficientList: 0x00000000008546b8 *  Klass:klass AbstractMemoryEfficientList: 0x00000000008546b8 * !orig=[1876] !jvms: AbstractMemoryEfficientList::equals @ bci:53 AbstractList::equals @ bci:-1
 2853   DecodeN === _  2911  [[ 2869 ]]  #klass AbstractMemoryEfficientList: 0x00000000008546b8 *  Klass:klass AbstractMemoryEfficientList: 0x00000000008546b8 * !orig=[1876] !jvms: AbstractMemoryEfficientList::equals @ bci:53 AbstractList::equals @ bci:-1
 2869   Phi     ===  2862  2853  2854  [[ 2858  2856 ]]  #klass AbstractMemoryEfficientList: 0x00000000008546b8 *  Klass:klass AbstractMemoryEfficientList: 0x00000000008546b8 * !orig=[2852],[1876] !jvms: AbstractMemoryEfficientList::equals @ bci:53 AbstractList::equals @ bci:-1

After the optimization in PhiNode::Ideal we will get new Phi with incorrect type:

 2910   ConN    ===  0  [[ 2854  2916 ]]  #narrowoop: precise klass DoubletonList: 0x00000000008101f8:Constant:exact *
 2911   ConN    ===  0  [[ 2853  2916 ]]  #narrowoop: precise klass SingletonList: 0x0000000000810118:Constant:exact *
  2916   Phi     ===  2862  2911  2910  [[ 2917 ]]  #narrowoop: precise klass DoubletonList: 0x00000000008101f8:Constant:exact * !orig=2869,[2852],[1876] !jvms: AbstractMemoryEfficientList::equals @ bci:53 AbstractList::equals @ bci:-1

The Phi is used in Cmp node and as result of wrong type the result of Cmp is wrong. It leads to incorrect graph and generated code.
                                     
2009-07-30
SUGGESTED FIX

src/share/vm/opto/cfgnode.cpp	Wed Jul 29 18:27:17 2009 -0700
@@ -1792,15 +1792,12 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bo
   if (UseCompressedOops && can_reshape && progress == NULL) {
     bool may_push = true;
     bool has_decodeN = false;
-    Node* in_decodeN = NULL;
     for (uint i=1; i<req(); ++i) {// For all paths in
       Node *ii = in(i);
       if (ii->is_DecodeN() && ii->bottom_type() == bottom_type()) {
-        // Note: in_decodeN is used only to define the type of new phi.
-        // Find a non dead path otherwise phi type will be wrong.
+        // Do optimization if a non dead path exist.
         if (ii->in(1)->bottom_type() != Type::TOP) {
           has_decodeN = true;
-          in_decodeN = ii->in(1);
         }
       } else if (!ii->is_Phi()) {
         may_push = false;
@@ -1809,7 +1806,9 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bo
 
     if (has_decodeN && may_push) {
       PhaseIterGVN *igvn = phase->is_IterGVN();
-      PhiNode *new_phi = PhiNode::make_blank(in(0), in_decodeN);
+      // Make narrow type for new phi.
+      const Type* narrow_t = TypeNarrowOop::make(this->bottom_type()->is_ptr());
+      PhiNode* new_phi = new (phase->C, r->req()) PhiNode(r, narrow_t);
       uint orig_cnt = req();
       for (uint i=1; i<req(); ++i) {// For all paths in
         Node *ii = in(i);
@@ -1822,7 +1821,7 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bo
           if (ii->as_Phi() == this) {
             new_ii = new_phi;
           } else {
-            new_ii = new (phase->C, 2) EncodePNode(ii, in_decodeN->bottom_type());
+            new_ii = new (phase->C, 2) EncodePNode(ii, narrow_t);
             igvn->register_new_node_with_optimizer(new_ii);
           }
         }
                                     
2009-07-30
EVALUATION

http://hg.openjdk.java.net/jdk7/hotspot-comp/hotspot/rev/55cb84cd1247
                                     
2009-07-31
PUBLIC COMMENTS

Problem:
The problem at the same place as in 6851282.
The new Phi narrow type is incorrect since it is based
on the type of one of inputs which could be subtype of
the original Phi's type. The Phi is used in CmpP node
which gives a wrong result since Phi's type is wrong.
It leads to incorrect graph and generated code.

Solution:
Produce narrow type for new Phi from the original type
instead of using a type of Phi's input.
                                     
2009-07-31
EVALUATION

http://hg.openjdk.java.net/jdk7/hotspot-gc/hotspot/rev/55cb84cd1247
                                     
2009-08-10



Hardware and Software, Engineered to Work Together