RFR: 8280438: Improve BufferNode::Allocator::release to avoid walking pending list

Ivan Walulya iwalulya at openjdk.java.net
Mon Jan 31 08:50:16 UTC 2022


On Tue, 25 Jan 2022 05:04:46 GMT, Kim Barrett <kbarrett at openjdk.org> wrote:

> Please review this change to BufferNode::Allocator::release to avoid needing
> to walk the pending list in preparation for transferring it to the free list.
> We need to have both the head and the tail of the pending list to perform that
> transfer.
> 
> Rather than using a LockFreeStack to accumulate the pending list, we now use a
> bespoke data structure that only supports concurrent additions, since that's
> all we need.  This simplifies the code, and also makes it easy to capture the
> first pushed node as the tail.
> 
> To make the transfer from the pending list to the free list, we double-buffer
> the pending list.  Additions are made to the currently active pending list.  A
> transfer flips which pending list is active, and transfers from the list that
> was just deactivated.  Additions are made in a critical section.  The critical
> section synchronization already performed when transferring now does double
> duty, also synchronizing the pending list flip.
> 
> Testing:
> mach5 tier1-3
> 
> Ran a test with -Xlog:gc,ptrqueue,freelist and verified transfers were
> occurring as expected.

src/hotspot/share/gc/shared/ptrQueue.cpp line 88:

> 86: BufferNode::Allocator::Allocator(const char* name, size_t buffer_size) :
> 87:   _buffer_size(buffer_size),
> 88:   _pending_lists{},

Suggestion:

  _pending_lists(),


Some buggy compilers attempt to initialize the aggregate using copy initialization ({ initializer-list }), which consequently calls the deleted PendingList copy constructor. This is a compiler bug; according to the c++14 standard (8.5.1/7 and 8.5.4/3.4), the object should be value-initialized in this case as the initializer list has no elements.

-------------

PR: https://git.openjdk.java.net/jdk/pull/7210



More information about the hotspot-gc-dev mailing list