src/share/vm/gc_implementation/g1/heapRegionSet.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 3058
3be7439273c5
child 3713
720b6a76dd9d
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

tonyp@2472 1 /*
katleman@3058 2 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
tonyp@2472 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
tonyp@2472 4 *
tonyp@2472 5 * This code is free software; you can redistribute it and/or modify it
tonyp@2472 6 * under the terms of the GNU General Public License version 2 only, as
tonyp@2472 7 * published by the Free Software Foundation.
tonyp@2472 8 *
tonyp@2472 9 * This code is distributed in the hope that it will be useful, but WITHOUT
tonyp@2472 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
tonyp@2472 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
tonyp@2472 12 * version 2 for more details (a copy is included in the LICENSE file that
tonyp@2472 13 * accompanied this code).
tonyp@2472 14 *
tonyp@2472 15 * You should have received a copy of the GNU General Public License version
tonyp@2472 16 * 2 along with this work; if not, write to the Free Software Foundation,
tonyp@2472 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
tonyp@2472 18 *
tonyp@2472 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
tonyp@2472 20 * or visit www.oracle.com if you need additional information or have any
tonyp@2472 21 * questions.
tonyp@2472 22 *
tonyp@2472 23 */
tonyp@2472 24
tonyp@2472 25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSET_INLINE_HPP
tonyp@2472 26 #define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSET_INLINE_HPP
tonyp@2472 27
tonyp@2472 28 #include "gc_implementation/g1/heapRegionSet.hpp"
tonyp@2472 29
tonyp@2472 30 //////////////////// HeapRegionSetBase ////////////////////
tonyp@2472 31
tonyp@2472 32 inline void HeapRegionSetBase::update_for_addition(HeapRegion* hr) {
tonyp@2472 33 // Assumes the caller has already verified the region.
tonyp@2472 34
tonyp@2472 35 _length += 1;
tonyp@2472 36 if (!hr->isHumongous()) {
tonyp@2472 37 _region_num += 1;
tonyp@2472 38 } else {
tonyp@2472 39 _region_num += calculate_region_num(hr);
tonyp@2472 40 }
tonyp@2472 41 _total_used_bytes += hr->used();
tonyp@2472 42 }
tonyp@2472 43
tonyp@2472 44 inline void HeapRegionSetBase::add_internal(HeapRegion* hr) {
tonyp@2643 45 hrs_assert_region_ok(this, hr, NULL);
tonyp@2643 46 assert(hr->next() == NULL, hrs_ext_msg(this, "should not already be linked"));
tonyp@2472 47
tonyp@2472 48 update_for_addition(hr);
tonyp@2472 49 hr->set_containing_set(this);
tonyp@2472 50 }
tonyp@2472 51
tonyp@2472 52 inline void HeapRegionSetBase::update_for_removal(HeapRegion* hr) {
tonyp@2472 53 // Assumes the caller has already verified the region.
tonyp@2643 54 assert(_length > 0, hrs_ext_msg(this, "pre-condition"));
tonyp@2472 55 _length -= 1;
tonyp@2472 56
tonyp@2472 57 size_t region_num_diff;
tonyp@2472 58 if (!hr->isHumongous()) {
tonyp@2472 59 region_num_diff = 1;
tonyp@2472 60 } else {
tonyp@2472 61 region_num_diff = calculate_region_num(hr);
tonyp@2472 62 }
tonyp@2472 63 assert(region_num_diff <= _region_num,
tonyp@2643 64 hrs_err_msg("[%s] region's region num: "SIZE_FORMAT" "
tonyp@2472 65 "should be <= region num: "SIZE_FORMAT,
tonyp@2472 66 name(), region_num_diff, _region_num));
tonyp@2472 67 _region_num -= region_num_diff;
tonyp@2472 68
tonyp@2472 69 size_t used_bytes = hr->used();
tonyp@2472 70 assert(used_bytes <= _total_used_bytes,
tonyp@2643 71 hrs_err_msg("[%s] region's used bytes: "SIZE_FORMAT" "
tonyp@2472 72 "should be <= used bytes: "SIZE_FORMAT,
tonyp@2472 73 name(), used_bytes, _total_used_bytes));
tonyp@2472 74 _total_used_bytes -= used_bytes;
tonyp@2472 75 }
tonyp@2472 76
tonyp@2472 77 inline void HeapRegionSetBase::remove_internal(HeapRegion* hr) {
tonyp@2643 78 hrs_assert_region_ok(this, hr, this);
tonyp@2643 79 assert(hr->next() == NULL, hrs_ext_msg(this, "should already be unlinked"));
tonyp@2472 80
tonyp@2472 81 hr->set_containing_set(NULL);
tonyp@2472 82 update_for_removal(hr);
tonyp@2472 83 }
tonyp@2472 84
tonyp@2472 85 //////////////////// HeapRegionSet ////////////////////
tonyp@2472 86
tonyp@2472 87 inline void HeapRegionSet::add(HeapRegion* hr) {
tonyp@2643 88 hrs_assert_mt_safety_ok(this);
tonyp@2472 89 // add_internal() will verify the region.
tonyp@2472 90 add_internal(hr);
tonyp@2472 91 }
tonyp@2472 92
tonyp@2472 93 inline void HeapRegionSet::remove(HeapRegion* hr) {
tonyp@2643 94 hrs_assert_mt_safety_ok(this);
tonyp@2472 95 // remove_internal() will verify the region.
tonyp@2472 96 remove_internal(hr);
tonyp@2472 97 }
tonyp@2472 98
tonyp@2472 99 inline void HeapRegionSet::remove_with_proxy(HeapRegion* hr,
tonyp@2472 100 HeapRegionSet* proxy_set) {
tonyp@2472 101 // No need to fo the MT safety check here given that this method
tonyp@2472 102 // does not update the contents of the set but instead accumulates
tonyp@2472 103 // the changes in proxy_set which is assumed to be thread-local.
tonyp@2643 104 hrs_assert_sets_match(this, proxy_set);
tonyp@2643 105 hrs_assert_region_ok(this, hr, this);
tonyp@2472 106
tonyp@2472 107 hr->set_containing_set(NULL);
tonyp@2472 108 proxy_set->update_for_addition(hr);
tonyp@2472 109 }
tonyp@2472 110
tonyp@2472 111 //////////////////// HeapRegionLinkedList ////////////////////
tonyp@2472 112
tonyp@2714 113 inline void HeapRegionLinkedList::add_as_head(HeapRegion* hr) {
tonyp@2714 114 hrs_assert_mt_safety_ok(this);
tonyp@2714 115 assert((length() == 0 && _head == NULL && _tail == NULL) ||
tonyp@2714 116 (length() > 0 && _head != NULL && _tail != NULL),
tonyp@2714 117 hrs_ext_msg(this, "invariant"));
tonyp@2714 118 // add_internal() will verify the region.
tonyp@2714 119 add_internal(hr);
tonyp@2714 120
tonyp@2714 121 // Now link the region.
tonyp@2714 122 if (_head != NULL) {
tonyp@2714 123 hr->set_next(_head);
tonyp@2714 124 } else {
tonyp@2714 125 _tail = hr;
tonyp@2714 126 }
tonyp@2714 127 _head = hr;
tonyp@2714 128 }
tonyp@2714 129
tonyp@2472 130 inline void HeapRegionLinkedList::add_as_tail(HeapRegion* hr) {
tonyp@2643 131 hrs_assert_mt_safety_ok(this);
tonyp@2472 132 assert((length() == 0 && _head == NULL && _tail == NULL) ||
tonyp@2472 133 (length() > 0 && _head != NULL && _tail != NULL),
tonyp@2643 134 hrs_ext_msg(this, "invariant"));
tonyp@2472 135 // add_internal() will verify the region.
tonyp@2472 136 add_internal(hr);
tonyp@2472 137
tonyp@2472 138 // Now link the region.
tonyp@2472 139 if (_tail != NULL) {
tonyp@2472 140 _tail->set_next(hr);
tonyp@2472 141 } else {
tonyp@2472 142 _head = hr;
tonyp@2472 143 }
tonyp@2472 144 _tail = hr;
tonyp@2472 145 }
tonyp@2472 146
tonyp@2472 147 inline HeapRegion* HeapRegionLinkedList::remove_head() {
tonyp@2643 148 hrs_assert_mt_safety_ok(this);
tonyp@2643 149 assert(!is_empty(), hrs_ext_msg(this, "the list should not be empty"));
tonyp@2472 150 assert(length() > 0 && _head != NULL && _tail != NULL,
tonyp@2643 151 hrs_ext_msg(this, "invariant"));
tonyp@2472 152
tonyp@2472 153 // We need to unlink it first.
tonyp@2472 154 HeapRegion* hr = _head;
tonyp@2472 155 _head = hr->next();
tonyp@2472 156 if (_head == NULL) {
tonyp@2472 157 _tail = NULL;
tonyp@2472 158 }
tonyp@2472 159 hr->set_next(NULL);
tonyp@2472 160
tonyp@2472 161 // remove_internal() will verify the region.
tonyp@2472 162 remove_internal(hr);
tonyp@2472 163 return hr;
tonyp@2472 164 }
tonyp@2472 165
tonyp@2472 166 inline HeapRegion* HeapRegionLinkedList::remove_head_or_null() {
tonyp@2643 167 hrs_assert_mt_safety_ok(this);
tonyp@2472 168
tonyp@2472 169 if (!is_empty()) {
tonyp@2472 170 return remove_head();
tonyp@2472 171 } else {
tonyp@2472 172 return NULL;
tonyp@2472 173 }
tonyp@2472 174 }
tonyp@2472 175
tonyp@2472 176 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSET_INLINE_HPP

mercurial