--- old/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp 2020-02-11 11:09:16.576858676 -0500 +++ new/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp 2020-02-11 11:09:16.312844389 -0500 @@ -77,11 +77,8 @@ }; // A lock-free FIFO of BufferNodes, linked through their next() fields. - // This class has a restriction that pop() cannot return the last buffer - // in the queue, or what was the last buffer for a concurrent push/append - // operation. It is expected that there will be a later push/append that - // will make that buffer available to a future pop(), or there will - // eventually be a complete transfer via take_all(). + // This class has a restriction that pop() may return NULL when there are + // buffers in the queue if there is a concurrent push/append operation. class Queue { BufferNode* volatile _head; DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(BufferNode*)); @@ -105,9 +102,10 @@ void append(BufferNode& first, BufferNode& last); // Thread-safe attempt to remove and return the first buffer in the queue. - // Returns NULL if the queue is empty, or if only one buffer is found. - // Uses GlobalCounter critical sections to address the ABA problem; this - // works with the buffer allocator's use of GlobalCounter synchronization. + // Returns NULL if the queue is empty, or if a concurrent push/append + // interferes. Uses GlobalCounter critical sections to address the ABA + // problem; this works with the buffer allocator's use of GlobalCounter + // synchronization. BufferNode* pop(); // Take all the buffers from the queue, leaving the queue empty.