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

Fri, 06 Aug 2010 10:17:21 -0700

author
johnc
date
Fri, 06 Aug 2010 10:17:21 -0700
changeset 2063
a03ae377b2e8
parent 2060
2d160770d2e5
child 2216
c32059ef4dc0
permissions
-rw-r--r--

6930581: G1: assert(ParallelGCThreads > 1 || n_yielded() == _hrrs->occupied(),"Should have yielded all the ..
Summary: During RSet updating, when ParallelGCThreads is zero, references that point into the collection set are added directly the referenced region's RSet. This can cause the sparse table in the RSet to expand. RSet scanning and the "occupied" routine will then operate on different instances of the sparse table causing the assert to trip. This may also cause some cards added post expansion to be missed during RSet scanning. When ParallelGCThreads is non-zero such references are recorded on the "references to be scanned" queue and the card containing the reference is recorded in a dirty card queue for use in the event of an evacuation failure. Employ the parallel code in the serial case to avoid expanding the RSets of regions in the collection set.
Reviewed-by: iveresov, ysr, tonyp

ysr@777 1 /*
johnc@2060 2 * Copyright (c) 2001, 2010, 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
ysr@777 25 inline size_t G1RemSet::n_workers() {
ysr@777 26 if (_g1->workers() != NULL) {
ysr@777 27 return _g1->workers()->total_workers();
ysr@777 28 } else {
ysr@777 29 return 1;
ysr@777 30 }
ysr@777 31 }
ysr@777 32
ysr@1280 33 template <class T> inline void HRInto_G1RemSet::write_ref_nv(HeapRegion* from, T* p) {
ysr@1280 34 par_write_ref_nv(from, p, 0);
ysr@777 35 }
ysr@777 36
ysr@777 37 inline bool HRInto_G1RemSet::self_forwarded(oop obj) {
ysr@777 38 bool result = (obj->is_forwarded() && (obj->forwardee()== obj));
ysr@777 39 return result;
ysr@777 40 }
ysr@777 41
ysr@1280 42 template <class T> inline void HRInto_G1RemSet::par_write_ref_nv(HeapRegion* from, T* p, int tid) {
ysr@1280 43 oop obj = oopDesc::load_decode_heap_oop(p);
ysr@777 44 #ifdef ASSERT
ysr@777 45 // can't do because of races
ysr@777 46 // assert(obj == NULL || obj->is_oop(), "expected an oop");
ysr@777 47
ysr@777 48 // Do the safe subset of is_oop
ysr@777 49 if (obj != NULL) {
ysr@777 50 #ifdef CHECK_UNHANDLED_OOPS
ysr@777 51 oopDesc* o = obj.obj();
ysr@777 52 #else
ysr@777 53 oopDesc* o = obj;
ysr@777 54 #endif // CHECK_UNHANDLED_OOPS
ysr@777 55 assert((intptr_t)o % MinObjAlignmentInBytes == 0, "not oop aligned");
ysr@777 56 assert(Universe::heap()->is_in_reserved(obj), "must be in heap");
ysr@777 57 }
ysr@777 58 #endif // ASSERT
johnc@2060 59
johnc@2060 60 assert(from == NULL || from->is_in_reserved(p), "p is not in from");
johnc@2060 61
ysr@777 62 HeapRegion* to = _g1->heap_region_containing(obj);
ysr@777 63 // The test below could be optimized by applying a bit op to to and from.
ysr@777 64 if (to != NULL && from != NULL && from != to) {
johnc@2063 65 // The _traversal_in_progress flag is true during the collection pause,
johnc@2063 66 // false during the evacuation failure handling. This should avoid a
johnc@2060 67 // potential loop if we were to add the card containing 'p' to the DCQS
johnc@2060 68 // that's used to regenerate the remembered sets for the collection set,
johnc@2060 69 // in the event of an evacuation failure, here. The UpdateRSImmediate
johnc@2060 70 // closure will eventally call this routine.
johnc@2063 71 if (_traversal_in_progress &&
iveresov@1051 72 to->in_collection_set() && !self_forwarded(obj)) {
johnc@2060 73
johnc@2060 74 assert(_cset_rs_update_cl[tid] != NULL, "should have been set already");
johnc@2060 75 _cset_rs_update_cl[tid]->do_oop(p);
johnc@2060 76
johnc@2060 77 // Deferred updates to the CSet are either discarded (in the normal case),
iveresov@1051 78 // or processed (if an evacuation failure occurs) at the end
iveresov@1051 79 // of the collection.
iveresov@1051 80 // See HRInto_G1RemSet::cleanup_after_oops_into_collection_set_do().
apetrusenko@1112 81 } else {
ysr@777 82 #if G1_REM_SET_LOGGING
ysr@777 83 gclog_or_tty->print_cr("Adding " PTR_FORMAT " (" PTR_FORMAT ") to RS"
ysr@777 84 " for region [" PTR_FORMAT ", " PTR_FORMAT ")",
ysr@777 85 p, obj,
ysr@777 86 to->bottom(), to->end());
ysr@777 87 #endif
ysr@777 88 assert(to->rem_set() != NULL, "Need per-region 'into' remsets.");
apetrusenko@1112 89 to->rem_set()->add_reference(p, tid);
ysr@777 90 }
ysr@777 91 }
ysr@777 92 }
apetrusenko@1061 93
ysr@1280 94 template <class T> inline void UpdateRSOopClosure::do_oop_work(T* p) {
apetrusenko@1061 95 assert(_from != NULL, "from region must be non-NULL");
apetrusenko@1061 96 _rs->par_write_ref(_from, p, _worker_i);
apetrusenko@1061 97 }
johnc@2060 98
johnc@2060 99 template <class T> inline void UpdateRSetImmediate::do_oop_work(T* p) {
johnc@2060 100 assert(_from->is_in_reserved(p), "paranoia");
johnc@2060 101 T heap_oop = oopDesc::load_heap_oop(p);
johnc@2060 102 if (!oopDesc::is_null(heap_oop) && !_from->is_survivor()) {
johnc@2060 103 _g1_rem_set->par_write_ref(_from, p, 0);
johnc@2060 104 }
johnc@2060 105 }
johnc@2060 106

mercurial