annotate src/share/vm/gc_implementation/g1/ptrQueue.cpp @ 889:15c5903cf9e1

6865703: G1: Parallelize hot card cache cleanup Summary: Have the GC worker threads clear the hot card cache in parallel by having each worker thread claim a chunk of the card cache and process the cards in that chunk. The size of the chunks that each thread will claim is determined at VM initialization from the size of the card cache and the number of worker threads. Reviewed-by: jmasa, tonyp
author johnc
date Mon, 03 Aug 2009 12:59:30 -0700
parents bd02caa94611
children 5f932a151fd4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
1 /*
844
bd02caa94611 6862919: Update copyright year
xdono
parents: 794
diff changeset
2 * Copyright 2001-2009 Sun Microsystems, Inc. All Rights Reserved.
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
4 *
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
7 * published by the Free Software Foundation.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
8 *
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
13 * accompanied this code).
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
14 *
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
18 *
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
21 * have any questions.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
22 *
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
23 */
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
24
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
25 # include "incls/_precompiled.incl"
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
26 # include "incls/_ptrQueue.cpp.incl"
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
27
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
28 PtrQueue::PtrQueue(PtrQueueSet* qset_, bool perm) :
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
29 _qset(qset_), _buf(NULL), _index(0), _active(false),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
30 _perm(perm), _lock(NULL)
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
31 {}
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
32
441
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 342
diff changeset
33 void PtrQueue::flush() {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
34 if (!_perm && _buf != NULL) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
35 if (_index == _sz) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
36 // No work to do.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
37 qset()->deallocate_buffer(_buf);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
38 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
39 // We must NULL out the unused entries, then enqueue.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
40 for (size_t i = 0; i < _index; i += oopSize) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
41 _buf[byte_index_to_index((int)i)] = NULL;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
42 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
43 qset()->enqueue_complete_buffer(_buf);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
44 }
441
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 342
diff changeset
45 _buf = NULL;
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 342
diff changeset
46 _index = 0;
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
47 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
48 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
49
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
50
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
51 static int byte_index_to_index(int ind) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
52 assert((ind % oopSize) == 0, "Invariant.");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
53 return ind / oopSize;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
54 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
55
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
56 static int index_to_byte_index(int byte_ind) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
57 return byte_ind * oopSize;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
58 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
59
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
60 void PtrQueue::enqueue_known_active(void* ptr) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
61 assert(0 <= _index && _index <= _sz, "Invariant.");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
62 assert(_index == 0 || _buf != NULL, "invariant");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
63
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
64 while (_index == 0) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
65 handle_zero_index();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
66 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
67 assert(_index > 0, "postcondition");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
68
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
69 _index -= oopSize;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
70 _buf[byte_index_to_index((int)_index)] = ptr;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
71 assert(0 <= _index && _index <= _sz, "Invariant.");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
72 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
73
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
74 void PtrQueue::locking_enqueue_completed_buffer(void** buf) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
75 assert(_lock->owned_by_self(), "Required.");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
76 _lock->unlock();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
77 qset()->enqueue_complete_buffer(buf);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
78 // We must relock only because the caller will unlock, for the normal
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
79 // case.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
80 _lock->lock_without_safepoint_check();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
81 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
82
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
83
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
84 PtrQueueSet::PtrQueueSet(bool notify_when_complete) :
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
85 _max_completed_queue(0),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
86 _cbl_mon(NULL), _fl_lock(NULL),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
87 _notify_when_complete(notify_when_complete),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
88 _sz(0),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
89 _completed_buffers_head(NULL),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
90 _completed_buffers_tail(NULL),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
91 _n_completed_buffers(0),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
92 _process_completed_threshold(0), _process_completed(false),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
93 _buf_free_list(NULL), _buf_free_list_sz(0)
616
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
94 {
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
95 _fl_owner = this;
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
96 }
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
97
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
98 void** PtrQueueSet::allocate_buffer() {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
99 assert(_sz > 0, "Didn't set a buffer size.");
616
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
100 MutexLockerEx x(_fl_owner->_fl_lock, Mutex::_no_safepoint_check_flag);
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
101 if (_fl_owner->_buf_free_list != NULL) {
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
102 void** res = _fl_owner->_buf_free_list;
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
103 _fl_owner->_buf_free_list = (void**)_fl_owner->_buf_free_list[0];
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
104 _fl_owner->_buf_free_list_sz--;
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
105 // Just override the next pointer with NULL, just in case we scan this part
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
106 // of the buffer.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
107 res[0] = NULL;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
108 return res;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
109 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
110 return NEW_C_HEAP_ARRAY(void*, _sz);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
111 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
112 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
113
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
114 void PtrQueueSet::deallocate_buffer(void** buf) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
115 assert(_sz > 0, "Didn't set a buffer size.");
616
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
116 MutexLockerEx x(_fl_owner->_fl_lock, Mutex::_no_safepoint_check_flag);
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
117 buf[0] = (void*)_fl_owner->_buf_free_list;
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
118 _fl_owner->_buf_free_list = buf;
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
119 _fl_owner->_buf_free_list_sz++;
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
120 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
121
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
122 void PtrQueueSet::reduce_free_list() {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
123 // For now we'll adopt the strategy of deleting half.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
124 MutexLockerEx x(_fl_lock, Mutex::_no_safepoint_check_flag);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
125 size_t n = _buf_free_list_sz / 2;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
126 while (n > 0) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
127 assert(_buf_free_list != NULL, "_buf_free_list_sz must be wrong.");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
128 void** head = _buf_free_list;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
129 _buf_free_list = (void**)_buf_free_list[0];
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
130 FREE_C_HEAP_ARRAY(void*,head);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
131 n--;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
132 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
133 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
134
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
135 void PtrQueueSet::enqueue_complete_buffer(void** buf, size_t index, bool ignore_max_completed) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
136 // I use explicit locking here because there's a bailout in the middle.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
137 _cbl_mon->lock_without_safepoint_check();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
138
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
139 Thread* thread = Thread::current();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
140 assert( ignore_max_completed ||
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
141 thread->is_Java_thread() ||
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
142 SafepointSynchronize::is_at_safepoint(),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
143 "invariant" );
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
144 ignore_max_completed = ignore_max_completed || !thread->is_Java_thread();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
145
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
146 if (!ignore_max_completed && _max_completed_queue > 0 &&
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
147 _n_completed_buffers >= (size_t) _max_completed_queue) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
148 _cbl_mon->unlock();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
149 bool b = mut_process_buffer(buf);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
150 if (b) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
151 deallocate_buffer(buf);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
152 return;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
153 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
154
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
155 // Otherwise, go ahead and enqueue the buffer. Must reaquire the lock.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
156 _cbl_mon->lock_without_safepoint_check();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
157 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
158
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
159 // Here we still hold the _cbl_mon.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
160 CompletedBufferNode* cbn = new CompletedBufferNode;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
161 cbn->buf = buf;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
162 cbn->next = NULL;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
163 cbn->index = index;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
164 if (_completed_buffers_tail == NULL) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
165 assert(_completed_buffers_head == NULL, "Well-formedness");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
166 _completed_buffers_head = cbn;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
167 _completed_buffers_tail = cbn;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
168 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
169 _completed_buffers_tail->next = cbn;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
170 _completed_buffers_tail = cbn;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
171 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
172 _n_completed_buffers++;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
173
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
174 if (!_process_completed &&
794
315a5d70b295 6484957: G1: parallel concurrent refinement
iveresov
parents: 616
diff changeset
175 _n_completed_buffers >= _process_completed_threshold) {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
176 _process_completed = true;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
177 if (_notify_when_complete)
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
178 _cbl_mon->notify_all();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
179 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
180 debug_only(assert_completed_buffer_list_len_correct_locked());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
181 _cbl_mon->unlock();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
182 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
183
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
184 int PtrQueueSet::completed_buffers_list_length() {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
185 int n = 0;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
186 CompletedBufferNode* cbn = _completed_buffers_head;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
187 while (cbn != NULL) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
188 n++;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
189 cbn = cbn->next;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
190 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
191 return n;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
192 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
193
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
194 void PtrQueueSet::assert_completed_buffer_list_len_correct() {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
195 MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
196 assert_completed_buffer_list_len_correct_locked();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
197 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
198
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
199 void PtrQueueSet::assert_completed_buffer_list_len_correct_locked() {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
200 guarantee((size_t)completed_buffers_list_length() == _n_completed_buffers,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
201 "Completed buffer length is wrong.");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
202 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
203
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
204 void PtrQueueSet::set_buffer_size(size_t sz) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
205 assert(_sz == 0 && sz > 0, "Should be called only once.");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
206 _sz = sz * oopSize;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
207 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
208
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
209 void PtrQueueSet::set_process_completed_threshold(size_t sz) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
210 _process_completed_threshold = sz;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
211 }
616
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
212
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
213 // Merge lists of buffers. Notify waiting threads if the length of the list
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
214 // exceeds threshold. The source queue is emptied as a result. The queues
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
215 // must share the monitor.
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
216 void PtrQueueSet::merge_bufferlists(PtrQueueSet *src) {
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
217 assert(_cbl_mon == src->_cbl_mon, "Should share the same lock");
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
218 MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
219 if (_completed_buffers_tail == NULL) {
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
220 assert(_completed_buffers_head == NULL, "Well-formedness");
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
221 _completed_buffers_head = src->_completed_buffers_head;
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
222 _completed_buffers_tail = src->_completed_buffers_tail;
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
223 } else {
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
224 assert(_completed_buffers_head != NULL, "Well formedness");
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
225 if (src->_completed_buffers_head != NULL) {
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
226 _completed_buffers_tail->next = src->_completed_buffers_head;
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
227 _completed_buffers_tail = src->_completed_buffers_tail;
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
228 }
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
229 }
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
230 _n_completed_buffers += src->_n_completed_buffers;
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
231
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
232 src->_n_completed_buffers = 0;
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
233 src->_completed_buffers_head = NULL;
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
234 src->_completed_buffers_tail = NULL;
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
235
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
236 assert(_completed_buffers_head == NULL && _completed_buffers_tail == NULL ||
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
237 _completed_buffers_head != NULL && _completed_buffers_tail != NULL,
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
238 "Sanity");
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
239
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
240 if (!_process_completed &&
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
241 _n_completed_buffers >= _process_completed_threshold) {
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
242 _process_completed = true;
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
243 if (_notify_when_complete)
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
244 _cbl_mon->notify_all();
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
245 }
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
246 }
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
247
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
248 // Merge free lists of the two queues. The free list of the source
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
249 // queue is emptied as a result. The queues must share the same
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
250 // mutex that guards free lists.
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
251 void PtrQueueSet::merge_freelists(PtrQueueSet* src) {
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
252 assert(_fl_lock == src->_fl_lock, "Should share the same lock");
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
253 MutexLockerEx x(_fl_lock, Mutex::_no_safepoint_check_flag);
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
254 if (_buf_free_list != NULL) {
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
255 void **p = _buf_free_list;
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
256 while (*p != NULL) {
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
257 p = (void**)*p;
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
258 }
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
259 *p = src->_buf_free_list;
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
260 } else {
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
261 _buf_free_list = src->_buf_free_list;
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
262 }
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
263 _buf_free_list_sz += src->_buf_free_list_sz;
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
264 src->_buf_free_list = NULL;
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
265 src->_buf_free_list_sz = 0;
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
266 }