/* * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. *
*/
// There are various techniques that require threads to be able to log // addresses. For example, a generational write barrier might log // the addresses of modified old-generation objects. This type supports // this operation.
class BufferNode; class PtrQueueSet; class PtrQueue { friendclass VMStructs;
NONCOPYABLE(PtrQueue);
// The (byte) index at which an object was last enqueued. Starts at // capacity (in bytes) (indicating an empty buffer) and goes towards zero. // Value is always pointer-size aligned.
size_t _index;
// Size of the current buffer, in bytes. // Value is always pointer-size aligned.
size_t _capacity_in_bytes;
staticconst size_t _element_size = sizeof(void*);
// Get the capacity, in bytes. The capacity must have been set.
size_t capacity_in_bytes() const {
assert(_capacity_in_bytes > 0, "capacity not set"); return _capacity_in_bytes;
}
// Return the BufferNode containing the buffer, after setting its index. static BufferNode* make_node_from_buffer(void** buffer, size_t index) {
BufferNode* node = reinterpret_cast<BufferNode*>( reinterpret_cast<char*>(buffer) - buffer_offset());
node->set_index(index); return node;
}
// Return the buffer for node. staticvoid** make_buffer_from_node(BufferNode *node) { // &_buffer[0] might lead to index out of bounds warnings. returnreinterpret_cast<void**>( reinterpret_cast<char*>(node) + buffer_offset());
}
class AllocatorConfig; class Allocator; // Free-list based allocator. class TestSupport; // Unit test support.
};
// We use BufferNode::AllocatorConfig to set the allocation options for the // FreeListAllocator. class BufferNode::AllocatorConfig : public FreeListConfig { const size_t _buffer_size; public: explicit AllocatorConfig(size_t size);
// A PtrQueueSet represents resources common to a set of pointer queues. // In particular, the individual queues allocate buffers from this shared // set, and return completed buffers to the set. class PtrQueueSet {
BufferNode::Allocator* _allocator;
// Discard any buffered enqueued data. void reset_queue(PtrQueue& queue);
// If queue has any buffered enqueued data, transfer it to this qset. // Otherwise, deallocate queue's buffer. void flush_queue(PtrQueue& queue);
// Add value to queue's buffer, returning true. If buffer is full // or if queue doesn't have a buffer, does nothing and returns false. bool try_enqueue(PtrQueue& queue, void* value);
// Add value to queue's buffer. The queue must have a non-full buffer. // Used after an initial try_enqueue has failed and the situation resolved. void retry_enqueue(PtrQueue& queue, void* value);
// Installs a new buffer into queue. // Returns the old buffer, or null if queue didn't have a buffer.
BufferNode* exchange_buffer_with_new(PtrQueue& queue);
// Installs a new buffer into queue. void install_new_buffer(PtrQueue& queue);
// Return the buffer for a BufferNode of size buffer_size(). void** allocate_buffer();
// Return an empty buffer to the free list. The node is required // to have been allocated with a size of buffer_size(). void deallocate_buffer(BufferNode* node);
// A completed buffer is a buffer the mutator is finished with, and // is ready to be processed by the collector. It need not be full.
// Adds node to the completed buffer list. virtualvoid enqueue_completed_buffer(BufferNode* node) = 0;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.