JDK-6709165 : Tests hang or misbahve with HS 13.0-b01 on solaris-sparcv9
  • Type: Bug
  • Status: Closed
  • Resolution: Fixed
  • Component: hotspot
  • Sub-Component: compiler
  • Priority: P2
  • Affected Version: hs13
  • OS: generic
  • CPU: generic
  • Submit Date: 2008-05-30
  • Updated Date: 2011-03-07
  • Resolved Date: 2011-03-07
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 Availabitlity Release.

To download the current JDK release, click here.
JDK 6 JDK 7
6u14Resolved 7Fixed
Description
I'm seeing a number tests hanging or misbehaving on solaris-sparcv9 since jdk7-b27 was promoted. jdk7-b27 has HotSpot 13.0-b01. Problems go away if I run with -Xint or exclude specific methods from compilation. I pulled in HotSpot 12.0-b03 from jdk7-b26 and don't observe any problems so this looks like a regression.

Here's an example of a regression test in the JDK repository where compareAndSet seems to be broken:
  test/java/nio/channels/SelectionKey/AtomicAttachTest.java

Works okay when this method is excluded:
exclude java/util/concurrent/atomic/AtomicReferenceFieldUpdater getAndSet

The following is another small test which is hacked from a much larger test that hangs with jdk7-b27. In this case, the test works when java.util.concurrent.locks.AbstractQueuedSynchronizer.enq is excluded from compilation.

import java.util.concurrent.*;

public class Test {
    public static void main(String[] args) throws Exception {
        Executor executor = Executors.newFixedThreadPool(1,
            new ThreadFactory() {
                public Thread newThread(Runnable r) {
                    Thread t = new Thread(r);
                    t.setDaemon(true);
                    return t;
                }
            });

        int i = 0;
        while (i<10000) {
            final CountDownLatch latch =  new CountDownLatch(1);
            executor.execute(new Runnable() {
                public void run() {
                    latch.countDown();
                }
            });
            latch.await();
            i++;
        }
    }
}

Comments
EVALUATION The assembly for CompareAndSwapN is wrong. CAS always destroys the register containing the new value. I think when I wrote the code I must have mistakenly simplified it. The fix is to make the assembly look like the CompareAndSwapI code. I'm not sure how this slipped through all the testing that was done.
2008-05-30

SUGGESTED FIX diff -r 437d03ea40b1 src/cpu/sparc/vm/sparc.ad --- a/src/cpu/sparc/vm/sparc.ad Wed May 21 16:31:35 2008 -0700 +++ b/src/cpu/sparc/vm/sparc.ad Fri May 30 15:36:51 2008 -0700 @@ -6694,8 +6694,9 @@ instruct compareAndSwapN_bool_comp(iRegP Register Rnew = reg_to_register_object($newval$$reg); Register Rres = reg_to_register_object($res$$reg); - __ cas(Rmem, Rold, Rnew); - __ cmp( Rold, Rnew ); + __ mov(Rnew, O7); + __ cas(Rmem, Rold, O7); + __ cmp( Rold, O7 ); __ mov(1, Rres); __ movcc( Assembler::notEqual, false, Assembler::icc, G0, Rres ); %}
2008-05-30