Mercurial > hg > truffle
annotate src/share/vm/gc_implementation/g1/heapRegionSeq.cpp @ 4710:41406797186b
7113012: G1: rename not-fully-young GCs as "mixed"
Summary: Renamed partially-young GCs as mixed and fully-young GCs as young. Change all external output that includes those terms (GC log and GC ergo log) as well as any comments, fields, methods, etc. The changeset also includes very minor code tidying up (added some curly brackets).
Reviewed-by: johnc, brutisso
author | tonyp |
---|---|
date | Fri, 16 Dec 2011 02:14:27 -0500 |
parents | c3f1170908be |
children | 720b6a76dd9d |
rev | line source |
---|---|
342 | 1 /* |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
2 * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. |
342 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
960
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
960
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
960
diff
changeset
|
21 * questions. |
342 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
3766 | 26 #include "gc_implementation/g1/heapRegion.hpp" |
27 #include "gc_implementation/g1/heapRegionSeq.inline.hpp" | |
28 #include "gc_implementation/g1/heapRegionSets.hpp" | |
1972 | 29 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" |
30 #include "memory/allocation.hpp" | |
342 | 31 |
3766 | 32 // Private |
342 | 33 |
3766 | 34 size_t HeapRegionSeq::find_contiguous_from(size_t from, size_t num) { |
35 size_t len = length(); | |
36 assert(num > 1, "use this only for sequences of length 2 or greater"); | |
37 assert(from <= len, | |
38 err_msg("from: "SIZE_FORMAT" should be valid and <= than "SIZE_FORMAT, | |
39 from, len)); | |
342 | 40 |
3766 | 41 size_t curr = from; |
42 size_t first = G1_NULL_HRS_INDEX; | |
2152 | 43 size_t num_so_far = 0; |
3766 | 44 while (curr < len && num_so_far < num) { |
45 if (at(curr)->is_empty()) { | |
46 if (first == G1_NULL_HRS_INDEX) { | |
2152 | 47 first = curr; |
48 num_so_far = 1; | |
49 } else { | |
50 num_so_far += 1; | |
51 } | |
52 } else { | |
3766 | 53 first = G1_NULL_HRS_INDEX; |
2152 | 54 num_so_far = 0; |
55 } | |
56 curr += 1; | |
57 } | |
58 assert(num_so_far <= num, "post-condition"); | |
59 if (num_so_far == num) { | |
2361 | 60 // we found enough space for the humongous object |
3766 | 61 assert(from <= first && first < len, "post-condition"); |
62 assert(first < curr && (curr - first) == num, "post-condition"); | |
63 for (size_t i = first; i < first + num; ++i) { | |
64 assert(at(i)->is_empty(), "post-condition"); | |
2152 | 65 } |
66 return first; | |
67 } else { | |
68 // we failed to find enough space for the humongous object | |
3766 | 69 return G1_NULL_HRS_INDEX; |
2152 | 70 } |
71 } | |
72 | |
3766 | 73 // Public |
74 | |
75 void HeapRegionSeq::initialize(HeapWord* bottom, HeapWord* end, | |
76 size_t max_length) { | |
77 assert((size_t) bottom % HeapRegion::GrainBytes == 0, | |
78 "bottom should be heap region aligned"); | |
79 assert((size_t) end % HeapRegion::GrainBytes == 0, | |
80 "end should be heap region aligned"); | |
81 | |
82 _length = 0; | |
83 _heap_bottom = bottom; | |
84 _heap_end = end; | |
85 _region_shift = HeapRegion::LogOfHRGrainBytes; | |
86 _next_search_index = 0; | |
87 _allocated_length = 0; | |
88 _max_length = max_length; | |
89 | |
90 _regions = NEW_C_HEAP_ARRAY(HeapRegion*, max_length); | |
91 memset(_regions, 0, max_length * sizeof(HeapRegion*)); | |
92 _regions_biased = _regions - ((size_t) bottom >> _region_shift); | |
93 | |
94 assert(&_regions[0] == &_regions_biased[addr_to_index_biased(bottom)], | |
95 "bottom should be included in the region with index 0"); | |
96 } | |
97 | |
98 MemRegion HeapRegionSeq::expand_by(HeapWord* old_end, | |
99 HeapWord* new_end, | |
100 FreeRegionList* list) { | |
101 assert(old_end < new_end, "don't call it otherwise"); | |
102 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
103 | |
104 HeapWord* next_bottom = old_end; | |
105 assert(_heap_bottom <= next_bottom, "invariant"); | |
106 while (next_bottom < new_end) { | |
107 assert(next_bottom < _heap_end, "invariant"); | |
108 size_t index = length(); | |
2152 | 109 |
3766 | 110 assert(index < _max_length, "otherwise we cannot expand further"); |
111 if (index == 0) { | |
112 // We have not allocated any regions so far | |
113 assert(next_bottom == _heap_bottom, "invariant"); | |
114 } else { | |
115 // next_bottom should match the end of the last/previous region | |
116 assert(next_bottom == at(index - 1)->end(), "invariant"); | |
117 } | |
118 | |
119 if (index == _allocated_length) { | |
120 // We have to allocate a new HeapRegion. | |
121 HeapRegion* new_hr = g1h->new_heap_region(index, next_bottom); | |
122 if (new_hr == NULL) { | |
123 // allocation failed, we bail out and return what we have done so far | |
124 return MemRegion(old_end, next_bottom); | |
125 } | |
126 assert(_regions[index] == NULL, "invariant"); | |
127 _regions[index] = new_hr; | |
128 increment_length(&_allocated_length); | |
129 } | |
130 // Have to increment the length first, otherwise we will get an | |
131 // assert failure at(index) below. | |
132 increment_length(&_length); | |
133 HeapRegion* hr = at(index); | |
134 list->add_as_tail(hr); | |
135 | |
136 next_bottom = hr->end(); | |
2152 | 137 } |
3766 | 138 assert(next_bottom == new_end, "post-condition"); |
139 return MemRegion(old_end, next_bottom); | |
140 } | |
141 | |
142 size_t HeapRegionSeq::free_suffix() { | |
143 size_t res = 0; | |
144 size_t index = length(); | |
145 while (index > 0) { | |
146 index -= 1; | |
147 if (!at(index)->is_empty()) { | |
148 break; | |
149 } | |
150 res += 1; | |
2152 | 151 } |
342 | 152 return res; |
153 } | |
154 | |
3766 | 155 size_t HeapRegionSeq::find_contiguous(size_t num) { |
156 assert(num > 1, "use this only for sequences of length 2 or greater"); | |
157 assert(_next_search_index <= length(), | |
158 err_msg("_next_search_indeex: "SIZE_FORMAT" " | |
159 "should be valid and <= than "SIZE_FORMAT, | |
160 _next_search_index, length())); | |
161 | |
162 size_t start = _next_search_index; | |
163 size_t res = find_contiguous_from(start, num); | |
164 if (res == G1_NULL_HRS_INDEX && start > 0) { | |
165 // Try starting from the beginning. If _next_search_index was 0, | |
166 // no point in doing this again. | |
167 res = find_contiguous_from(0, num); | |
168 } | |
169 if (res != G1_NULL_HRS_INDEX) { | |
170 assert(res < length(), | |
171 err_msg("res: "SIZE_FORMAT" should be valid", res)); | |
172 _next_search_index = res + num; | |
173 assert(_next_search_index <= length(), | |
174 err_msg("_next_search_indeex: "SIZE_FORMAT" " | |
175 "should be valid and <= than "SIZE_FORMAT, | |
176 _next_search_index, length())); | |
177 } | |
178 return res; | |
342 | 179 } |
180 | |
3766 | 181 void HeapRegionSeq::iterate(HeapRegionClosure* blk) const { |
182 iterate_from((HeapRegion*) NULL, blk); | |
183 } | |
342 | 184 |
3766 | 185 void HeapRegionSeq::iterate_from(HeapRegion* hr, HeapRegionClosure* blk) const { |
186 size_t hr_index = 0; | |
187 if (hr != NULL) { | |
188 hr_index = (size_t) hr->hrs_index(); | |
342 | 189 } |
3766 | 190 |
191 size_t len = length(); | |
192 for (size_t i = hr_index; i < len; i += 1) { | |
193 bool res = blk->doHeapRegion(at(i)); | |
342 | 194 if (res) { |
195 blk->incomplete(); | |
196 return; | |
197 } | |
198 } | |
3766 | 199 for (size_t i = 0; i < hr_index; i += 1) { |
200 bool res = blk->doHeapRegion(at(i)); | |
342 | 201 if (res) { |
202 blk->incomplete(); | |
203 return; | |
204 } | |
205 } | |
206 } | |
207 | |
208 MemRegion HeapRegionSeq::shrink_by(size_t shrink_bytes, | |
3766 | 209 size_t* num_regions_deleted) { |
2152 | 210 // Reset this in case it's currently pointing into the regions that |
211 // we just removed. | |
3766 | 212 _next_search_index = 0; |
2152 | 213 |
342 | 214 assert(shrink_bytes % os::vm_page_size() == 0, "unaligned"); |
215 assert(shrink_bytes % HeapRegion::GrainBytes == 0, "unaligned"); | |
3766 | 216 assert(length() > 0, "the region sequence should not be empty"); |
217 assert(length() <= _allocated_length, "invariant"); | |
218 assert(_allocated_length > 0, "we should have at least one region committed"); | |
342 | 219 |
3766 | 220 // around the loop, i will be the next region to be removed |
221 size_t i = length() - 1; | |
222 assert(i > 0, "we should never remove all regions"); | |
223 // [last_start, end) is the MemRegion that covers the regions we will remove. | |
224 HeapWord* end = at(i)->end(); | |
342 | 225 HeapWord* last_start = end; |
3766 | 226 *num_regions_deleted = 0; |
227 while (shrink_bytes > 0) { | |
228 HeapRegion* cur = at(i); | |
229 // We should leave the humongous regions where they are. | |
230 if (cur->isHumongous()) break; | |
231 // We should stop shrinking if we come across a non-empty region. | |
342 | 232 if (!cur->is_empty()) break; |
3766 | 233 |
234 i -= 1; | |
235 *num_regions_deleted += 1; | |
342 | 236 shrink_bytes -= cur->capacity(); |
237 last_start = cur->bottom(); | |
3766 | 238 decrement_length(&_length); |
239 // We will reclaim the HeapRegion. _allocated_length should be | |
240 // covering this index. So, even though we removed the region from | |
241 // the active set by decreasing _length, we still have it | |
242 // available in the future if we need to re-use it. | |
243 assert(i > 0, "we should never remove all regions"); | |
244 assert(length() > 0, "we should never remove all regions"); | |
342 | 245 } |
246 return MemRegion(last_start, end); | |
247 } | |
248 | |
3766 | 249 #ifndef PRODUCT |
250 void HeapRegionSeq::verify_optional() { | |
251 guarantee(_length <= _allocated_length, | |
252 err_msg("invariant: _length: "SIZE_FORMAT" " | |
253 "_allocated_length: "SIZE_FORMAT, | |
254 _length, _allocated_length)); | |
255 guarantee(_allocated_length <= _max_length, | |
256 err_msg("invariant: _allocated_length: "SIZE_FORMAT" " | |
257 "_max_length: "SIZE_FORMAT, | |
258 _allocated_length, _max_length)); | |
259 guarantee(_next_search_index <= _length, | |
260 err_msg("invariant: _next_search_index: "SIZE_FORMAT" " | |
261 "_length: "SIZE_FORMAT, | |
262 _next_search_index, _length)); | |
263 | |
264 HeapWord* prev_end = _heap_bottom; | |
265 for (size_t i = 0; i < _allocated_length; i += 1) { | |
266 HeapRegion* hr = _regions[i]; | |
267 guarantee(hr != NULL, err_msg("invariant: i: "SIZE_FORMAT, i)); | |
268 guarantee(hr->bottom() == prev_end, | |
269 err_msg("invariant i: "SIZE_FORMAT" "HR_FORMAT" " | |
270 "prev_end: "PTR_FORMAT, | |
271 i, HR_FORMAT_PARAMS(hr), prev_end)); | |
272 guarantee(hr->hrs_index() == i, | |
273 err_msg("invariant: i: "SIZE_FORMAT" hrs_index(): "SIZE_FORMAT, | |
274 i, hr->hrs_index())); | |
275 if (i < _length) { | |
276 // Asserts will fire if i is >= _length | |
277 HeapWord* addr = hr->bottom(); | |
278 guarantee(addr_to_region(addr) == hr, "sanity"); | |
279 guarantee(addr_to_region_unsafe(addr) == hr, "sanity"); | |
280 } else { | |
281 guarantee(hr->is_empty(), "sanity"); | |
282 guarantee(!hr->isHumongous(), "sanity"); | |
283 // using assert instead of guarantee here since containing_set() | |
284 // is only available in non-product builds. | |
285 assert(hr->containing_set() == NULL, "sanity"); | |
286 } | |
287 if (hr->startsHumongous()) { | |
288 prev_end = hr->orig_end(); | |
289 } else { | |
290 prev_end = hr->end(); | |
291 } | |
342 | 292 } |
3766 | 293 for (size_t i = _allocated_length; i < _max_length; i += 1) { |
294 guarantee(_regions[i] == NULL, err_msg("invariant i: "SIZE_FORMAT, i)); | |
295 } | |
342 | 296 } |
3766 | 297 #endif // PRODUCT |