JDK-6821507 : Alignment problem in GC taskqueue
  • Type: Bug
  • Component: hotspot
  • Sub-Component: gc
  • Affected Version: 5.0u18
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: solaris
  • CPU: sparc
  • Submitted: 2009-03-24
  • Updated: 2010-12-03
  • Resolved: 2009-04-06
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.
Other Other JDK 6 JDK 7 Other
5.0u18-rev,hs11.3Fixed 5.0u19Fixed 6u13-revFixed 7Fixed hs11.3Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
Promotion build of 5.0u18-rev-b04 failed:

RE Build Status:
/net/j4b.sfbay/n/tiger/j4b/jdk1.5.0_18/ws
/net/j4b.sfbay/n/tiger/j4b/jdk1.5.0_18/logs

Build Log:
http://jre.sfbay/net/j4b.sfbay/n/tiger/j4b/jdk1.5.0_18/logs/build-solaris-sparc.log

 
Number of Errors: 8
   
Logfile report:

	-o /BUILD_AREA/jdk1.5.0_18/control/build/solaris-sparc/classes/sun/text/resources -spec ../../tools/GenerateBreakIteratorData/../GenerateCharacter/UnicodeData.txt
#
# An unexpected error has been detected by HotSpot Virtual Machine:
#
#  SIGBUS (0xa) at pc=0xfe246c40, pid=1424, tid=5
#
# Java VM: Java HotSpot(TM) Server VM (1.5.0_18-rev-b04-debug mixed mode)
# Problematic frame:
# V  [libjvm_g.so+0xe46c40]
#
# An error report file with more information is saved as hs_err_pid1424.log
[thread 4 also had an error]
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
#
Current thread is 5
Dumping core ...
gnumake[4]: *** [/BUILD_AREA/jdk1.5.0_18/control/build/solaris-sparc/classes/sun/text/resources/CharacterBreakIteratorData] Abort (core dumped)
gnumake[4]: *** Deleting file `/BUILD_AREA/jdk1.5.0_18/control/build/solaris-sparc/classes/sun/text/resources/CharacterBreakIteratorData'
gnumake[4]: Leaving directory `/BUILD_AREA/jdk1.5.0_18/j2se/make/java/text'
gnumake[3]: *** [debug] Error 2
gnumake[3]: Leaving directory `/BUILD_AREA/jdk1.5.0_18/j2se/make/java/text'
gnumake[2]: *** [all] Error 1
gnumake[2]: Leaving directory `/BUILD_AREA/jdk1.5.0_18/j2se/make/java'
gnumake[1]: *** [all] Error 1
gnumake[1]: Leaving directory `/BUILD_AREA/jdk1.5.0_18/j2se/make'
gnumake: *** [j2se-build] Error 2
## Solaris sparc 32-bit local build finished on jb5-sol-sparc

#### RETAG "End Core Build" "FAILED" "03/24/09 03:50:06"

#### RETAG "Start Create Build Result" "" "03/24/09 03:50:06"

#### RETAG "End Create Build Result" "SUCCEEDED" "03/24/09 03:51:04"

#### RETAG "Start Ftp Build Result" "" "03/24/09 03:51:04"
Local directory now /net/j4b.sfbay/n/tiger/j4b/jdk1.5.0_18/ws/control
Interactive mode off.

#### RETAG "End Ftp Build Result" "SUCCEEDED" "03/24/09 03:51:22"

#### RETAG "Start Untar Build Result" "" "03/24/09 03:51:22"

#### RETAG "End Untar Build Result" "SUCCEEDED" "03/24/09 03:52:26"
## Moving buildresult-solaris-sparc.tar to intermediate directory...

#### RETAG "Start Check Core Build" "" "03/24/09 03:52:27"

#### RETAG "End Check Core Build" "FAILED" "03/24/09 03:52:27"
;    


Apparently this is due to an unaligned struct referenced in the change for 
6786503/6787254 exposed by build on jb5-sol-sparc.sfbay

Comments
EVALUATION http://hg.openjdk.java.net/jdk7/hotspot/hotspot/rev/3ee342e25e57
10-08-2009

EVALUATION http://hg.openjdk.java.net/jdk7/hotspot-gc/hotspot/rev/3ee342e25e57
06-08-2009

SUGGESTED FIX Current status: (will rename TAG_FILLER to TAG_ALIGN) Passes the hand run test from the build that failed, passes jprt. --- src/share/vm/utilities/taskqueue.hpp- Mon Mar 23 06:36:09 2009 +++ src/share/vm/utilities/taskqueue.hpp Wed Mar 25 01:13:28 2009 @@ -1,25 +1,33 @@ #ifdef USE_PRAGMA_IDENT_HDR -#pragma ident "@(#)taskqueue.hpp 1.30 09/03/21 00:17:11 JVM" +#pragma ident "@(#)taskqueue.hpp 1.31 09/03/25 01:25:38 JVM" #endif /* - * @(#)taskqueue.hpp 1.30 09/03/21 + * @(#)taskqueue.hpp 1.31 09/03/25 * * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ #ifdef LP64 typedef juint TAG_TYPE; +typedef unsigned long TAG_FILLER; // for a taskqueue size of 4M #define LOG_TASKQ_SIZE 22 #else typedef jushort TAG_TYPE; +typedef unsigned int TAG_FILLER; // for a taskqueue size of 16K #define LOG_TASKQ_SIZE 14 #endif +typedef struct { + TAG_TYPE _top; + TAG_TYPE _tag; +} Age_t; + + class TaskQueueSuper: public CHeapObj { friend class ChunkTaskQueue; protected: // The first free element after the last one pushed (mod _n). @@ -36,17 +44,19 @@ uint n() { return (1 << Log_n); } // For computing "x mod n" efficiently. uint n_mod_mask() { return n() - 1; } struct Age { - TAG_TYPE _top; - TAG_TYPE _tag; + union { + Age_t a; + TAG_FILLER x; + }; - TAG_TYPE tag() const { return _tag; } - TAG_TYPE top() const { return _top; } + TAG_TYPE tag() const { return a._tag; } + TAG_TYPE top() const { return a._top; } - Age() { _tag = 0; _top = 0; } + Age() { a._tag = 0; a._top = 0; } friend bool operator ==(const Age& a1, const Age& a2) { return a1.tag() == a2.tag() && a1.top() == a2.top(); } }; @@ -59,11 +69,11 @@ void set_age(Age a) { *(volatile uint*)(&_age) = *(uint*)(&a); } TAG_TYPE get_top() { - return _age._top; + return _age.a._top; } // These both operate mod _n. uint increment_index(uint ind) { return (ind + 1) & n_mod_mask(); --- src/share/vm/utilities/taskqueue.cpp- Mon Mar 23 06:35:43 2009 +++ src/share/vm/utilities/taskqueue.cpp Wed Mar 25 01:13:28 2009 @@ -1,10 +1,10 @@ #ifdef USE_PRAGMA_IDENT_SRC -#pragma ident "@(#)taskqueue.cpp 1.18 09/03/21 00:17:10 JVM" +#pragma ident "@(#)taskqueue.cpp 1.19 09/03/25 01:25:38 JVM" #endif /* - * @(#)taskqueue.cpp 1.18 09/03/21 + * @(#)taskqueue.cpp 1.19 09/03/25 * * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ @@ -121,12 +121,12 @@ // "top == 0". A pop_global could read the queue element in that case, // then have the owner thread do a pop followed by another push. Without // the incrementing of "tag", the pop_global's CAS could succeed, // allowing it to believe it has claimed the stale element.) Age newAge; - newAge._top = localBot; - newAge._tag = oldAge.tag() + 1; + newAge.a._top = localBot; + newAge.a._tag = oldAge.tag() + 1; // Perhaps a competing pop_global has already incremented "top", in which // case it wins the element. if (localBot == oldAge.top()) { Age tempAge; // No competing pop_global has yet incremented "top"; we'll try to @@ -158,17 +158,17 @@ if (n_elems == 0) { return false; } t = _elems[oldAge.top()]; newAge = oldAge; - newAge._top = increment_index(newAge.top()); - if ( newAge._top == 0 ) newAge._tag++; + newAge.a._top = increment_index(newAge.top()); + if ( newAge.a._top == 0 ) newAge.a._tag++; Age resAge; *(jint*)&resAge = Atomic::cmpxchg(*(jint*)&newAge, (volatile jint*)&_age, *(jint*)&oldAge); // Note that using "_bottom" here might fail, since a pop_local might // have decremented it. - assert(dirty_size(localBot, newAge._top) != n() - 1, + assert(dirty_size(localBot, newAge.a._top) != n() - 1, "Shouldn't be possible..."); return (resAge == oldAge); } OopTaskQueue::~OopTaskQueue() { @@ -208,12 +208,12 @@ // "top == 0". A pop_global could read the queue element in that case, // then have the owner thread do a pop followed by another push. Without // the incrementing of "tag", the pop_global's CAS could succeed, // allowing it to believe it has claimed the stale element.) Age newAge; - newAge._top = localBot; - newAge._tag = oldAge.tag() + 1; + newAge.a._top = localBot; + newAge.a._tag = oldAge.tag() + 1; // Perhaps a competing pop_global has already incremented "top", in which // case it wins the element. if (localBot == oldAge.top()) { Age tempAge; // No competing pop_global has yet incremented "top"; we'll try to @@ -245,17 +245,17 @@ if (n_elems == 0) { return false; } t = _elems[oldAge.top()]; newAge = oldAge; - newAge._top = increment_index(newAge.top()); - if ( newAge._top == 0 ) newAge._tag++; + newAge.a._top = increment_index(newAge.top()); + if ( newAge.a._top == 0 ) newAge.a._tag++; Age resAge; *(jint*)&resAge = Atomic::cmpxchg(*(jint*)&newAge, (volatile jint*)&_age, *(jint*)&oldAge); // Note that using "_bottom" here might fail, since a pop_local might // have decremented it. - assert(dirty_size(localBot, newAge._top) != n() - 1, + assert(dirty_size(localBot, newAge.a._top) != n() - 1, "Shouldn't be possible..."); return (resAge == oldAge); } GenTaskQueue::~GenTaskQueue() {
25-03-2009

EVALUATION Definition of Age and get_age allow short aligned struct to be returned on the stack. Causes cast to int align to fail in use in cmpxchg.
24-03-2009