RFR(XS): 8001384: G1: assert(!is_null(v)) failed: narrow oop value can never be zero

Bengt Rutisson bengt.rutisson at oracle.com
Wed Jan 30 21:18:09 UTC 2013

Hi John,

Nice detective work to find this issue! Based on your very good 
explanation I think this change looks good!

One small detail. I think the comment in JavaThread::exit() is a little 
confusing. I think you are right in your explanation (and code change) 
that the deferred card marks need to be flushed for all collectors. But 
the comment seems to suggest that it only affects G1:

1899   // Flush any deferred card marks. Flushing may add cards to this
1900   // thread's G1 dirty card queue so we have to do this before
1901   // flushing the G1 barrier queues.

I would prefer to move this comment in to the G1 specific section where 
we flush the barrier queues:

1906   // We must flush G1-related buffers before removing a thread from
1907   // the list of active threads.
1908   if (UseG1GC) {
1909     flush_barrier_queues();
1910   }

The comment could say something like "For G1, flushing the deferred card 
marks may add cards to the thread's dirty card queue. So we need to 
flush the barrier queues after we have flushed the deferred card marks.".

Also, should we update the title of the bug? Should it have the "G1:" 
prefix since it is not a G1 specific fix?


On 1/30/13 8:19 PM, John Cuthbertson wrote:
> Hi Everyone,
> Can I have a couple volunteers review the changes for this CR - the 
> webrev can be found at: 
> http://cr.openjdk.java.net/~johnc/8001384/webrev.0/
> Background:
> The ReduceInitialCardMarks optimization allows the JIT compiler, in 
> some circumstances, to skip generation of the card marks associated 
> with the initializing stores of a newly allocated object. The skipped 
> card marks are then elided into a single deferred operation.
> The deferred card marks are recorded in a field in the allocating 
> thread. Typically deferred card marks are flushed (and the associated 
> cards dirtied) when another set of card marks is to be deferred for 
> the same thread, or at the start of the next GC (in 
> CollectedHeap::ensure_parseability()).
> The problem here was that the deferred card marks, if any, for a given 
> thread were not being flushed when that thread exited. As a result we 
> would end up with missing (card marks) write barriers, (in the case of 
> G1) missing RSet entries, and dangling references.
> The fix is, obviously, flush any deferred cards marks before the 
> thread exits, and before flushing the G1 dirty card queue for the thread.
> Although the problem was found by G1's marking verification 
> (VerifyDuringGC) occasionally detecting missing RSet entries and 
> dangling references, I believe this issue affects all the collectors.
> Testing:
> runThese bigapp on the failing machine with IHOP=10 and marking 
> verification;
> runThese on my local workstation with IHOP=5 and marking verification;
> gc test suite to sanity test the other collectors.
> Thanks,
> JohnC

More information about the hotspot-gc-dev mailing list