When using conditional card marking in conjunction with CMS precleaning, the conditional card mark check may float above the store of the reference, using invalid information to skip card marking, causing it to loose card updates.
I.e.
mutator:
x.a = something
StoreStore
if (card[@x.a] != dirty) {
card[@x.a] = dirty
}
preclean:
if (card[@x.a] == dirty) {
card[@x.a] = precleaned
}
storeload/loadstore/loadload
read x.a
The storestore barrier in the mutator code does not prevent the check whether the card is dirty to be executed above setting the value in the memory. So the update might get lost because the mutator might see dirty, the preclean thread sets it to preclean, examines the memory and only then the mutator updates the memory.
The storestore synchronization in the mutator is insufficient.
This bug has been in hotspot with CMS since UseCondCardMark code for that has been added to C2.