src/share/vm/gc_implementation/g1/heapRegionSeq.cpp

Sat, 06 Oct 2012 01:17:44 -0700

author
johnc
date
Sat, 06 Oct 2012 01:17:44 -0700
changeset 4173
8a5ea0a9ccc4
parent 3900
d2a62e0f25eb
child 5074
b0d20fa374b4
permissions
-rw-r--r--

7127708: G1: change task num types from int to uint in concurrent mark
Summary: Change the type of various task num fields, parameters etc to unsigned and rename them to be more consistent with the other collectors. Code changes were also reviewed by Vitaly Davidovich.
Reviewed-by: johnc
Contributed-by: Kaushik Srenevasan <kaushik@twitter.com>

ysr@777 1 /*
tonyp@3713 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 #include "precompiled.hpp"
tonyp@2963 26 #include "gc_implementation/g1/heapRegion.hpp"
tonyp@2963 27 #include "gc_implementation/g1/heapRegionSeq.inline.hpp"
tonyp@2963 28 #include "gc_implementation/g1/heapRegionSets.hpp"
stefank@2314 29 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
stefank@2314 30 #include "memory/allocation.hpp"
ysr@777 31
tonyp@2963 32 // Private
ysr@777 33
tonyp@3713 34 uint HeapRegionSeq::find_contiguous_from(uint from, uint num) {
tonyp@3713 35 uint len = length();
tonyp@2963 36 assert(num > 1, "use this only for sequences of length 2 or greater");
tonyp@2963 37 assert(from <= len,
tonyp@3713 38 err_msg("from: %u should be valid and <= than %u", from, len));
ysr@777 39
tonyp@3713 40 uint curr = from;
tonyp@3713 41 uint first = G1_NULL_HRS_INDEX;
tonyp@3713 42 uint num_so_far = 0;
tonyp@2963 43 while (curr < len && num_so_far < num) {
tonyp@2963 44 if (at(curr)->is_empty()) {
tonyp@2963 45 if (first == G1_NULL_HRS_INDEX) {
tonyp@2472 46 first = curr;
tonyp@2472 47 num_so_far = 1;
tonyp@2472 48 } else {
tonyp@2472 49 num_so_far += 1;
tonyp@2472 50 }
tonyp@2472 51 } else {
tonyp@2963 52 first = G1_NULL_HRS_INDEX;
tonyp@2472 53 num_so_far = 0;
tonyp@2472 54 }
tonyp@2472 55 curr += 1;
tonyp@2472 56 }
tonyp@2472 57 assert(num_so_far <= num, "post-condition");
tonyp@2472 58 if (num_so_far == num) {
tonyp@2643 59 // we found enough space for the humongous object
tonyp@2963 60 assert(from <= first && first < len, "post-condition");
tonyp@2963 61 assert(first < curr && (curr - first) == num, "post-condition");
tonyp@3713 62 for (uint i = first; i < first + num; ++i) {
tonyp@2963 63 assert(at(i)->is_empty(), "post-condition");
tonyp@2472 64 }
tonyp@2472 65 return first;
tonyp@2472 66 } else {
tonyp@2472 67 // we failed to find enough space for the humongous object
tonyp@2963 68 return G1_NULL_HRS_INDEX;
tonyp@2472 69 }
tonyp@2472 70 }
tonyp@2472 71
tonyp@2963 72 // Public
tonyp@2472 73
tonyp@2963 74 void HeapRegionSeq::initialize(HeapWord* bottom, HeapWord* end,
tonyp@3713 75 uint max_length) {
tonyp@3713 76 assert((uintptr_t) bottom % HeapRegion::GrainBytes == 0,
tonyp@2963 77 "bottom should be heap region aligned");
tonyp@3713 78 assert((uintptr_t) end % HeapRegion::GrainBytes == 0,
tonyp@2963 79 "end should be heap region aligned");
tonyp@2963 80
tonyp@2963 81 _length = 0;
tonyp@2963 82 _heap_bottom = bottom;
tonyp@2963 83 _heap_end = end;
tonyp@2963 84 _region_shift = HeapRegion::LogOfHRGrainBytes;
tonyp@2963 85 _next_search_index = 0;
tonyp@2963 86 _allocated_length = 0;
tonyp@2963 87 _max_length = max_length;
tonyp@2963 88
zgu@3900 89 _regions = NEW_C_HEAP_ARRAY(HeapRegion*, max_length, mtGC);
tonyp@3713 90 memset(_regions, 0, (size_t) max_length * sizeof(HeapRegion*));
tonyp@3713 91 _regions_biased = _regions - ((uintx) bottom >> _region_shift);
tonyp@2963 92
tonyp@2963 93 assert(&_regions[0] == &_regions_biased[addr_to_index_biased(bottom)],
tonyp@2963 94 "bottom should be included in the region with index 0");
tonyp@2963 95 }
tonyp@2963 96
tonyp@2963 97 MemRegion HeapRegionSeq::expand_by(HeapWord* old_end,
tonyp@2963 98 HeapWord* new_end,
tonyp@2963 99 FreeRegionList* list) {
tonyp@2963 100 assert(old_end < new_end, "don't call it otherwise");
tonyp@2963 101 G1CollectedHeap* g1h = G1CollectedHeap::heap();
tonyp@2963 102
tonyp@2963 103 HeapWord* next_bottom = old_end;
tonyp@2963 104 assert(_heap_bottom <= next_bottom, "invariant");
tonyp@2963 105 while (next_bottom < new_end) {
tonyp@2963 106 assert(next_bottom < _heap_end, "invariant");
tonyp@3713 107 uint index = length();
tonyp@2963 108
tonyp@2963 109 assert(index < _max_length, "otherwise we cannot expand further");
tonyp@2963 110 if (index == 0) {
tonyp@2963 111 // We have not allocated any regions so far
tonyp@2963 112 assert(next_bottom == _heap_bottom, "invariant");
tonyp@2963 113 } else {
tonyp@2963 114 // next_bottom should match the end of the last/previous region
tonyp@2963 115 assert(next_bottom == at(index - 1)->end(), "invariant");
tonyp@2963 116 }
tonyp@2963 117
tonyp@2963 118 if (index == _allocated_length) {
tonyp@2963 119 // We have to allocate a new HeapRegion.
tonyp@2963 120 HeapRegion* new_hr = g1h->new_heap_region(index, next_bottom);
tonyp@2963 121 if (new_hr == NULL) {
tonyp@2963 122 // allocation failed, we bail out and return what we have done so far
tonyp@2963 123 return MemRegion(old_end, next_bottom);
tonyp@2963 124 }
tonyp@2963 125 assert(_regions[index] == NULL, "invariant");
tonyp@2963 126 _regions[index] = new_hr;
tonyp@2963 127 increment_length(&_allocated_length);
tonyp@2963 128 }
tonyp@2963 129 // Have to increment the length first, otherwise we will get an
tonyp@2963 130 // assert failure at(index) below.
tonyp@2963 131 increment_length(&_length);
tonyp@2963 132 HeapRegion* hr = at(index);
tonyp@2963 133 list->add_as_tail(hr);
tonyp@2963 134
tonyp@2963 135 next_bottom = hr->end();
tonyp@2472 136 }
tonyp@2963 137 assert(next_bottom == new_end, "post-condition");
tonyp@2963 138 return MemRegion(old_end, next_bottom);
tonyp@2963 139 }
tonyp@2963 140
tonyp@3713 141 uint HeapRegionSeq::free_suffix() {
tonyp@3713 142 uint res = 0;
tonyp@3713 143 uint index = length();
tonyp@2963 144 while (index > 0) {
tonyp@2963 145 index -= 1;
tonyp@2963 146 if (!at(index)->is_empty()) {
tonyp@2963 147 break;
tonyp@2963 148 }
tonyp@2963 149 res += 1;
tonyp@2472 150 }
ysr@777 151 return res;
ysr@777 152 }
ysr@777 153
tonyp@3713 154 uint HeapRegionSeq::find_contiguous(uint num) {
tonyp@2963 155 assert(num > 1, "use this only for sequences of length 2 or greater");
tonyp@2963 156 assert(_next_search_index <= length(),
tonyp@3713 157 err_msg("_next_search_index: %u should be valid and <= than %u",
tonyp@2963 158 _next_search_index, length()));
tonyp@2963 159
tonyp@3713 160 uint start = _next_search_index;
tonyp@3713 161 uint res = find_contiguous_from(start, num);
tonyp@2963 162 if (res == G1_NULL_HRS_INDEX && start > 0) {
tonyp@2963 163 // Try starting from the beginning. If _next_search_index was 0,
tonyp@2963 164 // no point in doing this again.
tonyp@2963 165 res = find_contiguous_from(0, num);
tonyp@2963 166 }
tonyp@2963 167 if (res != G1_NULL_HRS_INDEX) {
tonyp@3713 168 assert(res < length(), err_msg("res: %u should be valid", res));
tonyp@2963 169 _next_search_index = res + num;
tonyp@2963 170 assert(_next_search_index <= length(),
tonyp@3713 171 err_msg("_next_search_index: %u should be valid and <= than %u",
tonyp@2963 172 _next_search_index, length()));
tonyp@2963 173 }
tonyp@2963 174 return res;
ysr@777 175 }
ysr@777 176
tonyp@2963 177 void HeapRegionSeq::iterate(HeapRegionClosure* blk) const {
tonyp@2963 178 iterate_from((HeapRegion*) NULL, blk);
tonyp@2963 179 }
ysr@777 180
tonyp@2963 181 void HeapRegionSeq::iterate_from(HeapRegion* hr, HeapRegionClosure* blk) const {
tonyp@3713 182 uint hr_index = 0;
tonyp@2963 183 if (hr != NULL) {
tonyp@3713 184 hr_index = hr->hrs_index();
tonyp@2963 185 }
ysr@777 186
tonyp@3713 187 uint len = length();
tonyp@3713 188 for (uint i = hr_index; i < len; i += 1) {
tonyp@2963 189 bool res = blk->doHeapRegion(at(i));
ysr@777 190 if (res) {
ysr@777 191 blk->incomplete();
ysr@777 192 return;
ysr@777 193 }
ysr@777 194 }
tonyp@3713 195 for (uint i = 0; i < hr_index; i += 1) {
tonyp@2963 196 bool res = blk->doHeapRegion(at(i));
ysr@777 197 if (res) {
ysr@777 198 blk->incomplete();
ysr@777 199 return;
ysr@777 200 }
ysr@777 201 }
ysr@777 202 }
ysr@777 203
ysr@777 204 MemRegion HeapRegionSeq::shrink_by(size_t shrink_bytes,
tonyp@3713 205 uint* num_regions_deleted) {
tonyp@2472 206 // Reset this in case it's currently pointing into the regions that
tonyp@2472 207 // we just removed.
tonyp@2963 208 _next_search_index = 0;
tonyp@2472 209
ysr@777 210 assert(shrink_bytes % os::vm_page_size() == 0, "unaligned");
ysr@777 211 assert(shrink_bytes % HeapRegion::GrainBytes == 0, "unaligned");
tonyp@2963 212 assert(length() > 0, "the region sequence should not be empty");
tonyp@2963 213 assert(length() <= _allocated_length, "invariant");
tonyp@2963 214 assert(_allocated_length > 0, "we should have at least one region committed");
ysr@777 215
tonyp@2963 216 // around the loop, i will be the next region to be removed
tonyp@3713 217 uint i = length() - 1;
tonyp@2963 218 assert(i > 0, "we should never remove all regions");
tonyp@2963 219 // [last_start, end) is the MemRegion that covers the regions we will remove.
tonyp@2963 220 HeapWord* end = at(i)->end();
ysr@777 221 HeapWord* last_start = end;
tonyp@2963 222 *num_regions_deleted = 0;
tonyp@2963 223 while (shrink_bytes > 0) {
tonyp@2963 224 HeapRegion* cur = at(i);
tonyp@2963 225 // We should leave the humongous regions where they are.
tonyp@2963 226 if (cur->isHumongous()) break;
tonyp@2963 227 // We should stop shrinking if we come across a non-empty region.
ysr@777 228 if (!cur->is_empty()) break;
tonyp@2963 229
tonyp@2963 230 i -= 1;
tonyp@2963 231 *num_regions_deleted += 1;
ysr@777 232 shrink_bytes -= cur->capacity();
ysr@777 233 last_start = cur->bottom();
tonyp@2963 234 decrement_length(&_length);
tonyp@2963 235 // We will reclaim the HeapRegion. _allocated_length should be
tonyp@2963 236 // covering this index. So, even though we removed the region from
tonyp@2963 237 // the active set by decreasing _length, we still have it
tonyp@2963 238 // available in the future if we need to re-use it.
tonyp@2963 239 assert(i > 0, "we should never remove all regions");
tonyp@2963 240 assert(length() > 0, "we should never remove all regions");
ysr@777 241 }
ysr@777 242 return MemRegion(last_start, end);
ysr@777 243 }
ysr@777 244
tonyp@2963 245 #ifndef PRODUCT
tonyp@2963 246 void HeapRegionSeq::verify_optional() {
tonyp@2963 247 guarantee(_length <= _allocated_length,
tonyp@3713 248 err_msg("invariant: _length: %u _allocated_length: %u",
tonyp@2963 249 _length, _allocated_length));
tonyp@2963 250 guarantee(_allocated_length <= _max_length,
tonyp@3713 251 err_msg("invariant: _allocated_length: %u _max_length: %u",
tonyp@2963 252 _allocated_length, _max_length));
tonyp@2963 253 guarantee(_next_search_index <= _length,
tonyp@3713 254 err_msg("invariant: _next_search_index: %u _length: %u",
tonyp@2963 255 _next_search_index, _length));
tonyp@2963 256
tonyp@2963 257 HeapWord* prev_end = _heap_bottom;
tonyp@3713 258 for (uint i = 0; i < _allocated_length; i += 1) {
tonyp@2963 259 HeapRegion* hr = _regions[i];
tonyp@3713 260 guarantee(hr != NULL, err_msg("invariant: i: %u", i));
tonyp@2963 261 guarantee(hr->bottom() == prev_end,
tonyp@3713 262 err_msg("invariant i: %u "HR_FORMAT" prev_end: "PTR_FORMAT,
tonyp@2963 263 i, HR_FORMAT_PARAMS(hr), prev_end));
tonyp@2963 264 guarantee(hr->hrs_index() == i,
tonyp@3713 265 err_msg("invariant: i: %u hrs_index(): %u", i, hr->hrs_index()));
tonyp@2963 266 if (i < _length) {
tonyp@2963 267 // Asserts will fire if i is >= _length
tonyp@2963 268 HeapWord* addr = hr->bottom();
tonyp@2963 269 guarantee(addr_to_region(addr) == hr, "sanity");
tonyp@2963 270 guarantee(addr_to_region_unsafe(addr) == hr, "sanity");
tonyp@2963 271 } else {
tonyp@2963 272 guarantee(hr->is_empty(), "sanity");
tonyp@2963 273 guarantee(!hr->isHumongous(), "sanity");
tonyp@2963 274 // using assert instead of guarantee here since containing_set()
tonyp@2963 275 // is only available in non-product builds.
tonyp@2963 276 assert(hr->containing_set() == NULL, "sanity");
tonyp@2963 277 }
tonyp@2963 278 if (hr->startsHumongous()) {
tonyp@2963 279 prev_end = hr->orig_end();
tonyp@2963 280 } else {
tonyp@2963 281 prev_end = hr->end();
tonyp@2963 282 }
ysr@777 283 }
tonyp@3713 284 for (uint i = _allocated_length; i < _max_length; i += 1) {
tonyp@3713 285 guarantee(_regions[i] == NULL, err_msg("invariant i: %u", i));
tonyp@2963 286 }
ysr@777 287 }
tonyp@2963 288 #endif // PRODUCT

mercurial