1.1 --- a/src/share/vm/gc_implementation/g1/ptrQueue.hpp Fri Dec 11 09:30:48 2009 -0800 1.2 +++ b/src/share/vm/gc_implementation/g1/ptrQueue.hpp Wed Dec 16 15:12:51 2009 -0800 1.3 @@ -27,8 +27,10 @@ 1.4 // the addresses of modified old-generation objects. This type supports 1.5 // this operation. 1.6 1.7 +// The definition of placement operator new(size_t, void*) in the <new>. 1.8 +#include <new> 1.9 + 1.10 class PtrQueueSet; 1.11 - 1.12 class PtrQueue VALUE_OBJ_CLASS_SPEC { 1.13 1.14 protected: 1.15 @@ -77,7 +79,7 @@ 1.16 else enqueue_known_active(ptr); 1.17 } 1.18 1.19 - inline void handle_zero_index(); 1.20 + void handle_zero_index(); 1.21 void locking_enqueue_completed_buffer(void** buf); 1.22 1.23 void enqueue_known_active(void* ptr); 1.24 @@ -126,34 +128,65 @@ 1.25 1.26 }; 1.27 1.28 +class BufferNode { 1.29 + size_t _index; 1.30 + BufferNode* _next; 1.31 +public: 1.32 + BufferNode() : _index(0), _next(NULL) { } 1.33 + BufferNode* next() const { return _next; } 1.34 + void set_next(BufferNode* n) { _next = n; } 1.35 + size_t index() const { return _index; } 1.36 + void set_index(size_t i) { _index = i; } 1.37 + 1.38 + // Align the size of the structure to the size of the pointer 1.39 + static size_t aligned_size() { 1.40 + static const size_t alignment = round_to(sizeof(BufferNode), sizeof(void*)); 1.41 + return alignment; 1.42 + } 1.43 + 1.44 + // BufferNode is allocated before the buffer. 1.45 + // The chunk of memory that holds both of them is a block. 1.46 + 1.47 + // Produce a new BufferNode given a buffer. 1.48 + static BufferNode* new_from_buffer(void** buf) { 1.49 + return new (make_block_from_buffer(buf)) BufferNode; 1.50 + } 1.51 + 1.52 + // The following are the required conversion routines: 1.53 + static BufferNode* make_node_from_buffer(void** buf) { 1.54 + return (BufferNode*)make_block_from_buffer(buf); 1.55 + } 1.56 + static void** make_buffer_from_node(BufferNode *node) { 1.57 + return make_buffer_from_block(node); 1.58 + } 1.59 + static void* make_block_from_node(BufferNode *node) { 1.60 + return (void*)node; 1.61 + } 1.62 + static void** make_buffer_from_block(void* p) { 1.63 + return (void**)((char*)p + aligned_size()); 1.64 + } 1.65 + static void* make_block_from_buffer(void** p) { 1.66 + return (void*)((char*)p - aligned_size()); 1.67 + } 1.68 +}; 1.69 + 1.70 // A PtrQueueSet represents resources common to a set of pointer queues. 1.71 // In particular, the individual queues allocate buffers from this shared 1.72 // set, and return completed buffers to the set. 1.73 // All these variables are are protected by the TLOQ_CBL_mon. XXX ??? 1.74 class PtrQueueSet VALUE_OBJ_CLASS_SPEC { 1.75 - 1.76 protected: 1.77 - 1.78 - class CompletedBufferNode: public CHeapObj { 1.79 - public: 1.80 - void** buf; 1.81 - size_t index; 1.82 - CompletedBufferNode* next; 1.83 - CompletedBufferNode() : buf(NULL), 1.84 - index(0), next(NULL){ } 1.85 - }; 1.86 - 1.87 Monitor* _cbl_mon; // Protects the fields below. 1.88 - CompletedBufferNode* _completed_buffers_head; 1.89 - CompletedBufferNode* _completed_buffers_tail; 1.90 - size_t _n_completed_buffers; 1.91 - size_t _process_completed_threshold; 1.92 + BufferNode* _completed_buffers_head; 1.93 + BufferNode* _completed_buffers_tail; 1.94 + int _n_completed_buffers; 1.95 + int _process_completed_threshold; 1.96 volatile bool _process_completed; 1.97 1.98 // This (and the interpretation of the first element as a "next" 1.99 // pointer) are protected by the TLOQ_FL_lock. 1.100 Mutex* _fl_lock; 1.101 - void** _buf_free_list; 1.102 + BufferNode* _buf_free_list; 1.103 size_t _buf_free_list_sz; 1.104 // Queue set can share a freelist. The _fl_owner variable 1.105 // specifies the owner. It is set to "this" by default. 1.106 @@ -170,6 +203,7 @@ 1.107 // Maximum number of elements allowed on completed queue: after that, 1.108 // enqueuer does the work itself. Zero indicates no maximum. 1.109 int _max_completed_queue; 1.110 + int _completed_queue_padding; 1.111 1.112 int completed_buffers_list_length(); 1.113 void assert_completed_buffer_list_len_correct_locked(); 1.114 @@ -191,9 +225,12 @@ 1.115 // Because of init-order concerns, we can't pass these as constructor 1.116 // arguments. 1.117 void initialize(Monitor* cbl_mon, Mutex* fl_lock, 1.118 - int max_completed_queue = 0, 1.119 + int process_completed_threshold, 1.120 + int max_completed_queue, 1.121 PtrQueueSet *fl_owner = NULL) { 1.122 _max_completed_queue = max_completed_queue; 1.123 + _process_completed_threshold = process_completed_threshold; 1.124 + _completed_queue_padding = 0; 1.125 assert(cbl_mon != NULL && fl_lock != NULL, "Init order issue?"); 1.126 _cbl_mon = cbl_mon; 1.127 _fl_lock = fl_lock; 1.128 @@ -208,14 +245,17 @@ 1.129 void deallocate_buffer(void** buf); 1.130 1.131 // Declares that "buf" is a complete buffer. 1.132 - void enqueue_complete_buffer(void** buf, size_t index = 0, 1.133 - bool ignore_max_completed = false); 1.134 + void enqueue_complete_buffer(void** buf, size_t index = 0); 1.135 + 1.136 + // To be invoked by the mutator. 1.137 + bool process_or_enqueue_complete_buffer(void** buf); 1.138 1.139 bool completed_buffers_exist_dirty() { 1.140 return _n_completed_buffers > 0; 1.141 } 1.142 1.143 bool process_completed_buffers() { return _process_completed; } 1.144 + void set_process_completed(bool x) { _process_completed = x; } 1.145 1.146 bool active() { return _all_active; } 1.147 1.148 @@ -226,15 +266,24 @@ 1.149 // Get the buffer size. 1.150 size_t buffer_size() { return _sz; } 1.151 1.152 - // Set the number of completed buffers that triggers log processing. 1.153 - void set_process_completed_threshold(size_t sz); 1.154 + // Get/Set the number of completed buffers that triggers log processing. 1.155 + void set_process_completed_threshold(int sz) { _process_completed_threshold = sz; } 1.156 + int process_completed_threshold() const { return _process_completed_threshold; } 1.157 1.158 // Must only be called at a safe point. Indicates that the buffer free 1.159 // list size may be reduced, if that is deemed desirable. 1.160 void reduce_free_list(); 1.161 1.162 - size_t completed_buffers_num() { return _n_completed_buffers; } 1.163 + int completed_buffers_num() { return _n_completed_buffers; } 1.164 1.165 void merge_bufferlists(PtrQueueSet* src); 1.166 - void merge_freelists(PtrQueueSet* src); 1.167 + 1.168 + void set_max_completed_queue(int m) { _max_completed_queue = m; } 1.169 + int max_completed_queue() { return _max_completed_queue; } 1.170 + 1.171 + void set_completed_queue_padding(int padding) { _completed_queue_padding = padding; } 1.172 + int completed_queue_padding() { return _completed_queue_padding; } 1.173 + 1.174 + // Notify the consumer if the number of buffers crossed the threshold 1.175 + void notify_if_necessary(); 1.176 };