class LocalSSB extends Deque
Each instance stores word-sized values into a local buffer. When
the buffer is full, or if the flushLocal()
method is
called, the buffer enqueued at the tail of a
SharedDeque
. This class provides no mechanism for
dequeing.
The implementation is intended to be as efficient as possible, in
time and space, as it is used in critical code such as the GC work
queue and the write buffer used by many "remembering"
collectors. Each instance has just two fields: a bump pointer and a
pointer to the SharedDeque
Preconditions: Buffers are always aligned on buffer-size address boundaries.
Invariants: Buffers are filled such that tuples (of the specified arity) are packed to the low end of the buffer. Thus buffer overflows on inserts and pops (underflow actually) will always arise when then cursor is buffer-size aligned.
Modifier and Type | Field and Description |
---|---|
protected SharedDeque |
queue
the shared queue
|
protected Address |
tail
the location in the buffer
|
protected Address |
tailBufferEnd
the end of the buffer
|
BUFFER_MASK, BUFFER_SIZE, HEAD_INITIAL_VALUE, LOG_PAGES_PER_BUFFER, META_DATA_SIZE, NEXT_FIELD_OFFSET, PAGES_PER_BUFFER, TAIL_INITIAL_VALUE, USABLE_BUFFER_BYTES
Constructor and Description |
---|
LocalSSB(SharedDeque queue)
Constructor
|
Modifier and Type | Method and Description |
---|---|
protected Offset |
bufferSentinel(int arity)
Return the sentinel offset for a buffer of a given arity.
|
protected void |
checkTailInsert(int arity)
Check whether there is space in the buffer for a pending insert.
|
private void |
closeAndEnqueueTail(int arity)
Close the tail buffer (normalizing if necessary), and enqueue it
at the tail of the shared buffer queue.
|
void |
flushLocal()
Flush the buffer and add it to the shared queue (this will
make any entries in the buffer visible to any consumer associated
with the shared queue).
|
boolean |
isFlushed()
Return true if this SSB is locally empty
|
protected Address |
normalizeTail(int arity)
In the case where a buffer must be flushed before being
filled (either to the queue or to the head), the entries must be
slid to the base of the buffer in order to preserve the invariant
that all non-tail buffers will have entries starting at the base
(which allows a simple test against the base to be used when
popping entries).
|
void |
reset() |
void |
resetLocal()
Reset the local buffer (throwing away any local entries).
|
private void |
tailOverflow(int arity)
Buffer space has been exhausted, allocate a new buffer and enqueue
the existing buffer (if any).
|
protected void |
uncheckedTailInsert(Address value)
Insert a value into the buffer.
|
bufferEnd, bufferFirst, bufferLast, bufferLast, bufferLastOffset, bufferOffset, bufferStart
protected Address tailBufferEnd
protected final SharedDeque queue
LocalSSB(SharedDeque queue)
queue
- The shared queue to which this local ssb will append
its buffers (when full or flushed).public void flushLocal()
public void reset()
public void resetLocal()
protected final void checkTailInsert(int arity)
arity
- The arity of the values stored in this SSB: the
buffer must contain enough space for this many words.protected final void uncheckedTailInsert(Address value)
checkInsert()
to ensure the
buffer can accommodate the insertion.value
- the value to be inserted.protected final Address normalizeTail(int arity)
arity
- The arity of the buffer in questionprotected final Offset bufferSentinel(int arity)
arity
- The arity of this bufferprivate void tailOverflow(int arity)
arity
- The arity of this buffer (used for sanity test only).private void closeAndEnqueueTail(int arity)
arity
- The arity of this buffer.public final boolean isFlushed()