Fri, 10 Oct 2014 15:51:58 +0200
8059758: Footprint regressions with JDK-8038423
Summary: Changes in JDK-8038423 always initialize (zero out) virtual memory used for auxiliary data structures. This causes a footprint regression for G1 in startup benchmarks. This is because they do not touch that memory at all, so the operating system does not actually commit these pages. The fix is to, if the initialization value of the data structures matches the default value of just committed memory (=0), do not do anything.
Reviewed-by: jwilhelm, brutisso
1 /*
2 * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
25 #include "precompiled.hpp"
26 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
27 #include "gc_implementation/g1/satbQueue.hpp"
28 #include "memory/allocation.inline.hpp"
29 #include "memory/sharedHeap.hpp"
30 #include "oops/oop.inline.hpp"
31 #include "runtime/mutexLocker.hpp"
32 #include "runtime/thread.hpp"
33 #include "runtime/vmThread.hpp"
35 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
37 void ObjPtrQueue::flush() {
38 // The buffer might contain refs into the CSet. We have to filter it
39 // first before we flush it, otherwise we might end up with an
40 // enqueued buffer with refs into the CSet which breaks our invariants.
41 filter();
42 PtrQueue::flush();
43 }
45 // This method removes entries from an SATB buffer that will not be
46 // useful to the concurrent marking threads. An entry is removed if it
47 // satisfies one of the following conditions:
48 //
49 // * it points to an object outside the G1 heap (G1's concurrent
50 // marking only visits objects inside the G1 heap),
51 // * it points to an object that has been allocated since marking
52 // started (according to SATB those objects do not need to be
53 // visited during marking), or
54 // * it points to an object that has already been marked (no need to
55 // process it again).
56 //
57 // The rest of the entries will be retained and are compacted towards
58 // the top of the buffer. Note that, because we do not allow old
59 // regions in the CSet during marking, all objects on the CSet regions
60 // are young (eden or survivors) and therefore implicitly live. So any
61 // references into the CSet will be removed during filtering.
63 void ObjPtrQueue::filter() {
64 G1CollectedHeap* g1h = G1CollectedHeap::heap();
65 void** buf = _buf;
66 size_t sz = _sz;
68 if (buf == NULL) {
69 // nothing to do
70 return;
71 }
73 // Used for sanity checking at the end of the loop.
74 debug_only(size_t entries = 0; size_t retained = 0;)
76 size_t i = sz;
77 size_t new_index = sz;
79 while (i > _index) {
80 assert(i > 0, "we should have at least one more entry to process");
81 i -= oopSize;
82 debug_only(entries += 1;)
83 oop* p = (oop*) &buf[byte_index_to_index((int) i)];
84 oop obj = *p;
85 // NULL the entry so that unused parts of the buffer contain NULLs
86 // at the end. If we are going to retain it we will copy it to its
87 // final place. If we have retained all entries we have visited so
88 // far, we'll just end up copying it to the same place.
89 *p = NULL;
91 bool retain = g1h->is_obj_ill(obj);
92 if (retain) {
93 assert(new_index > 0, "we should not have already filled up the buffer");
94 new_index -= oopSize;
95 assert(new_index >= i,
96 "new_index should never be below i, as we alwaysr compact 'up'");
97 oop* new_p = (oop*) &buf[byte_index_to_index((int) new_index)];
98 assert(new_p >= p, "the destination location should never be below "
99 "the source as we always compact 'up'");
100 assert(*new_p == NULL,
101 "we should have already cleared the destination location");
102 *new_p = obj;
103 debug_only(retained += 1;)
104 }
105 }
107 #ifdef ASSERT
108 size_t entries_calc = (sz - _index) / oopSize;
109 assert(entries == entries_calc, "the number of entries we counted "
110 "should match the number of entries we calculated");
111 size_t retained_calc = (sz - new_index) / oopSize;
112 assert(retained == retained_calc, "the number of retained entries we counted "
113 "should match the number of retained entries we calculated");
114 #endif // ASSERT
116 _index = new_index;
117 }
119 // This method will first apply the above filtering to the buffer. If
120 // post-filtering a large enough chunk of the buffer has been cleared
121 // we can re-use the buffer (instead of enqueueing it) and we can just
122 // allow the mutator to carry on executing using the same buffer
123 // instead of replacing it.
125 bool ObjPtrQueue::should_enqueue_buffer() {
126 assert(_lock == NULL || _lock->owned_by_self(),
127 "we should have taken the lock before calling this");
129 // Even if G1SATBBufferEnqueueingThresholdPercent == 0 we have to
130 // filter the buffer given that this will remove any references into
131 // the CSet as we currently assume that no such refs will appear in
132 // enqueued buffers.
134 // This method should only be called if there is a non-NULL buffer
135 // that is full.
136 assert(_index == 0, "pre-condition");
137 assert(_buf != NULL, "pre-condition");
139 filter();
141 size_t sz = _sz;
142 size_t all_entries = sz / oopSize;
143 size_t retained_entries = (sz - _index) / oopSize;
144 size_t perc = retained_entries * 100 / all_entries;
145 bool should_enqueue = perc > (size_t) G1SATBBufferEnqueueingThresholdPercent;
146 return should_enqueue;
147 }
149 void ObjPtrQueue::apply_closure(ObjectClosure* cl) {
150 if (_buf != NULL) {
151 apply_closure_to_buffer(cl, _buf, _index, _sz);
152 }
153 }
155 void ObjPtrQueue::apply_closure_and_empty(ObjectClosure* cl) {
156 if (_buf != NULL) {
157 apply_closure_to_buffer(cl, _buf, _index, _sz);
158 _index = _sz;
159 }
160 }
162 void ObjPtrQueue::apply_closure_to_buffer(ObjectClosure* cl,
163 void** buf, size_t index, size_t sz) {
164 if (cl == NULL) return;
165 for (size_t i = index; i < sz; i += oopSize) {
166 oop obj = (oop)buf[byte_index_to_index((int)i)];
167 // There can be NULL entries because of destructors.
168 if (obj != NULL) {
169 cl->do_object(obj);
170 }
171 }
172 }
174 #ifndef PRODUCT
175 // Helpful for debugging
177 void ObjPtrQueue::print(const char* name) {
178 print(name, _buf, _index, _sz);
179 }
181 void ObjPtrQueue::print(const char* name,
182 void** buf, size_t index, size_t sz) {
183 gclog_or_tty->print_cr(" SATB BUFFER [%s] buf: "PTR_FORMAT" "
184 "index: "SIZE_FORMAT" sz: "SIZE_FORMAT,
185 name, buf, index, sz);
186 }
187 #endif // PRODUCT
189 #ifdef ASSERT
190 void ObjPtrQueue::verify_oops_in_buffer() {
191 if (_buf == NULL) return;
192 for (size_t i = _index; i < _sz; i += oopSize) {
193 oop obj = (oop)_buf[byte_index_to_index((int)i)];
194 assert(obj != NULL && obj->is_oop(true /* ignore mark word */),
195 "Not an oop");
196 }
197 }
198 #endif
200 #ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away
201 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list
202 #endif // _MSC_VER
204 SATBMarkQueueSet::SATBMarkQueueSet() :
205 PtrQueueSet(), _closure(NULL), _par_closures(NULL),
206 _shared_satb_queue(this, true /*perm*/) { }
208 void SATBMarkQueueSet::initialize(Monitor* cbl_mon, Mutex* fl_lock,
209 int process_completed_threshold,
210 Mutex* lock) {
211 PtrQueueSet::initialize(cbl_mon, fl_lock, process_completed_threshold, -1);
212 _shared_satb_queue.set_lock(lock);
213 if (ParallelGCThreads > 0) {
214 _par_closures = NEW_C_HEAP_ARRAY(ObjectClosure*, ParallelGCThreads, mtGC);
215 }
216 }
218 void SATBMarkQueueSet::handle_zero_index_for_thread(JavaThread* t) {
219 DEBUG_ONLY(t->satb_mark_queue().verify_oops_in_buffer();)
220 t->satb_mark_queue().handle_zero_index();
221 }
223 #ifdef ASSERT
224 void SATBMarkQueueSet::dump_active_states(bool expected_active) {
225 gclog_or_tty->print_cr("Expected SATB active state: %s",
226 expected_active ? "ACTIVE" : "INACTIVE");
227 gclog_or_tty->print_cr("Actual SATB active states:");
228 gclog_or_tty->print_cr(" Queue set: %s", is_active() ? "ACTIVE" : "INACTIVE");
229 for (JavaThread* t = Threads::first(); t; t = t->next()) {
230 gclog_or_tty->print_cr(" Thread \"%s\" queue: %s", t->name(),
231 t->satb_mark_queue().is_active() ? "ACTIVE" : "INACTIVE");
232 }
233 gclog_or_tty->print_cr(" Shared queue: %s",
234 shared_satb_queue()->is_active() ? "ACTIVE" : "INACTIVE");
235 }
237 void SATBMarkQueueSet::verify_active_states(bool expected_active) {
238 // Verify queue set state
239 if (is_active() != expected_active) {
240 dump_active_states(expected_active);
241 guarantee(false, "SATB queue set has an unexpected active state");
242 }
244 // Verify thread queue states
245 for (JavaThread* t = Threads::first(); t; t = t->next()) {
246 if (t->satb_mark_queue().is_active() != expected_active) {
247 dump_active_states(expected_active);
248 guarantee(false, "Thread SATB queue has an unexpected active state");
249 }
250 }
252 // Verify shared queue state
253 if (shared_satb_queue()->is_active() != expected_active) {
254 dump_active_states(expected_active);
255 guarantee(false, "Shared SATB queue has an unexpected active state");
256 }
257 }
258 #endif // ASSERT
260 void SATBMarkQueueSet::set_active_all_threads(bool active, bool expected_active) {
261 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
262 #ifdef ASSERT
263 verify_active_states(expected_active);
264 #endif // ASSERT
265 _all_active = active;
266 for (JavaThread* t = Threads::first(); t; t = t->next()) {
267 t->satb_mark_queue().set_active(active);
268 }
269 shared_satb_queue()->set_active(active);
270 }
272 void SATBMarkQueueSet::filter_thread_buffers() {
273 for(JavaThread* t = Threads::first(); t; t = t->next()) {
274 t->satb_mark_queue().filter();
275 }
276 shared_satb_queue()->filter();
277 }
279 void SATBMarkQueueSet::set_closure(ObjectClosure* closure) {
280 _closure = closure;
281 }
283 void SATBMarkQueueSet::set_par_closure(int i, ObjectClosure* par_closure) {
284 assert(ParallelGCThreads > 0 && _par_closures != NULL, "Precondition");
285 _par_closures[i] = par_closure;
286 }
288 bool SATBMarkQueueSet::apply_closure_to_completed_buffer_work(bool par,
289 uint worker) {
290 BufferNode* nd = NULL;
291 {
292 MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
293 if (_completed_buffers_head != NULL) {
294 nd = _completed_buffers_head;
295 _completed_buffers_head = nd->next();
296 if (_completed_buffers_head == NULL) _completed_buffers_tail = NULL;
297 _n_completed_buffers--;
298 if (_n_completed_buffers == 0) _process_completed = false;
299 }
300 }
301 ObjectClosure* cl = (par ? _par_closures[worker] : _closure);
302 if (nd != NULL) {
303 void **buf = BufferNode::make_buffer_from_node(nd);
304 ObjPtrQueue::apply_closure_to_buffer(cl, buf, 0, _sz);
305 deallocate_buffer(buf);
306 return true;
307 } else {
308 return false;
309 }
310 }
312 void SATBMarkQueueSet::iterate_completed_buffers_read_only(ObjectClosure* cl) {
313 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
314 assert(cl != NULL, "pre-condition");
316 BufferNode* nd = _completed_buffers_head;
317 while (nd != NULL) {
318 void** buf = BufferNode::make_buffer_from_node(nd);
319 ObjPtrQueue::apply_closure_to_buffer(cl, buf, 0, _sz);
320 nd = nd->next();
321 }
322 }
324 void SATBMarkQueueSet::iterate_thread_buffers_read_only(ObjectClosure* cl) {
325 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
326 assert(cl != NULL, "pre-condition");
328 for (JavaThread* t = Threads::first(); t; t = t->next()) {
329 t->satb_mark_queue().apply_closure(cl);
330 }
331 shared_satb_queue()->apply_closure(cl);
332 }
334 #ifndef PRODUCT
335 // Helpful for debugging
337 #define SATB_PRINTER_BUFFER_SIZE 256
339 void SATBMarkQueueSet::print_all(const char* msg) {
340 char buffer[SATB_PRINTER_BUFFER_SIZE];
341 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
343 gclog_or_tty->cr();
344 gclog_or_tty->print_cr("SATB BUFFERS [%s]", msg);
346 BufferNode* nd = _completed_buffers_head;
347 int i = 0;
348 while (nd != NULL) {
349 void** buf = BufferNode::make_buffer_from_node(nd);
350 jio_snprintf(buffer, SATB_PRINTER_BUFFER_SIZE, "Enqueued: %d", i);
351 ObjPtrQueue::print(buffer, buf, 0, _sz);
352 nd = nd->next();
353 i += 1;
354 }
356 for (JavaThread* t = Threads::first(); t; t = t->next()) {
357 jio_snprintf(buffer, SATB_PRINTER_BUFFER_SIZE, "Thread: %s", t->name());
358 t->satb_mark_queue().print(buffer);
359 }
361 shared_satb_queue()->print("Shared");
363 gclog_or_tty->cr();
364 }
365 #endif // PRODUCT
367 void SATBMarkQueueSet::abandon_partial_marking() {
368 BufferNode* buffers_to_delete = NULL;
369 {
370 MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
371 while (_completed_buffers_head != NULL) {
372 BufferNode* nd = _completed_buffers_head;
373 _completed_buffers_head = nd->next();
374 nd->set_next(buffers_to_delete);
375 buffers_to_delete = nd;
376 }
377 _completed_buffers_tail = NULL;
378 _n_completed_buffers = 0;
379 DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked());
380 }
381 while (buffers_to_delete != NULL) {
382 BufferNode* nd = buffers_to_delete;
383 buffers_to_delete = nd->next();
384 deallocate_buffer(BufferNode::make_buffer_from_node(nd));
385 }
386 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
387 // So we can safely manipulate these queues.
388 for (JavaThread* t = Threads::first(); t; t = t->next()) {
389 t->satb_mark_queue().reset();
390 }
391 shared_satb_queue()->reset();
392 }