38 |
38 |
39 class PtrQueueSet; |
39 class PtrQueueSet; |
40 class PtrQueue VALUE_OBJ_CLASS_SPEC { |
40 class PtrQueue VALUE_OBJ_CLASS_SPEC { |
41 friend class VMStructs; |
41 friend class VMStructs; |
42 |
42 |
43 protected: |
43 // Noncopyable - not defined. |
|
44 PtrQueue(const PtrQueue&); |
|
45 PtrQueue& operator=(const PtrQueue&); |
|
46 |
44 // The ptr queue set to which this queue belongs. |
47 // The ptr queue set to which this queue belongs. |
45 PtrQueueSet* _qset; |
48 PtrQueueSet* const _qset; |
46 |
49 |
47 // Whether updates should be logged. |
50 // Whether updates should be logged. |
48 bool _active; |
51 bool _active; |
49 |
|
50 // The buffer. |
|
51 void** _buf; |
|
52 // The index at which an object was last enqueued. Starts at "_sz" |
|
53 // (indicating an empty buffer) and goes towards zero. |
|
54 size_t _index; |
|
55 |
|
56 // The size of the buffer. |
|
57 size_t _sz; |
|
58 |
52 |
59 // If true, the queue is permanent, and doesn't need to deallocate |
53 // If true, the queue is permanent, and doesn't need to deallocate |
60 // its buffer in the destructor (since that obtains a lock which may not |
54 // its buffer in the destructor (since that obtains a lock which may not |
61 // be legally locked by then. |
55 // be legally locked by then. |
62 bool _perm; |
56 const bool _permanent; |
|
57 |
|
58 protected: |
|
59 // The buffer. |
|
60 void** _buf; |
|
61 // The (byte) index at which an object was last enqueued. Starts at "_sz" |
|
62 // (indicating an empty buffer) and goes towards zero. |
|
63 size_t _index; |
|
64 |
|
65 // The (byte) size of the buffer. |
|
66 size_t _sz; |
63 |
67 |
64 // If there is a lock associated with this buffer, this is that lock. |
68 // If there is a lock associated with this buffer, this is that lock. |
65 Mutex* _lock; |
69 Mutex* _lock; |
66 |
70 |
67 PtrQueueSet* qset() { return _qset; } |
71 PtrQueueSet* qset() { return _qset; } |
68 bool is_permanent() const { return _perm; } |
72 bool is_permanent() const { return _permanent; } |
69 |
73 |
70 // Process queue entries and release resources, if not permanent. |
74 // Process queue entries and release resources, if not permanent. |
71 void flush_impl(); |
75 void flush_impl(); |
72 |
76 |
73 public: |
|
74 // Initialize this queue to contain a null buffer, and be part of the |
77 // Initialize this queue to contain a null buffer, and be part of the |
75 // given PtrQueueSet. |
78 // given PtrQueueSet. |
76 PtrQueue(PtrQueueSet* qset, bool perm = false, bool active = false); |
79 PtrQueue(PtrQueueSet* qset, bool permanent = false, bool active = false); |
77 |
80 |
78 // Requires queue flushed or permanent. |
81 // Requires queue flushed or permanent. |
79 ~PtrQueue(); |
82 ~PtrQueue(); |
|
83 |
|
84 public: |
80 |
85 |
81 // Associate a lock with a ptr queue. |
86 // Associate a lock with a ptr queue. |
82 void set_lock(Mutex* lock) { _lock = lock; } |
87 void set_lock(Mutex* lock) { _lock = lock; } |
83 |
88 |
84 void reset() { if (_buf != NULL) _index = _sz; } |
89 void reset() { if (_buf != NULL) _index = _sz; } |
127 } |
132 } |
128 } |
133 } |
129 |
134 |
130 bool is_active() { return _active; } |
135 bool is_active() { return _active; } |
131 |
136 |
132 static int byte_index_to_index(int ind) { |
137 static size_t byte_index_to_index(size_t ind) { |
133 assert((ind % oopSize) == 0, "Invariant."); |
138 assert((ind % sizeof(void*)) == 0, "Invariant."); |
134 return ind / oopSize; |
139 return ind / sizeof(void*); |
135 } |
|
136 |
|
137 static int index_to_byte_index(int byte_ind) { |
|
138 return byte_ind * oopSize; |
|
139 } |
140 } |
140 |
141 |
141 // To support compiler. |
142 // To support compiler. |
142 static ByteSize byte_offset_of_index() { |
143 static ByteSize byte_offset_of_index() { |
143 return byte_offset_of(PtrQueue, _index); |
144 return byte_offset_of(PtrQueue, _index); |
244 virtual bool mut_process_buffer(void** buf) { |
245 virtual bool mut_process_buffer(void** buf) { |
245 ShouldNotReachHere(); |
246 ShouldNotReachHere(); |
246 return false; |
247 return false; |
247 } |
248 } |
248 |
249 |
249 public: |
|
250 // Create an empty ptr queue set. |
250 // Create an empty ptr queue set. |
251 PtrQueueSet(bool notify_when_complete = false); |
251 PtrQueueSet(bool notify_when_complete = false); |
|
252 ~PtrQueueSet(); |
252 |
253 |
253 // Because of init-order concerns, we can't pass these as constructor |
254 // Because of init-order concerns, we can't pass these as constructor |
254 // arguments. |
255 // arguments. |
255 void initialize(Monitor* cbl_mon, Mutex* fl_lock, |
256 void initialize(Monitor* cbl_mon, |
|
257 Mutex* fl_lock, |
256 int process_completed_threshold, |
258 int process_completed_threshold, |
257 int max_completed_queue, |
259 int max_completed_queue, |
258 PtrQueueSet *fl_owner = NULL) { |
260 PtrQueueSet *fl_owner = NULL); |
259 _max_completed_queue = max_completed_queue; |
261 |
260 _process_completed_threshold = process_completed_threshold; |
262 public: |
261 _completed_queue_padding = 0; |
263 |
262 assert(cbl_mon != NULL && fl_lock != NULL, "Init order issue?"); |
264 // Return an empty array of size _sz (required to be non-zero). |
263 _cbl_mon = cbl_mon; |
|
264 _fl_lock = fl_lock; |
|
265 _fl_owner = (fl_owner != NULL) ? fl_owner : this; |
|
266 } |
|
267 |
|
268 // Return an empty oop array of size _sz (required to be non-zero). |
|
269 void** allocate_buffer(); |
265 void** allocate_buffer(); |
270 |
266 |
271 // Return an empty buffer to the free list. The "buf" argument is |
267 // Return an empty buffer to the free list. The "buf" argument is |
272 // required to be a pointer to the head of an array of length "_sz". |
268 // required to be a pointer to the head of an array of length "_sz". |
273 void deallocate_buffer(void** buf); |
269 void deallocate_buffer(void** buf); |