Mercurial > hg > graal-jvmci-8
annotate src/share/vm/gc_implementation/g1/heapRegion.cpp @ 2149:7e37af9d69ef
7011379: G1: overly long concurrent marking cycles
Summary: This changeset introduces filtering of SATB buffers at the point when they are about to be enqueued. If this filtering clears enough entries on each buffer, the buffer can then be re-used and not enqueued. This cuts down the number of SATB buffers that need to be processed by the concurrent marking threads.
Reviewed-by: johnc, ysr
author | tonyp |
---|---|
date | Wed, 19 Jan 2011 09:35:17 -0500 |
parents | 2250ee17e258 |
children | 0fa27f37d4d4 |
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:
1550
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1550
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:
1550
diff
changeset
|
21 * questions. |
342 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "gc_implementation/g1/concurrentZFThread.hpp" | |
27 #include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp" | |
28 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" | |
29 #include "gc_implementation/g1/g1OopClosures.inline.hpp" | |
30 #include "gc_implementation/g1/heapRegion.inline.hpp" | |
31 #include "gc_implementation/g1/heapRegionRemSet.hpp" | |
32 #include "gc_implementation/g1/heapRegionSeq.inline.hpp" | |
33 #include "memory/genOopClosures.inline.hpp" | |
34 #include "memory/iterator.hpp" | |
35 #include "oops/oop.inline.hpp" | |
342 | 36 |
942
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
37 int HeapRegion::LogOfHRGrainBytes = 0; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
38 int HeapRegion::LogOfHRGrainWords = 0; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
39 int HeapRegion::GrainBytes = 0; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
40 int HeapRegion::GrainWords = 0; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
41 int HeapRegion::CardsPerRegion = 0; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
42 |
342 | 43 HeapRegionDCTOC::HeapRegionDCTOC(G1CollectedHeap* g1, |
44 HeapRegion* hr, OopClosure* cl, | |
45 CardTableModRefBS::PrecisionStyle precision, | |
46 FilterKind fk) : | |
47 ContiguousSpaceDCTOC(hr, cl, precision, NULL), | |
48 _hr(hr), _fk(fk), _g1(g1) | |
49 {} | |
50 | |
51 FilterOutOfRegionClosure::FilterOutOfRegionClosure(HeapRegion* r, | |
52 OopClosure* oc) : | |
53 _r_bottom(r->bottom()), _r_end(r->end()), | |
54 _oc(oc), _out_of_region(0) | |
55 {} | |
56 | |
57 class VerifyLiveClosure: public OopClosure { | |
811 | 58 private: |
342 | 59 G1CollectedHeap* _g1h; |
60 CardTableModRefBS* _bs; | |
61 oop _containing_obj; | |
62 bool _failures; | |
63 int _n_failures; | |
811 | 64 bool _use_prev_marking; |
342 | 65 public: |
811 | 66 // use_prev_marking == true -> use "prev" marking information, |
67 // use_prev_marking == false -> use "next" marking information | |
68 VerifyLiveClosure(G1CollectedHeap* g1h, bool use_prev_marking) : | |
342 | 69 _g1h(g1h), _bs(NULL), _containing_obj(NULL), |
811 | 70 _failures(false), _n_failures(0), _use_prev_marking(use_prev_marking) |
342 | 71 { |
72 BarrierSet* bs = _g1h->barrier_set(); | |
73 if (bs->is_a(BarrierSet::CardTableModRef)) | |
74 _bs = (CardTableModRefBS*)bs; | |
75 } | |
76 | |
77 void set_containing_obj(oop obj) { | |
78 _containing_obj = obj; | |
79 } | |
80 | |
81 bool failures() { return _failures; } | |
82 int n_failures() { return _n_failures; } | |
83 | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
84 virtual void do_oop(narrowOop* p) { do_oop_work(p); } |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
85 virtual void do_oop( oop* p) { do_oop_work(p); } |
342 | 86 |
1388 | 87 void print_object(outputStream* out, oop obj) { |
88 #ifdef PRODUCT | |
89 klassOop k = obj->klass(); | |
90 const char* class_name = instanceKlass::cast(k)->external_name(); | |
91 out->print_cr("class name %s", class_name); | |
92 #else // PRODUCT | |
93 obj->print_on(out); | |
94 #endif // PRODUCT | |
95 } | |
96 | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
97 template <class T> void do_oop_work(T* p) { |
342 | 98 assert(_containing_obj != NULL, "Precondition"); |
811 | 99 assert(!_g1h->is_obj_dead_cond(_containing_obj, _use_prev_marking), |
100 "Precondition"); | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
101 T heap_oop = oopDesc::load_heap_oop(p); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
102 if (!oopDesc::is_null(heap_oop)) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
103 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); |
342 | 104 bool failed = false; |
811 | 105 if (!_g1h->is_in_closed_subset(obj) || |
106 _g1h->is_obj_dead_cond(obj, _use_prev_marking)) { | |
342 | 107 if (!_failures) { |
108 gclog_or_tty->print_cr(""); | |
109 gclog_or_tty->print_cr("----------"); | |
110 } | |
111 if (!_g1h->is_in_closed_subset(obj)) { | |
1388 | 112 HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p); |
342 | 113 gclog_or_tty->print_cr("Field "PTR_FORMAT |
1388 | 114 " of live obj "PTR_FORMAT" in region " |
115 "["PTR_FORMAT", "PTR_FORMAT")", | |
116 p, (void*) _containing_obj, | |
117 from->bottom(), from->end()); | |
118 print_object(gclog_or_tty, _containing_obj); | |
119 gclog_or_tty->print_cr("points to obj "PTR_FORMAT" not in the heap", | |
120 (void*) obj); | |
121 } else { | |
122 HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p); | |
123 HeapRegion* to = _g1h->heap_region_containing((HeapWord*)obj); | |
124 gclog_or_tty->print_cr("Field "PTR_FORMAT | |
125 " of live obj "PTR_FORMAT" in region " | |
126 "["PTR_FORMAT", "PTR_FORMAT")", | |
127 p, (void*) _containing_obj, | |
128 from->bottom(), from->end()); | |
129 print_object(gclog_or_tty, _containing_obj); | |
130 gclog_or_tty->print_cr("points to dead obj "PTR_FORMAT" in region " | |
131 "["PTR_FORMAT", "PTR_FORMAT")", | |
132 (void*) obj, to->bottom(), to->end()); | |
133 print_object(gclog_or_tty, obj); | |
342 | 134 } |
135 gclog_or_tty->print_cr("----------"); | |
136 _failures = true; | |
137 failed = true; | |
138 _n_failures++; | |
139 } | |
140 | |
141 if (!_g1h->full_collection()) { | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
142 HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
143 HeapRegion* to = _g1h->heap_region_containing(obj); |
342 | 144 if (from != NULL && to != NULL && |
145 from != to && | |
146 !to->isHumongous()) { | |
147 jbyte cv_obj = *_bs->byte_for_const(_containing_obj); | |
148 jbyte cv_field = *_bs->byte_for_const(p); | |
149 const jbyte dirty = CardTableModRefBS::dirty_card_val(); | |
150 | |
151 bool is_bad = !(from->is_young() | |
152 || to->rem_set()->contains_reference(p) | |
153 || !G1HRRSFlushLogBuffersOnVerify && // buffers were not flushed | |
154 (_containing_obj->is_objArray() ? | |
155 cv_field == dirty | |
156 : cv_obj == dirty || cv_field == dirty)); | |
157 if (is_bad) { | |
158 if (!_failures) { | |
159 gclog_or_tty->print_cr(""); | |
160 gclog_or_tty->print_cr("----------"); | |
161 } | |
162 gclog_or_tty->print_cr("Missing rem set entry:"); | |
163 gclog_or_tty->print_cr("Field "PTR_FORMAT | |
164 " of obj "PTR_FORMAT | |
165 ", in region %d ["PTR_FORMAT | |
166 ", "PTR_FORMAT"),", | |
167 p, (void*) _containing_obj, | |
168 from->hrs_index(), | |
169 from->bottom(), | |
170 from->end()); | |
171 _containing_obj->print_on(gclog_or_tty); | |
172 gclog_or_tty->print_cr("points to obj "PTR_FORMAT | |
173 " in region %d ["PTR_FORMAT | |
174 ", "PTR_FORMAT").", | |
175 (void*) obj, to->hrs_index(), | |
176 to->bottom(), to->end()); | |
177 obj->print_on(gclog_or_tty); | |
178 gclog_or_tty->print_cr("Obj head CTE = %d, field CTE = %d.", | |
179 cv_obj, cv_field); | |
180 gclog_or_tty->print_cr("----------"); | |
181 _failures = true; | |
182 if (!failed) _n_failures++; | |
183 } | |
184 } | |
185 } | |
186 } | |
187 } | |
188 }; | |
189 | |
190 template<class ClosureType> | |
191 HeapWord* walk_mem_region_loop(ClosureType* cl, G1CollectedHeap* g1h, | |
192 HeapRegion* hr, | |
193 HeapWord* cur, HeapWord* top) { | |
194 oop cur_oop = oop(cur); | |
195 int oop_size = cur_oop->size(); | |
196 HeapWord* next_obj = cur + oop_size; | |
197 while (next_obj < top) { | |
198 // Keep filtering the remembered set. | |
199 if (!g1h->is_obj_dead(cur_oop, hr)) { | |
200 // Bottom lies entirely below top, so we can call the | |
201 // non-memRegion version of oop_iterate below. | |
202 cur_oop->oop_iterate(cl); | |
203 } | |
204 cur = next_obj; | |
205 cur_oop = oop(cur); | |
206 oop_size = cur_oop->size(); | |
207 next_obj = cur + oop_size; | |
208 } | |
209 return cur; | |
210 } | |
211 | |
212 void HeapRegionDCTOC::walk_mem_region_with_cl(MemRegion mr, | |
213 HeapWord* bottom, | |
214 HeapWord* top, | |
215 OopClosure* cl) { | |
216 G1CollectedHeap* g1h = _g1; | |
217 | |
218 int oop_size; | |
219 | |
220 OopClosure* cl2 = cl; | |
221 FilterIntoCSClosure intoCSFilt(this, g1h, cl); | |
222 FilterOutOfRegionClosure outOfRegionFilt(_hr, cl); | |
223 switch (_fk) { | |
224 case IntoCSFilterKind: cl2 = &intoCSFilt; break; | |
225 case OutOfRegionFilterKind: cl2 = &outOfRegionFilt; break; | |
226 } | |
227 | |
228 // Start filtering what we add to the remembered set. If the object is | |
229 // not considered dead, either because it is marked (in the mark bitmap) | |
230 // or it was allocated after marking finished, then we add it. Otherwise | |
231 // we can safely ignore the object. | |
232 if (!g1h->is_obj_dead(oop(bottom), _hr)) { | |
233 oop_size = oop(bottom)->oop_iterate(cl2, mr); | |
234 } else { | |
235 oop_size = oop(bottom)->size(); | |
236 } | |
237 | |
238 bottom += oop_size; | |
239 | |
240 if (bottom < top) { | |
241 // We replicate the loop below for several kinds of possible filters. | |
242 switch (_fk) { | |
243 case NoFilterKind: | |
244 bottom = walk_mem_region_loop(cl, g1h, _hr, bottom, top); | |
245 break; | |
246 case IntoCSFilterKind: { | |
247 FilterIntoCSClosure filt(this, g1h, cl); | |
248 bottom = walk_mem_region_loop(&filt, g1h, _hr, bottom, top); | |
249 break; | |
250 } | |
251 case OutOfRegionFilterKind: { | |
252 FilterOutOfRegionClosure filt(_hr, cl); | |
253 bottom = walk_mem_region_loop(&filt, g1h, _hr, bottom, top); | |
254 break; | |
255 } | |
256 default: | |
257 ShouldNotReachHere(); | |
258 } | |
259 | |
260 // Last object. Need to do dead-obj filtering here too. | |
261 if (!g1h->is_obj_dead(oop(bottom), _hr)) { | |
262 oop(bottom)->oop_iterate(cl2, mr); | |
263 } | |
264 } | |
265 } | |
266 | |
942
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
267 // Minimum region size; we won't go lower than that. |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
268 // We might want to decrease this in the future, to deal with small |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
269 // heaps a bit more efficiently. |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
270 #define MIN_REGION_SIZE ( 1024 * 1024 ) |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
271 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
272 // Maximum region size; we don't go higher than that. There's a good |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
273 // reason for having an upper bound. We don't want regions to get too |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
274 // large, otherwise cleanup's effectiveness would decrease as there |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
275 // will be fewer opportunities to find totally empty regions after |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
276 // marking. |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
277 #define MAX_REGION_SIZE ( 32 * 1024 * 1024 ) |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
278 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
279 // The automatic region size calculation will try to have around this |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
280 // many regions in the heap (based on the min heap size). |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
281 #define TARGET_REGION_NUMBER 2048 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
282 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
283 void HeapRegion::setup_heap_region_size(uintx min_heap_size) { |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
284 // region_size in bytes |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
285 uintx region_size = G1HeapRegionSize; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
286 if (FLAG_IS_DEFAULT(G1HeapRegionSize)) { |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
287 // We base the automatic calculation on the min heap size. This |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
288 // can be problematic if the spread between min and max is quite |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
289 // wide, imagine -Xms128m -Xmx32g. But, if we decided it based on |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
290 // the max size, the region size might be way too large for the |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
291 // min size. Either way, some users might have to set the region |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
292 // size manually for some -Xms / -Xmx combos. |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
293 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
294 region_size = MAX2(min_heap_size / TARGET_REGION_NUMBER, |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
295 (uintx) MIN_REGION_SIZE); |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
296 } |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
297 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
298 int region_size_log = log2_long((jlong) region_size); |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
299 // Recalculate the region size to make sure it's a power of |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
300 // 2. This means that region_size is the largest power of 2 that's |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
301 // <= what we've calculated so far. |
1485
fb57d4cf76c2
6931180: Migration to recent versions of MS Platform SDK
prr
parents:
1394
diff
changeset
|
302 region_size = ((uintx)1 << region_size_log); |
942
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
303 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
304 // Now make sure that we don't go over or under our limits. |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
305 if (region_size < MIN_REGION_SIZE) { |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
306 region_size = MIN_REGION_SIZE; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
307 } else if (region_size > MAX_REGION_SIZE) { |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
308 region_size = MAX_REGION_SIZE; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
309 } |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
310 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
311 // And recalculate the log. |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
312 region_size_log = log2_long((jlong) region_size); |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
313 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
314 // Now, set up the globals. |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
315 guarantee(LogOfHRGrainBytes == 0, "we should only set it once"); |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
316 LogOfHRGrainBytes = region_size_log; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
317 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
318 guarantee(LogOfHRGrainWords == 0, "we should only set it once"); |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
319 LogOfHRGrainWords = LogOfHRGrainBytes - LogHeapWordSize; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
320 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
321 guarantee(GrainBytes == 0, "we should only set it once"); |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
322 // The cast to int is safe, given that we've bounded region_size by |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
323 // MIN_REGION_SIZE and MAX_REGION_SIZE. |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
324 GrainBytes = (int) region_size; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
325 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
326 guarantee(GrainWords == 0, "we should only set it once"); |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
327 GrainWords = GrainBytes >> LogHeapWordSize; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
328 guarantee(1 << LogOfHRGrainWords == GrainWords, "sanity"); |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
329 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
330 guarantee(CardsPerRegion == 0, "we should only set it once"); |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
331 CardsPerRegion = GrainBytes >> CardTableModRefBS::card_shift; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
332 } |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
333 |
342 | 334 void HeapRegion::reset_after_compaction() { |
335 G1OffsetTableContigSpace::reset_after_compaction(); | |
336 // After a compaction the mark bitmap is invalid, so we must | |
337 // treat all objects as being inside the unmarked area. | |
338 zero_marked_bytes(); | |
339 init_top_at_mark_start(); | |
340 } | |
341 | |
342 DirtyCardToOopClosure* | |
343 HeapRegion::new_dcto_closure(OopClosure* cl, | |
344 CardTableModRefBS::PrecisionStyle precision, | |
345 HeapRegionDCTOC::FilterKind fk) { | |
346 return new HeapRegionDCTOC(G1CollectedHeap::heap(), | |
347 this, cl, precision, fk); | |
348 } | |
349 | |
350 void HeapRegion::hr_clear(bool par, bool clear_space) { | |
355 | 351 _humongous_type = NotHumongous; |
342 | 352 _humongous_start_region = NULL; |
353 _in_collection_set = false; | |
354 _is_gc_alloc_region = false; | |
355 | |
356 // Age stuff (if parallel, this will be done separately, since it needs | |
357 // to be sequential). | |
358 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
359 | |
360 set_young_index_in_cset(-1); | |
361 uninstall_surv_rate_group(); | |
362 set_young_type(NotYoung); | |
363 | |
364 // In case it had been the start of a humongous sequence, reset its end. | |
365 set_end(_orig_end); | |
366 | |
367 if (!par) { | |
368 // If this is parallel, this will be done later. | |
369 HeapRegionRemSet* hrrs = rem_set(); | |
370 if (hrrs != NULL) hrrs->clear(); | |
355 | 371 _claimed = InitialClaimValue; |
342 | 372 } |
373 zero_marked_bytes(); | |
374 set_sort_index(-1); | |
375 | |
376 _offsets.resize(HeapRegion::GrainWords); | |
377 init_top_at_mark_start(); | |
356 | 378 if (clear_space) clear(SpaceDecorator::Mangle); |
342 | 379 } |
380 | |
381 // <PREDICTION> | |
382 void HeapRegion::calc_gc_efficiency() { | |
383 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
384 _gc_efficiency = (double) garbage_bytes() / | |
385 g1h->predict_region_elapsed_time_ms(this, false); | |
386 } | |
387 // </PREDICTION> | |
388 | |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
389 void HeapRegion::set_startsHumongous(HeapWord* new_top, HeapWord* new_end) { |
1886
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
390 assert(end() == _orig_end, |
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
391 "Should be normal before the humongous object allocation"); |
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
392 assert(top() == bottom(), "should be empty"); |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
393 assert(bottom() <= new_top && new_top <= new_end, "pre-condition"); |
1886
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
394 |
355 | 395 _humongous_type = StartsHumongous; |
342 | 396 _humongous_start_region = this; |
1886
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
397 |
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
398 set_end(new_end); |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
399 _offsets.set_for_starts_humongous(new_top); |
1886
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
400 } |
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
401 |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
402 void HeapRegion::set_continuesHumongous(HeapRegion* first_hr) { |
1886
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
403 assert(end() == _orig_end, |
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
404 "Should be normal before the humongous object allocation"); |
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
405 assert(top() == bottom(), "should be empty"); |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
406 assert(first_hr->startsHumongous(), "pre-condition"); |
1886
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
407 |
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
408 _humongous_type = ContinuesHumongous; |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
409 _humongous_start_region = first_hr; |
342 | 410 } |
411 | |
412 bool HeapRegion::claimHeapRegion(jint claimValue) { | |
413 jint current = _claimed; | |
414 if (current != claimValue) { | |
415 jint res = Atomic::cmpxchg(claimValue, &_claimed, current); | |
416 if (res == current) { | |
417 return true; | |
418 } | |
419 } | |
420 return false; | |
421 } | |
422 | |
423 HeapWord* HeapRegion::next_block_start_careful(HeapWord* addr) { | |
424 HeapWord* low = addr; | |
425 HeapWord* high = end(); | |
426 while (low < high) { | |
427 size_t diff = pointer_delta(high, low); | |
428 // Must add one below to bias toward the high amount. Otherwise, if | |
429 // "high" were at the desired value, and "low" were one less, we | |
430 // would not converge on "high". This is not symmetric, because | |
431 // we set "high" to a block start, which might be the right one, | |
432 // which we don't do for "low". | |
433 HeapWord* middle = low + (diff+1)/2; | |
434 if (middle == high) return high; | |
435 HeapWord* mid_bs = block_start_careful(middle); | |
436 if (mid_bs < addr) { | |
437 low = middle; | |
438 } else { | |
439 high = mid_bs; | |
440 } | |
441 } | |
442 assert(low == high && low >= addr, "Didn't work."); | |
443 return low; | |
444 } | |
445 | |
446 void HeapRegion::set_next_on_unclean_list(HeapRegion* r) { | |
447 assert(r == NULL || r->is_on_unclean_list(), "Malformed unclean list."); | |
448 _next_in_special_set = r; | |
449 } | |
450 | |
451 void HeapRegion::set_on_unclean_list(bool b) { | |
452 _is_on_unclean_list = b; | |
453 } | |
454 | |
356 | 455 void HeapRegion::initialize(MemRegion mr, bool clear_space, bool mangle_space) { |
456 G1OffsetTableContigSpace::initialize(mr, false, mangle_space); | |
342 | 457 hr_clear(false/*par*/, clear_space); |
458 } | |
459 #ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away | |
460 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list | |
461 #endif // _MSC_VER | |
462 | |
463 | |
464 HeapRegion:: | |
465 HeapRegion(G1BlockOffsetSharedArray* sharedOffsetArray, | |
466 MemRegion mr, bool is_zeroed) | |
467 : G1OffsetTableContigSpace(sharedOffsetArray, mr, is_zeroed), | |
468 _next_fk(HeapRegionDCTOC::NoFilterKind), | |
469 _hrs_index(-1), | |
355 | 470 _humongous_type(NotHumongous), _humongous_start_region(NULL), |
342 | 471 _in_collection_set(false), _is_gc_alloc_region(false), |
472 _is_on_free_list(false), _is_on_unclean_list(false), | |
473 _next_in_special_set(NULL), _orig_end(NULL), | |
355 | 474 _claimed(InitialClaimValue), _evacuation_failed(false), |
342 | 475 _prev_marked_bytes(0), _next_marked_bytes(0), _sort_index(-1), |
476 _young_type(NotYoung), _next_young_region(NULL), | |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
751
diff
changeset
|
477 _next_dirty_cards_region(NULL), |
342 | 478 _young_index_in_cset(-1), _surv_rate_group(NULL), _age_index(-1), |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1388
diff
changeset
|
479 _rem_set(NULL), _zfs(NotZeroFilled), |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1388
diff
changeset
|
480 _recorded_rs_length(0), _predicted_elapsed_time_ms(0), |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1388
diff
changeset
|
481 _predicted_bytes_to_copy(0) |
342 | 482 { |
483 _orig_end = mr.end(); | |
484 // Note that initialize() will set the start of the unmarked area of the | |
485 // region. | |
356 | 486 this->initialize(mr, !is_zeroed, SpaceDecorator::Mangle); |
487 set_top(bottom()); | |
488 set_saved_mark(); | |
342 | 489 |
490 _rem_set = new HeapRegionRemSet(sharedOffsetArray, this); | |
491 | |
492 assert(HeapRegionRemSet::num_par_rem_sets() > 0, "Invariant."); | |
493 // In case the region is allocated during a pause, note the top. | |
494 // We haven't done any counting on a brand new region. | |
495 _top_at_conc_mark_count = bottom(); | |
496 } | |
497 | |
498 class NextCompactionHeapRegionClosure: public HeapRegionClosure { | |
499 const HeapRegion* _target; | |
500 bool _target_seen; | |
501 HeapRegion* _last; | |
502 CompactibleSpace* _res; | |
503 public: | |
504 NextCompactionHeapRegionClosure(const HeapRegion* target) : | |
505 _target(target), _target_seen(false), _res(NULL) {} | |
506 bool doHeapRegion(HeapRegion* cur) { | |
507 if (_target_seen) { | |
508 if (!cur->isHumongous()) { | |
509 _res = cur; | |
510 return true; | |
511 } | |
512 } else if (cur == _target) { | |
513 _target_seen = true; | |
514 } | |
515 return false; | |
516 } | |
517 CompactibleSpace* result() { return _res; } | |
518 }; | |
519 | |
520 CompactibleSpace* HeapRegion::next_compaction_space() const { | |
521 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
522 // cast away const-ness | |
523 HeapRegion* r = (HeapRegion*) this; | |
524 NextCompactionHeapRegionClosure blk(r); | |
525 g1h->heap_region_iterate_from(r, &blk); | |
526 return blk.result(); | |
527 } | |
528 | |
529 void HeapRegion::save_marks() { | |
530 set_saved_mark(); | |
531 } | |
532 | |
533 void HeapRegion::oops_in_mr_iterate(MemRegion mr, OopClosure* cl) { | |
534 HeapWord* p = mr.start(); | |
535 HeapWord* e = mr.end(); | |
536 oop obj; | |
537 while (p < e) { | |
538 obj = oop(p); | |
539 p += obj->oop_iterate(cl); | |
540 } | |
541 assert(p == e, "bad memregion: doesn't end on obj boundary"); | |
542 } | |
543 | |
544 #define HeapRegion_OOP_SINCE_SAVE_MARKS_DEFN(OopClosureType, nv_suffix) \ | |
545 void HeapRegion::oop_since_save_marks_iterate##nv_suffix(OopClosureType* cl) { \ | |
546 ContiguousSpace::oop_since_save_marks_iterate##nv_suffix(cl); \ | |
547 } | |
548 SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(HeapRegion_OOP_SINCE_SAVE_MARKS_DEFN) | |
549 | |
550 | |
551 void HeapRegion::oop_before_save_marks_iterate(OopClosure* cl) { | |
552 oops_in_mr_iterate(MemRegion(bottom(), saved_mark_word()), cl); | |
553 } | |
554 | |
555 #ifdef DEBUG | |
556 HeapWord* HeapRegion::allocate(size_t size) { | |
557 jint state = zero_fill_state(); | |
558 assert(!G1CollectedHeap::heap()->allocs_are_zero_filled() || | |
559 zero_fill_is_allocated(), | |
560 "When ZF is on, only alloc in ZF'd regions"); | |
561 return G1OffsetTableContigSpace::allocate(size); | |
562 } | |
563 #endif | |
564 | |
565 void HeapRegion::set_zero_fill_state_work(ZeroFillState zfs) { | |
566 assert(ZF_mon->owned_by_self() || | |
567 Universe::heap()->is_gc_active(), | |
568 "Must hold the lock or be a full GC to modify."); | |
1545
cc387008223e
6921317: (partial) G1: assert(top() == bottom() || zfs == Allocated,"Region must be empty, or we must be setting it to
apetrusenko
parents:
1394
diff
changeset
|
569 #ifdef ASSERT |
cc387008223e
6921317: (partial) G1: assert(top() == bottom() || zfs == Allocated,"Region must be empty, or we must be setting it to
apetrusenko
parents:
1394
diff
changeset
|
570 if (top() != bottom() && zfs != Allocated) { |
cc387008223e
6921317: (partial) G1: assert(top() == bottom() || zfs == Allocated,"Region must be empty, or we must be setting it to
apetrusenko
parents:
1394
diff
changeset
|
571 ResourceMark rm; |
cc387008223e
6921317: (partial) G1: assert(top() == bottom() || zfs == Allocated,"Region must be empty, or we must be setting it to
apetrusenko
parents:
1394
diff
changeset
|
572 stringStream region_str; |
cc387008223e
6921317: (partial) G1: assert(top() == bottom() || zfs == Allocated,"Region must be empty, or we must be setting it to
apetrusenko
parents:
1394
diff
changeset
|
573 print_on(®ion_str); |
cc387008223e
6921317: (partial) G1: assert(top() == bottom() || zfs == Allocated,"Region must be empty, or we must be setting it to
apetrusenko
parents:
1394
diff
changeset
|
574 assert(top() == bottom() || zfs == Allocated, |
cc387008223e
6921317: (partial) G1: assert(top() == bottom() || zfs == Allocated,"Region must be empty, or we must be setting it to
apetrusenko
parents:
1394
diff
changeset
|
575 err_msg("Region must be empty, or we must be setting it to allocated. " |
cc387008223e
6921317: (partial) G1: assert(top() == bottom() || zfs == Allocated,"Region must be empty, or we must be setting it to
apetrusenko
parents:
1394
diff
changeset
|
576 "_zfs=%d, zfs=%d, region: %s", _zfs, zfs, region_str.as_string())); |
cc387008223e
6921317: (partial) G1: assert(top() == bottom() || zfs == Allocated,"Region must be empty, or we must be setting it to
apetrusenko
parents:
1394
diff
changeset
|
577 } |
cc387008223e
6921317: (partial) G1: assert(top() == bottom() || zfs == Allocated,"Region must be empty, or we must be setting it to
apetrusenko
parents:
1394
diff
changeset
|
578 #endif |
342 | 579 _zfs = zfs; |
580 } | |
581 | |
582 void HeapRegion::set_zero_fill_complete() { | |
583 set_zero_fill_state_work(ZeroFilled); | |
584 if (ZF_mon->owned_by_self()) { | |
585 ZF_mon->notify_all(); | |
586 } | |
587 } | |
588 | |
589 | |
590 void HeapRegion::ensure_zero_filled() { | |
591 MutexLockerEx x(ZF_mon, Mutex::_no_safepoint_check_flag); | |
592 ensure_zero_filled_locked(); | |
593 } | |
594 | |
595 void HeapRegion::ensure_zero_filled_locked() { | |
596 assert(ZF_mon->owned_by_self(), "Precondition"); | |
597 bool should_ignore_zf = SafepointSynchronize::is_at_safepoint(); | |
598 assert(should_ignore_zf || Heap_lock->is_locked(), | |
599 "Either we're in a GC or we're allocating a region."); | |
600 switch (zero_fill_state()) { | |
601 case HeapRegion::NotZeroFilled: | |
602 set_zero_fill_in_progress(Thread::current()); | |
603 { | |
604 ZF_mon->unlock(); | |
605 Copy::fill_to_words(bottom(), capacity()/HeapWordSize); | |
606 ZF_mon->lock_without_safepoint_check(); | |
607 } | |
608 // A trap. | |
609 guarantee(zero_fill_state() == HeapRegion::ZeroFilling | |
610 && zero_filler() == Thread::current(), | |
611 "AHA! Tell Dave D if you see this..."); | |
612 set_zero_fill_complete(); | |
613 // gclog_or_tty->print_cr("Did sync ZF."); | |
614 ConcurrentZFThread::note_sync_zfs(); | |
615 break; | |
616 case HeapRegion::ZeroFilling: | |
617 if (should_ignore_zf) { | |
618 // We can "break" the lock and take over the work. | |
619 Copy::fill_to_words(bottom(), capacity()/HeapWordSize); | |
620 set_zero_fill_complete(); | |
621 ConcurrentZFThread::note_sync_zfs(); | |
622 break; | |
623 } else { | |
624 ConcurrentZFThread::wait_for_ZF_completed(this); | |
625 } | |
626 case HeapRegion::ZeroFilled: | |
627 // Nothing to do. | |
628 break; | |
629 case HeapRegion::Allocated: | |
630 guarantee(false, "Should not call on allocated regions."); | |
631 } | |
632 assert(zero_fill_state() == HeapRegion::ZeroFilled, "Post"); | |
633 } | |
634 | |
635 HeapWord* | |
636 HeapRegion::object_iterate_mem_careful(MemRegion mr, | |
637 ObjectClosure* cl) { | |
638 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
639 // We used to use "block_start_careful" here. But we're actually happy | |
640 // to update the BOT while we do this... | |
641 HeapWord* cur = block_start(mr.start()); | |
642 mr = mr.intersection(used_region()); | |
643 if (mr.is_empty()) return NULL; | |
644 // Otherwise, find the obj that extends onto mr.start(). | |
645 | |
646 assert(cur <= mr.start() | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
647 && (oop(cur)->klass_or_null() == NULL || |
342 | 648 cur + oop(cur)->size() > mr.start()), |
649 "postcondition of block_start"); | |
650 oop obj; | |
651 while (cur < mr.end()) { | |
652 obj = oop(cur); | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
653 if (obj->klass_or_null() == NULL) { |
342 | 654 // Ran into an unparseable point. |
655 return cur; | |
656 } else if (!g1h->is_obj_dead(obj)) { | |
657 cl->do_object(obj); | |
658 } | |
659 if (cl->abort()) return cur; | |
660 // The check above must occur before the operation below, since an | |
661 // abort might invalidate the "size" operation. | |
662 cur += obj->size(); | |
663 } | |
664 return NULL; | |
665 } | |
666 | |
667 HeapWord* | |
668 HeapRegion:: | |
669 oops_on_card_seq_iterate_careful(MemRegion mr, | |
1666
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
670 FilterOutOfRegionClosure* cl, |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
671 bool filter_young) { |
342 | 672 G1CollectedHeap* g1h = G1CollectedHeap::heap(); |
673 | |
674 // If we're within a stop-world GC, then we might look at a card in a | |
675 // GC alloc region that extends onto a GC LAB, which may not be | |
676 // parseable. Stop such at the "saved_mark" of the region. | |
677 if (G1CollectedHeap::heap()->is_gc_active()) { | |
678 mr = mr.intersection(used_region_at_save_marks()); | |
679 } else { | |
680 mr = mr.intersection(used_region()); | |
681 } | |
682 if (mr.is_empty()) return NULL; | |
683 // Otherwise, find the obj that extends onto mr.start(). | |
684 | |
1666
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
685 // The intersection of the incoming mr (for the card) and the |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
686 // allocated part of the region is non-empty. This implies that |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
687 // we have actually allocated into this region. The code in |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
688 // G1CollectedHeap.cpp that allocates a new region sets the |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
689 // is_young tag on the region before allocating. Thus we |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
690 // safely know if this region is young. |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
691 if (is_young() && filter_young) { |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
692 return NULL; |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
693 } |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
694 |
1705 | 695 assert(!is_young(), "check value of filter_young"); |
696 | |
342 | 697 // We used to use "block_start_careful" here. But we're actually happy |
698 // to update the BOT while we do this... | |
699 HeapWord* cur = block_start(mr.start()); | |
700 assert(cur <= mr.start(), "Postcondition"); | |
701 | |
702 while (cur <= mr.start()) { | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
703 if (oop(cur)->klass_or_null() == NULL) { |
342 | 704 // Ran into an unparseable point. |
705 return cur; | |
706 } | |
707 // Otherwise... | |
708 int sz = oop(cur)->size(); | |
709 if (cur + sz > mr.start()) break; | |
710 // Otherwise, go on. | |
711 cur = cur + sz; | |
712 } | |
713 oop obj; | |
714 obj = oop(cur); | |
715 // If we finish this loop... | |
716 assert(cur <= mr.start() | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
717 && obj->klass_or_null() != NULL |
342 | 718 && cur + obj->size() > mr.start(), |
719 "Loop postcondition"); | |
720 if (!g1h->is_obj_dead(obj)) { | |
721 obj->oop_iterate(cl, mr); | |
722 } | |
723 | |
724 HeapWord* next; | |
725 while (cur < mr.end()) { | |
726 obj = oop(cur); | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
727 if (obj->klass_or_null() == NULL) { |
342 | 728 // Ran into an unparseable point. |
729 return cur; | |
730 }; | |
731 // Otherwise: | |
732 next = (cur + obj->size()); | |
733 if (!g1h->is_obj_dead(obj)) { | |
734 if (next < mr.end()) { | |
735 obj->oop_iterate(cl); | |
736 } else { | |
737 // this obj spans the boundary. If it's an array, stop at the | |
738 // boundary. | |
739 if (obj->is_objArray()) { | |
740 obj->oop_iterate(cl, mr); | |
741 } else { | |
742 obj->oop_iterate(cl); | |
743 } | |
744 } | |
745 } | |
746 cur = next; | |
747 } | |
748 return NULL; | |
749 } | |
750 | |
751 void HeapRegion::print() const { print_on(gclog_or_tty); } | |
752 void HeapRegion::print_on(outputStream* st) const { | |
753 if (isHumongous()) { | |
754 if (startsHumongous()) | |
755 st->print(" HS"); | |
756 else | |
757 st->print(" HC"); | |
758 } else { | |
759 st->print(" "); | |
760 } | |
761 if (in_collection_set()) | |
762 st->print(" CS"); | |
763 else if (is_gc_alloc_region()) | |
764 st->print(" A "); | |
765 else | |
766 st->print(" "); | |
767 if (is_young()) | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1388
diff
changeset
|
768 st->print(is_survivor() ? " SU" : " Y "); |
342 | 769 else |
770 st->print(" "); | |
771 if (is_empty()) | |
772 st->print(" F"); | |
773 else | |
774 st->print(" "); | |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
775 st->print(" %5d", _gc_time_stamp); |
1388 | 776 st->print(" PTAMS "PTR_FORMAT" NTAMS "PTR_FORMAT, |
777 prev_top_at_mark_start(), next_top_at_mark_start()); | |
342 | 778 G1OffsetTableContigSpace::print_on(st); |
779 } | |
780 | |
811 | 781 void HeapRegion::verify(bool allow_dirty) const { |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
782 bool dummy = false; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
783 verify(allow_dirty, /* use_prev_marking */ true, /* failures */ &dummy); |
811 | 784 } |
785 | |
342 | 786 // This really ought to be commoned up into OffsetTableContigSpace somehow. |
787 // We would need a mechanism to make that code skip dead objects. | |
788 | |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
789 void HeapRegion::verify(bool allow_dirty, |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
790 bool use_prev_marking, |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
791 bool* failures) const { |
342 | 792 G1CollectedHeap* g1 = G1CollectedHeap::heap(); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
793 *failures = false; |
342 | 794 HeapWord* p = bottom(); |
795 HeapWord* prev_p = NULL; | |
811 | 796 VerifyLiveClosure vl_cl(g1, use_prev_marking); |
1718
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
797 bool is_humongous = isHumongous(); |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
798 bool do_bot_verify = !is_young(); |
1718
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
799 size_t object_num = 0; |
342 | 800 while (p < top()) { |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
801 oop obj = oop(p); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
802 size_t obj_size = obj->size(); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
803 object_num += 1; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
804 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
805 if (is_humongous != g1->isHumongous(obj_size)) { |
1718
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
806 gclog_or_tty->print_cr("obj "PTR_FORMAT" is of %shumongous size (" |
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
807 SIZE_FORMAT" words) in a %shumongous region", |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
808 p, g1->isHumongous(obj_size) ? "" : "non-", |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
809 obj_size, is_humongous ? "" : "non-"); |
1718
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
810 *failures = true; |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
811 return; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
812 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
813 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
814 // If it returns false, verify_for_object() will output the |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
815 // appropriate messasge. |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
816 if (do_bot_verify && !_offsets.verify_for_object(p, obj_size)) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
817 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
818 return; |
1718
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
819 } |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
820 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
821 if (!g1->is_obj_dead_cond(obj, this, use_prev_marking)) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
822 if (obj->is_oop()) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
823 klassOop klass = obj->klass(); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
824 if (!klass->is_perm()) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
825 gclog_or_tty->print_cr("klass "PTR_FORMAT" of object "PTR_FORMAT" " |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
826 "not in perm", klass, obj); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
827 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
828 return; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
829 } else if (!klass->is_klass()) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
830 gclog_or_tty->print_cr("klass "PTR_FORMAT" of object "PTR_FORMAT" " |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
831 "not a klass", klass, obj); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
832 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
833 return; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
834 } else { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
835 vl_cl.set_containing_obj(obj); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
836 obj->oop_iterate(&vl_cl); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
837 if (vl_cl.failures()) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
838 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
839 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
840 if (G1MaxVerifyFailures >= 0 && |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
841 vl_cl.n_failures() >= G1MaxVerifyFailures) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
842 return; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
843 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
844 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
845 } else { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
846 gclog_or_tty->print_cr(PTR_FORMAT" no an oop", obj); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
847 *failures = true; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
848 return; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
849 } |
342 | 850 } |
851 prev_p = p; | |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
852 p += obj_size; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
853 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
854 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
855 if (p != top()) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
856 gclog_or_tty->print_cr("end of last object "PTR_FORMAT" " |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
857 "does not match top "PTR_FORMAT, p, top()); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
858 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
859 return; |
342 | 860 } |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
861 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
862 HeapWord* the_end = end(); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
863 assert(p == top(), "it should still hold"); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
864 // Do some extra BOT consistency checking for addresses in the |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
865 // range [top, end). BOT look-ups in this range should yield |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
866 // top. No point in doing that if top == end (there's nothing there). |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
867 if (p < the_end) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
868 // Look up top |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
869 HeapWord* addr_1 = p; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
870 HeapWord* b_start_1 = _offsets.block_start_const(addr_1); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
871 if (b_start_1 != p) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
872 gclog_or_tty->print_cr("BOT look up for top: "PTR_FORMAT" " |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
873 " yielded "PTR_FORMAT", expecting "PTR_FORMAT, |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
874 addr_1, b_start_1, p); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
875 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
876 return; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
877 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
878 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
879 // Look up top + 1 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
880 HeapWord* addr_2 = p + 1; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
881 if (addr_2 < the_end) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
882 HeapWord* b_start_2 = _offsets.block_start_const(addr_2); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
883 if (b_start_2 != p) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
884 gclog_or_tty->print_cr("BOT look up for top + 1: "PTR_FORMAT" " |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
885 " yielded "PTR_FORMAT", expecting "PTR_FORMAT, |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
886 addr_2, b_start_2, p); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
887 *failures = true; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
888 return; |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
889 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
890 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
891 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
892 // Look up an address between top and end |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
893 size_t diff = pointer_delta(the_end, p) / 2; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
894 HeapWord* addr_3 = p + diff; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
895 if (addr_3 < the_end) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
896 HeapWord* b_start_3 = _offsets.block_start_const(addr_3); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
897 if (b_start_3 != p) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
898 gclog_or_tty->print_cr("BOT look up for top + diff: "PTR_FORMAT" " |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
899 " yielded "PTR_FORMAT", expecting "PTR_FORMAT, |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
900 addr_3, b_start_3, p); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
901 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
902 return; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
903 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
904 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
905 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
906 // Loook up end - 1 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
907 HeapWord* addr_4 = the_end - 1; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
908 HeapWord* b_start_4 = _offsets.block_start_const(addr_4); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
909 if (b_start_4 != p) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
910 gclog_or_tty->print_cr("BOT look up for end - 1: "PTR_FORMAT" " |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
911 " yielded "PTR_FORMAT", expecting "PTR_FORMAT, |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
912 addr_4, b_start_4, p); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
913 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
914 return; |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
915 } |
342 | 916 } |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
917 |
1718
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
918 if (is_humongous && object_num > 1) { |
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
919 gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] is humongous " |
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
920 "but has "SIZE_FORMAT", objects", |
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
921 bottom(), end(), object_num); |
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
922 *failures = true; |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
923 return; |
342 | 924 } |
925 } | |
926 | |
927 // G1OffsetTableContigSpace code; copied from space.cpp. Hope this can go | |
928 // away eventually. | |
929 | |
356 | 930 void G1OffsetTableContigSpace::initialize(MemRegion mr, bool clear_space, bool mangle_space) { |
342 | 931 // false ==> we'll do the clearing if there's clearing to be done. |
356 | 932 ContiguousSpace::initialize(mr, false, mangle_space); |
342 | 933 _offsets.zero_bottom_entry(); |
934 _offsets.initialize_threshold(); | |
356 | 935 if (clear_space) clear(mangle_space); |
342 | 936 } |
937 | |
356 | 938 void G1OffsetTableContigSpace::clear(bool mangle_space) { |
939 ContiguousSpace::clear(mangle_space); | |
342 | 940 _offsets.zero_bottom_entry(); |
941 _offsets.initialize_threshold(); | |
942 } | |
943 | |
944 void G1OffsetTableContigSpace::set_bottom(HeapWord* new_bottom) { | |
945 Space::set_bottom(new_bottom); | |
946 _offsets.set_bottom(new_bottom); | |
947 } | |
948 | |
949 void G1OffsetTableContigSpace::set_end(HeapWord* new_end) { | |
950 Space::set_end(new_end); | |
951 _offsets.resize(new_end - bottom()); | |
952 } | |
953 | |
954 void G1OffsetTableContigSpace::print() const { | |
955 print_short(); | |
956 gclog_or_tty->print_cr(" [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " | |
957 INTPTR_FORMAT ", " INTPTR_FORMAT ")", | |
958 bottom(), top(), _offsets.threshold(), end()); | |
959 } | |
960 | |
961 HeapWord* G1OffsetTableContigSpace::initialize_threshold() { | |
962 return _offsets.initialize_threshold(); | |
963 } | |
964 | |
965 HeapWord* G1OffsetTableContigSpace::cross_threshold(HeapWord* start, | |
966 HeapWord* end) { | |
967 _offsets.alloc_block(start, end); | |
968 return _offsets.threshold(); | |
969 } | |
970 | |
971 HeapWord* G1OffsetTableContigSpace::saved_mark_word() const { | |
972 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
973 assert( _gc_time_stamp <= g1h->get_gc_time_stamp(), "invariant" ); | |
974 if (_gc_time_stamp < g1h->get_gc_time_stamp()) | |
975 return top(); | |
976 else | |
977 return ContiguousSpace::saved_mark_word(); | |
978 } | |
979 | |
980 void G1OffsetTableContigSpace::set_saved_mark() { | |
981 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
982 unsigned curr_gc_time_stamp = g1h->get_gc_time_stamp(); | |
983 | |
984 if (_gc_time_stamp < curr_gc_time_stamp) { | |
985 // The order of these is important, as another thread might be | |
986 // about to start scanning this region. If it does so after | |
987 // set_saved_mark and before _gc_time_stamp = ..., then the latter | |
988 // will be false, and it will pick up top() as the high water mark | |
989 // of region. If it does so after _gc_time_stamp = ..., then it | |
990 // will pick up the right saved_mark_word() as the high water mark | |
991 // of the region. Either way, the behaviour will be correct. | |
992 ContiguousSpace::set_saved_mark(); | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
993 OrderAccess::storestore(); |
353
9bb2c10ac07b
6723570: G1: assertion failure: p == current_top or oop(p)->is_oop(),"p is not a block start" (revisited!)
iveresov
parents:
342
diff
changeset
|
994 _gc_time_stamp = curr_gc_time_stamp; |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
995 // The following fence is to force a flush of the writes above, but |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
996 // is strictly not needed because when an allocating worker thread |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
997 // calls set_saved_mark() it does so under the ParGCRareEvent_lock; |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
998 // when the lock is released, the write will be flushed. |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
999 // OrderAccess::fence(); |
342 | 1000 } |
1001 } | |
1002 | |
1003 G1OffsetTableContigSpace:: | |
1004 G1OffsetTableContigSpace(G1BlockOffsetSharedArray* sharedOffsetArray, | |
1005 MemRegion mr, bool is_zeroed) : | |
1006 _offsets(sharedOffsetArray, mr), | |
1007 _par_alloc_lock(Mutex::leaf, "OffsetTableContigSpace par alloc lock", true), | |
1008 _gc_time_stamp(0) | |
1009 { | |
1010 _offsets.set_space(this); | |
356 | 1011 initialize(mr, !is_zeroed, SpaceDecorator::Mangle); |
342 | 1012 } |
1013 | |
1014 size_t RegionList::length() { | |
1015 size_t len = 0; | |
1016 HeapRegion* cur = hd(); | |
1017 DEBUG_ONLY(HeapRegion* last = NULL); | |
1018 while (cur != NULL) { | |
1019 len++; | |
1020 DEBUG_ONLY(last = cur); | |
1021 cur = get_next(cur); | |
1022 } | |
1023 assert(last == tl(), "Invariant"); | |
1024 return len; | |
1025 } | |
1026 | |
1027 void RegionList::insert_before_head(HeapRegion* r) { | |
1028 assert(well_formed(), "Inv"); | |
1029 set_next(r, hd()); | |
1030 _hd = r; | |
1031 _sz++; | |
1032 if (tl() == NULL) _tl = r; | |
1033 assert(well_formed(), "Inv"); | |
1034 } | |
1035 | |
1036 void RegionList::prepend_list(RegionList* new_list) { | |
1037 assert(well_formed(), "Precondition"); | |
1038 assert(new_list->well_formed(), "Precondition"); | |
1039 HeapRegion* new_tl = new_list->tl(); | |
1040 if (new_tl != NULL) { | |
1041 set_next(new_tl, hd()); | |
1042 _hd = new_list->hd(); | |
1043 _sz += new_list->sz(); | |
1044 if (tl() == NULL) _tl = new_list->tl(); | |
1045 } else { | |
1046 assert(new_list->hd() == NULL && new_list->sz() == 0, "Inv"); | |
1047 } | |
1048 assert(well_formed(), "Inv"); | |
1049 } | |
1050 | |
1051 void RegionList::delete_after(HeapRegion* r) { | |
1052 assert(well_formed(), "Precondition"); | |
1053 HeapRegion* next = get_next(r); | |
1054 assert(r != NULL, "Precondition"); | |
1055 HeapRegion* next_tl = get_next(next); | |
1056 set_next(r, next_tl); | |
1057 dec_sz(); | |
1058 if (next == tl()) { | |
1059 assert(next_tl == NULL, "Inv"); | |
1060 _tl = r; | |
1061 } | |
1062 assert(well_formed(), "Inv"); | |
1063 } | |
1064 | |
1065 HeapRegion* RegionList::pop() { | |
1066 assert(well_formed(), "Inv"); | |
1067 HeapRegion* res = hd(); | |
1068 if (res != NULL) { | |
1069 _hd = get_next(res); | |
1070 _sz--; | |
1071 set_next(res, NULL); | |
1072 if (sz() == 0) _tl = NULL; | |
1073 } | |
1074 assert(well_formed(), "Inv"); | |
1075 return res; | |
1076 } |