comparison src/share/vm/oops/oop.pcgc.inline.hpp @ 1992:3cd116fd11be

6994628: G1: Test gc/gctests/FinalizeTest05 fails (one live object is finalized) Summary: The Solaris Studio 12 update 1 C++ compiler was incorrectly re-ordering the reads of an object's mark word in oopDesc::forward_to_atomic(). This opened a small window where one thread could execute the successful CAS path even though another thread had already successfully forwarded the object. This could result in an object being copied twice. The code in oopDesc::forward_to_atomic() was changed to read the mark word once. Reviewed-by: ysr, tonyp
author johnc
date Tue, 07 Dec 2010 16:18:45 -0800
parents f95d63e2154a
children e5383553fd4e
comparison
equal deleted inserted replaced
1975:d9310331a29c 1992:3cd116fd11be
116 markOop curMark; 116 markOop curMark;
117 117
118 assert(forwardPtrMark->decode_pointer() == p, "encoding must be reversable"); 118 assert(forwardPtrMark->decode_pointer() == p, "encoding must be reversable");
119 assert(sizeof(markOop) == sizeof(intptr_t), "CAS below requires this."); 119 assert(sizeof(markOop) == sizeof(intptr_t), "CAS below requires this.");
120 120
121 while (!is_forwarded()) { 121 while (!oldMark->is_marked()) {
122 curMark = (markOop)Atomic::cmpxchg_ptr(forwardPtrMark, &_mark, oldMark); 122 curMark = (markOop)Atomic::cmpxchg_ptr(forwardPtrMark, &_mark, oldMark);
123 assert(is_forwarded(), "object should have been forwarded");
123 if (curMark == oldMark) { 124 if (curMark == oldMark) {
124 assert(is_forwarded(), "the CAS should have succeeded.");
125 return NULL; 125 return NULL;
126 } 126 }
127 // If the CAS was unsuccessful then curMark->is_marked()
128 // should return true as another thread has CAS'd in another
129 // forwarding pointer.
127 oldMark = curMark; 130 oldMark = curMark;
128 } 131 }
129 return forwardee(); 132 return forwardee();
130 } 133 }
131 134