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

Thu, 22 Sep 2011 10:57:37 -0700

author
johnc
date
Thu, 22 Sep 2011 10:57:37 -0700
changeset 3175
4dfb2df418f2
parent 2968
842b840e67db
child 3322
4406629aa157
permissions
-rw-r--r--

6484982: G1: process references during evacuation pauses
Summary: G1 now uses two reference processors - one is used by concurrent marking and the other is used by STW GCs (both full and incremental evacuation pauses). In an evacuation pause, the reference processor is embedded into the closures used to scan objects. Doing so causes causes reference objects to be 'discovered' by the reference processor. At the end of the evacuation pause, these discovered reference objects are processed - preserving (and copying) referent objects (and their reachable graphs) as appropriate.
Reviewed-by: ysr, jwilhelm, brutisso, stefank, tonyp

ysr@777 1 /*
tonyp@2962 2 * Copyright (c) 2001, 2011, 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"
stefank@2314 32
ysr@777 33 /*
ysr@777 34 * This really ought to be an inline function, but apparently the C++
ysr@777 35 * compiler sometimes sees fit to ignore inline declarations. Sigh.
ysr@777 36 */
ysr@777 37
ysr@777 38 // This must a ifdef'ed because the counting it controls is in a
ysr@777 39 // perf-critical inner loop.
ysr@777 40 #define FILTERINTOCSCLOSURE_DOHISTOGRAMCOUNT 0
ysr@777 41
ysr@1280 42 template <class T> inline void FilterIntoCSClosure::do_oop_nv(T* p) {
ysr@1280 43 T heap_oop = oopDesc::load_heap_oop(p);
ysr@1280 44 if (!oopDesc::is_null(heap_oop) &&
ysr@1280 45 _g1->obj_in_cs(oopDesc::decode_heap_oop_not_null(heap_oop))) {
ysr@777 46 _oc->do_oop(p);
ysr@777 47 #if FILTERINTOCSCLOSURE_DOHISTOGRAMCOUNT
johnc@2060 48 if (_dcto_cl != NULL)
johnc@2060 49 _dcto_cl->incr_count();
ysr@777 50 #endif
ysr@777 51 }
ysr@777 52 }
ysr@777 53
ysr@777 54 #define FILTEROUTOFREGIONCLOSURE_DOHISTOGRAMCOUNT 0
ysr@777 55
ysr@1280 56 template <class T> inline void FilterOutOfRegionClosure::do_oop_nv(T* p) {
ysr@1280 57 T heap_oop = oopDesc::load_heap_oop(p);
ysr@1280 58 if (!oopDesc::is_null(heap_oop)) {
ysr@1280 59 HeapWord* obj_hw = (HeapWord*)oopDesc::decode_heap_oop_not_null(heap_oop);
ysr@1280 60 if (obj_hw < _r_bottom || obj_hw >= _r_end) {
ysr@1280 61 _oc->do_oop(p);
ysr@777 62 #if FILTEROUTOFREGIONCLOSURE_DOHISTOGRAMCOUNT
ysr@1280 63 _out_of_region++;
ysr@777 64 #endif
ysr@1280 65 }
ysr@777 66 }
ysr@777 67 }
ysr@777 68
ysr@1280 69 // This closure is applied to the fields of the objects that have just been copied.
ysr@1280 70 template <class T> inline void G1ParScanClosure::do_oop_nv(T* p) {
ysr@1280 71 T heap_oop = oopDesc::load_heap_oop(p);
ysr@1280 72
ysr@1280 73 if (!oopDesc::is_null(heap_oop)) {
ysr@1280 74 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
ysr@1280 75 if (_g1->in_cset_fast_test(obj)) {
ysr@1280 76 // We're not going to even bother checking whether the object is
ysr@1280 77 // already forwarded or not, as this usually causes an immediate
ysr@1280 78 // stall. We'll try to prefetch the object (for write, given that
ysr@1280 79 // we might need to install the forwarding reference) and we'll
ysr@1280 80 // get back to it when pop it from the queue
ysr@1280 81 Prefetch::write(obj->mark_addr(), 0);
ysr@1280 82 Prefetch::read(obj->mark_addr(), (HeapWordSize*2));
ysr@1280 83
ysr@1280 84 // slightly paranoid test; I'm trying to catch potential
ysr@1280 85 // problems before we go into push_on_queue to know where the
ysr@1280 86 // problem is coming from
ysr@1280 87 assert(obj == oopDesc::load_decode_heap_oop(p),
ysr@1280 88 "p should still be pointing to obj");
ysr@1280 89 _par_scan_state->push_on_queue(p);
ysr@1280 90 } else {
ysr@1280 91 _par_scan_state->update_rs(_from, p, _par_scan_state->queue_num());
ysr@1280 92 }
ysr@1280 93 }
ysr@777 94 }
iveresov@1696 95
iveresov@1696 96 template <class T> inline void G1ParPushHeapRSClosure::do_oop_nv(T* p) {
iveresov@1696 97 T heap_oop = oopDesc::load_heap_oop(p);
iveresov@1696 98
iveresov@1696 99 if (!oopDesc::is_null(heap_oop)) {
iveresov@1696 100 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
iveresov@1696 101 if (_g1->in_cset_fast_test(obj)) {
iveresov@1696 102 Prefetch::write(obj->mark_addr(), 0);
iveresov@1696 103 Prefetch::read(obj->mark_addr(), (HeapWordSize*2));
johnc@2060 104
johnc@2060 105 // Place on the references queue
iveresov@1696 106 _par_scan_state->push_on_queue(p);
iveresov@1696 107 }
iveresov@1696 108 }
iveresov@1696 109 }
johnc@2060 110
tonyp@2968 111 template <class T> inline void G1CMOopClosure::do_oop_nv(T* p) {
tonyp@2968 112 assert(_g1h->is_in_g1_reserved((HeapWord*) p), "invariant");
tonyp@2968 113 assert(!_g1h->is_on_master_free_list(
tonyp@2968 114 _g1h->heap_region_containing((HeapWord*) p)), "invariant");
tonyp@2968 115
tonyp@2968 116 oop obj = oopDesc::load_decode_heap_oop(p);
tonyp@2968 117 if (_cm->verbose_high()) {
tonyp@2968 118 gclog_or_tty->print_cr("[%d] we're looking at location "
tonyp@2968 119 "*"PTR_FORMAT" = "PTR_FORMAT,
tonyp@2968 120 _task->task_id(), p, (void*) obj);
tonyp@2968 121 }
tonyp@2968 122 _task->deal_with_reference(obj);
tonyp@2968 123 }
stefank@2314 124
stefank@2314 125 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1OOPCLOSURES_INLINE_HPP

mercurial