src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp

Tue, 21 Aug 2012 14:10:39 -0700

author
johnc
date
Tue, 21 Aug 2012 14:10:39 -0700
changeset 3998
7383557659bd
parent 3957
a2f7274eb6ef
child 4173
8a5ea0a9ccc4
permissions
-rw-r--r--

7185699: G1: Prediction model discrepancies
Summary: Correct the result value of G1CollectedHeap::pending_card_num(). Change the code that calculates the GC efficiency of a non-young heap region to use historical data from mixed GCs and the actual number of live bytes when predicting how long it would take to collect the region. Changes were also reviewed by Thomas Schatzl.
Reviewed-by: azeemj, brutisso

ysr@777 1 /*
tonyp@3464 2 * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
ysr@777 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
ysr@777 4 *
ysr@777 5 * This code is free software; you can redistribute it and/or modify it
ysr@777 6 * under the terms of the GNU General Public License version 2 only, as
ysr@777 7 * published by the Free Software Foundation.
ysr@777 8 *
ysr@777 9 * This code is distributed in the hope that it will be useful, but WITHOUT
ysr@777 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ysr@777 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
ysr@777 12 * version 2 for more details (a copy is included in the LICENSE file that
ysr@777 13 * accompanied this code).
ysr@777 14 *
ysr@777 15 * You should have received a copy of the GNU General Public License version
ysr@777 16 * 2 along with this work; if not, write to the Free Software Foundation,
ysr@777 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ysr@777 18 *
trims@1907 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1907 20 * or visit www.oracle.com if you need additional information or have any
trims@1907 21 * questions.
ysr@777 22 *
ysr@777 23 */
ysr@777 24
stefank@2314 25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1OOPCLOSURES_INLINE_HPP
stefank@2314 26 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1OOPCLOSURES_INLINE_HPP
stefank@2314 27
tonyp@2968 28 #include "gc_implementation/g1/concurrentMark.inline.hpp"
stefank@2314 29 #include "gc_implementation/g1/g1CollectedHeap.hpp"
stefank@2314 30 #include "gc_implementation/g1/g1OopClosures.hpp"
stefank@2314 31 #include "gc_implementation/g1/g1RemSet.hpp"
johnc@3954 32 #include "gc_implementation/g1/heapRegionRemSet.hpp"
stefank@2314 33
ysr@777 34 /*
ysr@777 35 * This really ought to be an inline function, but apparently the C++
ysr@777 36 * compiler sometimes sees fit to ignore inline declarations. Sigh.
ysr@777 37 */
ysr@777 38
tonyp@3464 39 template <class T>
tonyp@3464 40 inline void FilterIntoCSClosure::do_oop_nv(T* p) {
ysr@1280 41 T heap_oop = oopDesc::load_heap_oop(p);
ysr@1280 42 if (!oopDesc::is_null(heap_oop) &&
ysr@1280 43 _g1->obj_in_cs(oopDesc::decode_heap_oop_not_null(heap_oop))) {
ysr@777 44 _oc->do_oop(p);
ysr@777 45 }
ysr@777 46 }
ysr@777 47
tonyp@3464 48 template <class T>
tonyp@3464 49 inline void FilterOutOfRegionClosure::do_oop_nv(T* p) {
ysr@1280 50 T heap_oop = oopDesc::load_heap_oop(p);
ysr@1280 51 if (!oopDesc::is_null(heap_oop)) {
ysr@1280 52 HeapWord* obj_hw = (HeapWord*)oopDesc::decode_heap_oop_not_null(heap_oop);
ysr@1280 53 if (obj_hw < _r_bottom || obj_hw >= _r_end) {
ysr@1280 54 _oc->do_oop(p);
ysr@1280 55 }
ysr@777 56 }
ysr@777 57 }
ysr@777 58
ysr@1280 59 // This closure is applied to the fields of the objects that have just been copied.
tonyp@3464 60 template <class T>
tonyp@3464 61 inline void G1ParScanClosure::do_oop_nv(T* p) {
ysr@1280 62 T heap_oop = oopDesc::load_heap_oop(p);
ysr@1280 63
ysr@1280 64 if (!oopDesc::is_null(heap_oop)) {
ysr@1280 65 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
ysr@1280 66 if (_g1->in_cset_fast_test(obj)) {
ysr@1280 67 // We're not going to even bother checking whether the object is
ysr@1280 68 // already forwarded or not, as this usually causes an immediate
ysr@1280 69 // stall. We'll try to prefetch the object (for write, given that
ysr@1280 70 // we might need to install the forwarding reference) and we'll
ysr@1280 71 // get back to it when pop it from the queue
ysr@1280 72 Prefetch::write(obj->mark_addr(), 0);
ysr@1280 73 Prefetch::read(obj->mark_addr(), (HeapWordSize*2));
ysr@1280 74
ysr@1280 75 // slightly paranoid test; I'm trying to catch potential
ysr@1280 76 // problems before we go into push_on_queue to know where the
ysr@1280 77 // problem is coming from
johnc@3322 78 assert((obj == oopDesc::load_decode_heap_oop(p)) ||
johnc@3322 79 (obj->is_forwarded() &&
johnc@3322 80 obj->forwardee() == oopDesc::load_decode_heap_oop(p)),
johnc@3322 81 "p should still be pointing to obj or to its forwardee");
johnc@3322 82
ysr@1280 83 _par_scan_state->push_on_queue(p);
ysr@1280 84 } else {
ysr@1280 85 _par_scan_state->update_rs(_from, p, _par_scan_state->queue_num());
ysr@1280 86 }
ysr@1280 87 }
ysr@777 88 }
iveresov@1696 89
tonyp@3464 90 template <class T>
tonyp@3464 91 inline void G1ParPushHeapRSClosure::do_oop_nv(T* p) {
iveresov@1696 92 T heap_oop = oopDesc::load_heap_oop(p);
iveresov@1696 93
iveresov@1696 94 if (!oopDesc::is_null(heap_oop)) {
iveresov@1696 95 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
iveresov@1696 96 if (_g1->in_cset_fast_test(obj)) {
iveresov@1696 97 Prefetch::write(obj->mark_addr(), 0);
iveresov@1696 98 Prefetch::read(obj->mark_addr(), (HeapWordSize*2));
johnc@2060 99
johnc@2060 100 // Place on the references queue
iveresov@1696 101 _par_scan_state->push_on_queue(p);
iveresov@1696 102 }
iveresov@1696 103 }
iveresov@1696 104 }
johnc@2060 105
tonyp@3464 106 template <class T>
tonyp@3464 107 inline void G1CMOopClosure::do_oop_nv(T* p) {
tonyp@2968 108 assert(_g1h->is_in_g1_reserved((HeapWord*) p), "invariant");
tonyp@2968 109 assert(!_g1h->is_on_master_free_list(
tonyp@2968 110 _g1h->heap_region_containing((HeapWord*) p)), "invariant");
tonyp@2968 111
tonyp@2968 112 oop obj = oopDesc::load_decode_heap_oop(p);
tonyp@2968 113 if (_cm->verbose_high()) {
tonyp@2968 114 gclog_or_tty->print_cr("[%d] we're looking at location "
tonyp@2968 115 "*"PTR_FORMAT" = "PTR_FORMAT,
tonyp@2968 116 _task->task_id(), p, (void*) obj);
tonyp@2968 117 }
tonyp@2968 118 _task->deal_with_reference(obj);
tonyp@2968 119 }
stefank@2314 120
tonyp@3464 121 template <class T>
tonyp@3464 122 inline void G1RootRegionScanClosure::do_oop_nv(T* p) {
tonyp@3464 123 T heap_oop = oopDesc::load_heap_oop(p);
tonyp@3464 124 if (!oopDesc::is_null(heap_oop)) {
tonyp@3464 125 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
tonyp@3464 126 HeapRegion* hr = _g1h->heap_region_containing((HeapWord*) obj);
tonyp@3464 127 if (hr != NULL) {
tonyp@3464 128 _cm->grayRoot(obj, obj->size(), _worker_id, hr);
tonyp@3464 129 }
tonyp@3464 130 }
tonyp@3464 131 }
tonyp@3464 132
johnc@3466 133 template <class T>
johnc@3466 134 inline void G1Mux2Closure::do_oop_nv(T* p) {
johnc@3466 135 // Apply first closure; then apply the second.
johnc@3466 136 _c1->do_oop(p);
johnc@3466 137 _c2->do_oop(p);
johnc@3466 138 }
johnc@3466 139
johnc@3466 140 template <class T>
johnc@3466 141 inline void G1TriggerClosure::do_oop_nv(T* p) {
johnc@3466 142 // Record that this closure was actually applied (triggered).
johnc@3466 143 _triggered = true;
johnc@3466 144 }
johnc@3466 145
johnc@3466 146 template <class T>
johnc@3466 147 inline void G1InvokeIfNotTriggeredClosure::do_oop_nv(T* p) {
johnc@3466 148 if (!_trigger_cl->triggered()) {
johnc@3466 149 _oop_cl->do_oop(p);
johnc@3466 150 }
johnc@3466 151 }
johnc@3466 152
johnc@3466 153 template <class T>
johnc@3466 154 inline void G1UpdateRSOrPushRefOopClosure::do_oop_nv(T* p) {
johnc@3466 155 oop obj = oopDesc::load_decode_heap_oop(p);
johnc@3466 156 #ifdef ASSERT
johnc@3466 157 // can't do because of races
johnc@3466 158 // assert(obj == NULL || obj->is_oop(), "expected an oop");
johnc@3466 159
johnc@3466 160 // Do the safe subset of is_oop
johnc@3466 161 if (obj != NULL) {
johnc@3466 162 #ifdef CHECK_UNHANDLED_OOPS
johnc@3466 163 oopDesc* o = obj.obj();
johnc@3466 164 #else
johnc@3466 165 oopDesc* o = obj;
johnc@3466 166 #endif // CHECK_UNHANDLED_OOPS
johnc@3466 167 assert((intptr_t)o % MinObjAlignmentInBytes == 0, "not oop aligned");
johnc@3466 168 assert(Universe::heap()->is_in_reserved(obj), "must be in heap");
johnc@3466 169 }
johnc@3466 170 #endif // ASSERT
johnc@3466 171
johnc@3466 172 assert(_from != NULL, "from region must be non-NULL");
johnc@3954 173 assert(_from->is_in_reserved(p), "p is not in from");
johnc@3466 174
johnc@3466 175 HeapRegion* to = _g1->heap_region_containing(obj);
johnc@3466 176 if (to != NULL && _from != to) {
johnc@3466 177 // The _record_refs_into_cset flag is true during the RSet
johnc@3466 178 // updating part of an evacuation pause. It is false at all
johnc@3466 179 // other times:
johnc@3466 180 // * rebuilding the rembered sets after a full GC
johnc@3466 181 // * during concurrent refinement.
johnc@3466 182 // * updating the remembered sets of regions in the collection
johnc@3466 183 // set in the event of an evacuation failure (when deferred
johnc@3466 184 // updates are enabled).
johnc@3466 185
johnc@3466 186 if (_record_refs_into_cset && to->in_collection_set()) {
johnc@3466 187 // We are recording references that point into the collection
johnc@3466 188 // set and this particular reference does exactly that...
johnc@3466 189 // If the referenced object has already been forwarded
johnc@3466 190 // to itself, we are handling an evacuation failure and
johnc@3466 191 // we have already visited/tried to copy this object
johnc@3466 192 // there is no need to retry.
johnc@3466 193 if (!self_forwarded(obj)) {
johnc@3466 194 assert(_push_ref_cl != NULL, "should not be null");
johnc@3466 195 // Push the reference in the refs queue of the G1ParScanThreadState
johnc@3466 196 // instance for this worker thread.
johnc@3466 197 _push_ref_cl->do_oop(p);
johnc@3466 198 }
johnc@3466 199
johnc@3466 200 // Deferred updates to the CSet are either discarded (in the normal case),
johnc@3466 201 // or processed (if an evacuation failure occurs) at the end
johnc@3466 202 // of the collection.
johnc@3466 203 // See G1RemSet::cleanup_after_oops_into_collection_set_do().
johnc@3954 204 return;
johnc@3466 205 }
johnc@3954 206
johnc@3954 207 // We either don't care about pushing references that point into the
johnc@3954 208 // collection set (i.e. we're not during an evacuation pause) _or_
johnc@3954 209 // the reference doesn't point into the collection set. Either way
johnc@3954 210 // we add the reference directly to the RSet of the region containing
johnc@3954 211 // the referenced object.
johnc@3954 212 assert(to->rem_set() != NULL, "Need per-region 'into' remsets.");
johnc@3954 213 to->rem_set()->add_reference(p, _worker_i);
johnc@3466 214 }
johnc@3466 215 }
johnc@3466 216
stefank@2314 217 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1OOPCLOSURES_INLINE_HPP

mercurial