< prev index next >

src/share/vm/gc/g1/ptrQueue.hpp

Print this page
rev 12859 : imported patch pqsize

*** 51,69 **** // If true, the queue is permanent, and doesn't need to deallocate // its buffer in the destructor (since that obtains a lock which may not // be legally locked by then. const bool _permanent; protected: // The buffer. void** _buf; - // The (byte) index at which an object was last enqueued. Starts at "_sz" - // (indicating an empty buffer) and goes towards zero. - size_t _index; ! // The (byte) size of the buffer. ! size_t _sz; // If there is a lock associated with this buffer, this is that lock. Mutex* _lock; PtrQueueSet* qset() { return _qset; } --- 51,111 ---- // If true, the queue is permanent, and doesn't need to deallocate // its buffer in the destructor (since that obtains a lock which may not // be legally locked by then. const bool _permanent; + // 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; + + static const 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; + } + + void set_capacity(size_t entries) { + size_t byte_capacity = index_to_byte_index(entries); + assert(_capacity_in_bytes == 0 || _capacity_in_bytes == byte_capacity, + "changing capacity " SIZE_FORMAT " -> " SIZE_FORMAT, + _capacity_in_bytes, byte_capacity); + _capacity_in_bytes = byte_capacity; + } + + static size_t byte_index_to_index(size_t ind) { + assert(is_size_aligned(ind, _element_size), "precondition"); + return ind / _element_size; + } + + static size_t index_to_byte_index(size_t ind) { + return ind * _element_size; + } + protected: // The buffer. void** _buf; ! size_t index() const { ! return byte_index_to_index(_index); ! } ! ! void set_index(size_t new_index) { ! size_t byte_index = index_to_byte_index(new_index); ! assert(byte_index <= capacity_in_bytes(), "precondition"); ! _index = byte_index; ! } ! ! size_t capacity() const { ! return byte_index_to_index(capacity_in_bytes()); ! } // If there is a lock associated with this buffer, this is that lock. Mutex* _lock; PtrQueueSet* qset() { return _qset; }
*** 82,92 **** public: // Associate a lock with a ptr queue. void set_lock(Mutex* lock) { _lock = lock; } ! void reset() { if (_buf != NULL) _index = _sz; } void enqueue(volatile void* ptr) { enqueue((void*)(ptr)); } --- 124,139 ---- public: // Associate a lock with a ptr queue. void set_lock(Mutex* lock) { _lock = lock; } ! // Forcibly set empty. ! void reset() { ! if (_buf != NULL) { ! _index = capacity_in_bytes(); ! } ! } void enqueue(volatile void* ptr) { enqueue((void*)(ptr)); }
*** 107,147 **** void handle_zero_index(); void locking_enqueue_completed_buffer(BufferNode* node); void enqueue_known_active(void* ptr); ! size_t size() { ! assert(_sz >= _index, "Invariant."); ! return _buf == NULL ? 0 : _sz - _index; } ! bool is_empty() { ! return _buf == NULL || _sz == _index; } // Set the "active" property of the queue to "b". An enqueue to an // inactive thread is a no-op. Setting a queue to inactive resets its // log to the empty state. void set_active(bool b) { _active = b; if (!b && _buf != NULL) { ! _index = _sz; } else if (b && _buf != NULL) { ! assert(_index == _sz, "invariant: queues are empty when activated."); } } ! bool is_active() { return _active; } ! ! static size_t byte_index_to_index(size_t ind) { ! assert((ind % sizeof(void*)) == 0, "Invariant."); ! return ind / sizeof(void*); ! } ! ! static size_t index_to_byte_index(size_t ind) { ! return ind * sizeof(void*); ! } // To support compiler. protected: template<typename Derived> --- 154,191 ---- void handle_zero_index(); void locking_enqueue_completed_buffer(BufferNode* node); void enqueue_known_active(void* ptr); ! // Return the size of the in-use region. ! size_t size() const { ! size_t result = 0; ! if (_buf != NULL) { ! assert(_index <= capacity_in_bytes(), "Invariant"); ! result = byte_index_to_index(capacity_in_bytes() - _index); ! } ! return result; } ! bool is_empty() const { ! return _buf == NULL || capacity_in_bytes() == _index; } // Set the "active" property of the queue to "b". An enqueue to an // inactive thread is a no-op. Setting a queue to inactive resets its // log to the empty state. void set_active(bool b) { _active = b; if (!b && _buf != NULL) { ! reset(); } else if (b && _buf != NULL) { ! assert(index() == capacity(), ! "invariant: queues are empty when activated."); } } ! bool is_active() const { return _active; } // To support compiler. protected: template<typename Derived>
*** 154,164 **** template<typename Derived> static ByteSize byte_offset_of_buf() { return byte_offset_of(Derived, _buf); } ! static ByteSize byte_width_of_buf() { return in_ByteSize(sizeof(void*)); } template<typename Derived> static ByteSize byte_offset_of_active() { return byte_offset_of(Derived, _active); } --- 198,208 ---- template<typename Derived> static ByteSize byte_offset_of_buf() { return byte_offset_of(Derived, _buf); } ! static ByteSize byte_width_of_buf() { return in_ByteSize(_element_size); } template<typename Derived> static ByteSize byte_offset_of_active() { return byte_offset_of(Derived, _active); }
*** 183,194 **** BufferNode* next() const { return _next; } void set_next(BufferNode* n) { _next = n; } size_t index() const { return _index; } void set_index(size_t i) { _index = i; } ! // Allocate a new BufferNode with the "buffer" having size bytes. ! static BufferNode* allocate(size_t byte_size); // Free a BufferNode. static void deallocate(BufferNode* node); // Return the BufferNode containing the buffer, after setting its index. --- 227,238 ---- BufferNode* next() const { return _next; } void set_next(BufferNode* n) { _next = n; } size_t index() const { return _index; } void set_index(size_t i) { _index = i; } ! // Allocate a new BufferNode with the "buffer" having size elements. ! static BufferNode* allocate(size_t size); // Free a BufferNode. static void deallocate(BufferNode* node); // Return the BufferNode containing the buffer, after setting its index.
*** 211,220 **** --- 255,268 ---- // 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. // All these variables are are protected by the TLOQ_CBL_mon. XXX ??? class PtrQueueSet VALUE_OBJ_CLASS_SPEC { + private: + // The size of all buffers in the set. + size_t _buffer_size; + protected: Monitor* _cbl_mon; // Protects the fields below. BufferNode* _completed_buffers_head; BufferNode* _completed_buffers_tail; size_t _n_completed_buffers;
*** 228,240 **** size_t _buf_free_list_sz; // Queue set can share a freelist. The _fl_owner variable // specifies the owner. It is set to "this" by default. PtrQueueSet* _fl_owner; - // The size of all buffers in the set. - size_t _sz; - bool _all_active; // If true, notify_all on _cbl_mon when the threshold is reached. bool _notify_when_complete; --- 276,285 ----
*** 268,282 **** int max_completed_queue, PtrQueueSet *fl_owner = NULL); public: ! // Return an empty array of size _sz (required to be non-zero). void** allocate_buffer(); ! // Return an empty buffer to the free list. The "buf" argument is ! // required to be a pointer to the head of an array of length "_sz". void deallocate_buffer(BufferNode* node); // Declares that "buf" is a complete buffer. void enqueue_complete_buffer(BufferNode* node); --- 313,327 ---- int max_completed_queue, PtrQueueSet *fl_owner = NULL); public: ! // 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); // Declares that "buf" is a complete buffer. void enqueue_complete_buffer(BufferNode* node);
*** 294,305 **** // Set the buffer size. Should be called before any "enqueue" operation // can be called. And should only be called once. void set_buffer_size(size_t sz); ! // Get the buffer size. ! size_t buffer_size() { return _sz; } // Get/Set the number of completed buffers that triggers log processing. void set_process_completed_threshold(int sz) { _process_completed_threshold = sz; } int process_completed_threshold() const { return _process_completed_threshold; } --- 339,353 ---- // Set the buffer size. Should be called before any "enqueue" operation // can be called. And should only be called once. void set_buffer_size(size_t sz); ! // Get the buffer size. Must have been set. ! size_t buffer_size() const { ! assert(_buffer_size > 0, "buffer size not set"); ! return _buffer_size; ! } // Get/Set the number of completed buffers that triggers log processing. void set_process_completed_threshold(int sz) { _process_completed_threshold = sz; } int process_completed_threshold() const { return _process_completed_threshold; }
< prev index next >