Mercurial > hg > graal-jvmci-8
annotate src/share/vm/gc_implementation/g1/heapRegionSeq.cpp @ 20211:82693fb204a5
8038930: G1CodeRootSet::test fails with assert(_num_chunks_handed_out == 0) failed: No elements must have been handed out yet
Summary: The test incorrectly assumed that it had been started with no other previous compilation activity. Fix this by allowing multiple code root free chunk lists, and use one separate from the global one to perform the test.
Reviewed-by: brutisso
author | tschatzl |
---|---|
date | Wed, 16 Apr 2014 10:14:50 +0200 |
parents | 78bbf4d43a14 |
children | 52b4284cb496 eec72fa4b108 |
rev | line source |
---|---|
342 | 1 /* |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17736
diff
changeset
|
2 * Copyright (c) 2001, 2014, 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" | |
17736
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
17467
diff
changeset
|
28 #include "gc_implementation/g1/heapRegionSet.hpp" |
1972 | 29 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" |
30 #include "memory/allocation.hpp" | |
342 | 31 |
3766 | 32 // Private |
342 | 33 |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
34 uint HeapRegionSeq::find_contiguous_from(uint from, uint num) { |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
35 uint len = length(); |
3766 | 36 assert(num > 1, "use this only for sequences of length 2 or greater"); |
37 assert(from <= len, | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
38 err_msg("from: %u should be valid and <= than %u", from, len)); |
342 | 39 |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
40 uint curr = from; |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
41 uint first = G1_NULL_HRS_INDEX; |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
42 uint num_so_far = 0; |
3766 | 43 while (curr < len && num_so_far < num) { |
44 if (at(curr)->is_empty()) { | |
45 if (first == G1_NULL_HRS_INDEX) { | |
2152 | 46 first = curr; |
47 num_so_far = 1; | |
48 } else { | |
49 num_so_far += 1; | |
50 } | |
51 } else { | |
3766 | 52 first = G1_NULL_HRS_INDEX; |
2152 | 53 num_so_far = 0; |
54 } | |
55 curr += 1; | |
56 } | |
57 assert(num_so_far <= num, "post-condition"); | |
58 if (num_so_far == num) { | |
2361 | 59 // we found enough space for the humongous object |
3766 | 60 assert(from <= first && first < len, "post-condition"); |
61 assert(first < curr && (curr - first) == num, "post-condition"); | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
62 for (uint i = first; i < first + num; ++i) { |
3766 | 63 assert(at(i)->is_empty(), "post-condition"); |
2152 | 64 } |
65 return first; | |
66 } else { | |
67 // we failed to find enough space for the humongous object | |
3766 | 68 return G1_NULL_HRS_INDEX; |
2152 | 69 } |
70 } | |
71 | |
3766 | 72 // Public |
73 | |
12305
a19bea467577
7163191: G1: introduce a "heap spanning table" abstraction
tschatzl
parents:
10242
diff
changeset
|
74 void HeapRegionSeq::initialize(HeapWord* bottom, HeapWord* end) { |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
75 assert((uintptr_t) bottom % HeapRegion::GrainBytes == 0, |
3766 | 76 "bottom should be heap region aligned"); |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
77 assert((uintptr_t) end % HeapRegion::GrainBytes == 0, |
3766 | 78 "end should be heap region aligned"); |
79 | |
80 _next_search_index = 0; | |
81 _allocated_length = 0; | |
82 | |
12305
a19bea467577
7163191: G1: introduce a "heap spanning table" abstraction
tschatzl
parents:
10242
diff
changeset
|
83 _regions.initialize(bottom, end, HeapRegion::GrainBytes); |
3766 | 84 } |
85 | |
86 MemRegion HeapRegionSeq::expand_by(HeapWord* old_end, | |
87 HeapWord* new_end, | |
88 FreeRegionList* list) { | |
89 assert(old_end < new_end, "don't call it otherwise"); | |
90 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
91 | |
92 HeapWord* next_bottom = old_end; | |
12305
a19bea467577
7163191: G1: introduce a "heap spanning table" abstraction
tschatzl
parents:
10242
diff
changeset
|
93 assert(heap_bottom() <= next_bottom, "invariant"); |
3766 | 94 while (next_bottom < new_end) { |
12305
a19bea467577
7163191: G1: introduce a "heap spanning table" abstraction
tschatzl
parents:
10242
diff
changeset
|
95 assert(next_bottom < heap_end(), "invariant"); |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
96 uint index = length(); |
2152 | 97 |
12305
a19bea467577
7163191: G1: introduce a "heap spanning table" abstraction
tschatzl
parents:
10242
diff
changeset
|
98 assert(index < max_length(), "otherwise we cannot expand further"); |
3766 | 99 if (index == 0) { |
100 // We have not allocated any regions so far | |
12305
a19bea467577
7163191: G1: introduce a "heap spanning table" abstraction
tschatzl
parents:
10242
diff
changeset
|
101 assert(next_bottom == heap_bottom(), "invariant"); |
3766 | 102 } else { |
103 // next_bottom should match the end of the last/previous region | |
104 assert(next_bottom == at(index - 1)->end(), "invariant"); | |
105 } | |
106 | |
107 if (index == _allocated_length) { | |
108 // We have to allocate a new HeapRegion. | |
109 HeapRegion* new_hr = g1h->new_heap_region(index, next_bottom); | |
110 if (new_hr == NULL) { | |
111 // allocation failed, we bail out and return what we have done so far | |
112 return MemRegion(old_end, next_bottom); | |
113 } | |
12305
a19bea467577
7163191: G1: introduce a "heap spanning table" abstraction
tschatzl
parents:
10242
diff
changeset
|
114 assert(_regions.get_by_index(index) == NULL, "invariant"); |
a19bea467577
7163191: G1: introduce a "heap spanning table" abstraction
tschatzl
parents:
10242
diff
changeset
|
115 _regions.set_by_index(index, new_hr); |
10242
b0d20fa374b4
8013872: G1: HeapRegionSeq::shrink_by() has invalid assert
brutisso
parents:
6197
diff
changeset
|
116 increment_allocated_length(); |
3766 | 117 } |
118 // Have to increment the length first, otherwise we will get an | |
119 // assert failure at(index) below. | |
10242
b0d20fa374b4
8013872: G1: HeapRegionSeq::shrink_by() has invalid assert
brutisso
parents:
6197
diff
changeset
|
120 increment_length(); |
3766 | 121 HeapRegion* hr = at(index); |
122 list->add_as_tail(hr); | |
123 | |
124 next_bottom = hr->end(); | |
2152 | 125 } |
3766 | 126 assert(next_bottom == new_end, "post-condition"); |
127 return MemRegion(old_end, next_bottom); | |
128 } | |
129 | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
130 uint HeapRegionSeq::free_suffix() { |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
131 uint res = 0; |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
132 uint index = length(); |
3766 | 133 while (index > 0) { |
134 index -= 1; | |
135 if (!at(index)->is_empty()) { | |
136 break; | |
137 } | |
138 res += 1; | |
2152 | 139 } |
342 | 140 return res; |
141 } | |
142 | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
143 uint HeapRegionSeq::find_contiguous(uint num) { |
3766 | 144 assert(num > 1, "use this only for sequences of length 2 or greater"); |
145 assert(_next_search_index <= length(), | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
146 err_msg("_next_search_index: %u should be valid and <= than %u", |
3766 | 147 _next_search_index, length())); |
148 | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
149 uint start = _next_search_index; |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
150 uint res = find_contiguous_from(start, num); |
3766 | 151 if (res == G1_NULL_HRS_INDEX && start > 0) { |
152 // Try starting from the beginning. If _next_search_index was 0, | |
153 // no point in doing this again. | |
154 res = find_contiguous_from(0, num); | |
155 } | |
156 if (res != G1_NULL_HRS_INDEX) { | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
157 assert(res < length(), err_msg("res: %u should be valid", res)); |
3766 | 158 _next_search_index = res + num; |
159 assert(_next_search_index <= length(), | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
160 err_msg("_next_search_index: %u should be valid and <= than %u", |
3766 | 161 _next_search_index, length())); |
162 } | |
163 return res; | |
342 | 164 } |
165 | |
3766 | 166 void HeapRegionSeq::iterate(HeapRegionClosure* blk) const { |
167 iterate_from((HeapRegion*) NULL, blk); | |
168 } | |
342 | 169 |
3766 | 170 void HeapRegionSeq::iterate_from(HeapRegion* hr, HeapRegionClosure* blk) const { |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
171 uint hr_index = 0; |
3766 | 172 if (hr != NULL) { |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
173 hr_index = hr->hrs_index(); |
342 | 174 } |
3766 | 175 |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
176 uint len = length(); |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
177 for (uint i = hr_index; i < len; i += 1) { |
3766 | 178 bool res = blk->doHeapRegion(at(i)); |
342 | 179 if (res) { |
180 blk->incomplete(); | |
181 return; | |
182 } | |
183 } | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
184 for (uint i = 0; i < hr_index; i += 1) { |
3766 | 185 bool res = blk->doHeapRegion(at(i)); |
342 | 186 if (res) { |
187 blk->incomplete(); | |
188 return; | |
189 } | |
190 } | |
191 } | |
192 | |
10242
b0d20fa374b4
8013872: G1: HeapRegionSeq::shrink_by() has invalid assert
brutisso
parents:
6197
diff
changeset
|
193 uint HeapRegionSeq::shrink_by(uint num_regions_to_remove) { |
2152 | 194 // Reset this in case it's currently pointing into the regions that |
195 // we just removed. | |
3766 | 196 _next_search_index = 0; |
2152 | 197 |
3766 | 198 assert(length() > 0, "the region sequence should not be empty"); |
199 assert(length() <= _allocated_length, "invariant"); | |
200 assert(_allocated_length > 0, "we should have at least one region committed"); | |
10242
b0d20fa374b4
8013872: G1: HeapRegionSeq::shrink_by() has invalid assert
brutisso
parents:
6197
diff
changeset
|
201 assert(num_regions_to_remove < length(), "We should never remove all regions"); |
342 | 202 |
10242
b0d20fa374b4
8013872: G1: HeapRegionSeq::shrink_by() has invalid assert
brutisso
parents:
6197
diff
changeset
|
203 uint i = 0; |
b0d20fa374b4
8013872: G1: HeapRegionSeq::shrink_by() has invalid assert
brutisso
parents:
6197
diff
changeset
|
204 for (; i < num_regions_to_remove; i++) { |
b0d20fa374b4
8013872: G1: HeapRegionSeq::shrink_by() has invalid assert
brutisso
parents:
6197
diff
changeset
|
205 HeapRegion* cur = at(length() - 1); |
3766 | 206 |
10242
b0d20fa374b4
8013872: G1: HeapRegionSeq::shrink_by() has invalid assert
brutisso
parents:
6197
diff
changeset
|
207 if (!cur->is_empty()) { |
b0d20fa374b4
8013872: G1: HeapRegionSeq::shrink_by() has invalid assert
brutisso
parents:
6197
diff
changeset
|
208 // We have to give up if the region can not be moved |
b0d20fa374b4
8013872: G1: HeapRegionSeq::shrink_by() has invalid assert
brutisso
parents:
6197
diff
changeset
|
209 break; |
342 | 210 } |
10242
b0d20fa374b4
8013872: G1: HeapRegionSeq::shrink_by() has invalid assert
brutisso
parents:
6197
diff
changeset
|
211 assert(!cur->isHumongous(), "Humongous regions should not be empty"); |
b0d20fa374b4
8013872: G1: HeapRegionSeq::shrink_by() has invalid assert
brutisso
parents:
6197
diff
changeset
|
212 |
b0d20fa374b4
8013872: G1: HeapRegionSeq::shrink_by() has invalid assert
brutisso
parents:
6197
diff
changeset
|
213 decrement_length(); |
b0d20fa374b4
8013872: G1: HeapRegionSeq::shrink_by() has invalid assert
brutisso
parents:
6197
diff
changeset
|
214 } |
b0d20fa374b4
8013872: G1: HeapRegionSeq::shrink_by() has invalid assert
brutisso
parents:
6197
diff
changeset
|
215 return i; |
342 | 216 } |
217 | |
3766 | 218 #ifndef PRODUCT |
219 void HeapRegionSeq::verify_optional() { | |
12305
a19bea467577
7163191: G1: introduce a "heap spanning table" abstraction
tschatzl
parents:
10242
diff
changeset
|
220 guarantee(length() <= _allocated_length, |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
221 err_msg("invariant: _length: %u _allocated_length: %u", |
12305
a19bea467577
7163191: G1: introduce a "heap spanning table" abstraction
tschatzl
parents:
10242
diff
changeset
|
222 length(), _allocated_length)); |
a19bea467577
7163191: G1: introduce a "heap spanning table" abstraction
tschatzl
parents:
10242
diff
changeset
|
223 guarantee(_allocated_length <= max_length(), |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
224 err_msg("invariant: _allocated_length: %u _max_length: %u", |
12305
a19bea467577
7163191: G1: introduce a "heap spanning table" abstraction
tschatzl
parents:
10242
diff
changeset
|
225 _allocated_length, max_length())); |
a19bea467577
7163191: G1: introduce a "heap spanning table" abstraction
tschatzl
parents:
10242
diff
changeset
|
226 guarantee(_next_search_index <= length(), |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
227 err_msg("invariant: _next_search_index: %u _length: %u", |
12305
a19bea467577
7163191: G1: introduce a "heap spanning table" abstraction
tschatzl
parents:
10242
diff
changeset
|
228 _next_search_index, length())); |
3766 | 229 |
12305
a19bea467577
7163191: G1: introduce a "heap spanning table" abstraction
tschatzl
parents:
10242
diff
changeset
|
230 HeapWord* prev_end = heap_bottom(); |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
231 for (uint i = 0; i < _allocated_length; i += 1) { |
12305
a19bea467577
7163191: G1: introduce a "heap spanning table" abstraction
tschatzl
parents:
10242
diff
changeset
|
232 HeapRegion* hr = _regions.get_by_index(i); |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
233 guarantee(hr != NULL, err_msg("invariant: i: %u", i)); |
3766 | 234 guarantee(hr->bottom() == prev_end, |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
235 err_msg("invariant i: %u "HR_FORMAT" prev_end: "PTR_FORMAT, |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17736
diff
changeset
|
236 i, HR_FORMAT_PARAMS(hr), p2i(prev_end))); |
3766 | 237 guarantee(hr->hrs_index() == i, |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
3766
diff
changeset
|
238 err_msg("invariant: i: %u hrs_index(): %u", i, hr->hrs_index())); |
12305
a19bea467577
7163191: G1: introduce a "heap spanning table" abstraction
tschatzl
parents:
10242
diff
changeset
|
239 if (i < length()) { |
3766 | 240 // Asserts will fire if i is >= _length |
241 HeapWord* addr = hr->bottom(); | |
242 guarantee(addr_to_region(addr) == hr, "sanity"); | |
243 guarantee(addr_to_region_unsafe(addr) == hr, "sanity"); | |
244 } else { | |
245 guarantee(hr->is_empty(), "sanity"); | |
246 guarantee(!hr->isHumongous(), "sanity"); | |
247 // using assert instead of guarantee here since containing_set() | |
248 // is only available in non-product builds. | |
249 assert(hr->containing_set() == NULL, "sanity"); | |
250 } | |
251 if (hr->startsHumongous()) { | |
252 prev_end = hr->orig_end(); | |
253 } else { | |
254 prev_end = hr->end(); | |
255 } | |
342 | 256 } |
12305
a19bea467577
7163191: G1: introduce a "heap spanning table" abstraction
tschatzl
parents:
10242
diff
changeset
|
257 for (uint i = _allocated_length; i < max_length(); i += 1) { |
a19bea467577
7163191: G1: introduce a "heap spanning table" abstraction
tschatzl
parents:
10242
diff
changeset
|
258 guarantee(_regions.get_by_index(i) == NULL, err_msg("invariant i: %u", i)); |
3766 | 259 } |
342 | 260 } |
3766 | 261 #endif // PRODUCT |