Mercurial > hg > truffle
annotate src/share/vm/gc_implementation/g1/heapRegion.cpp @ 3979:4dfb2df418f2
6484982: G1: process references during evacuation pauses
Summary: G1 now uses two reference processors - one is used by concurrent marking and the other is used by STW GCs (both full and incremental evacuation pauses). In an evacuation pause, the reference processor is embedded into the closures used to scan objects. Doing so causes causes reference objects to be 'discovered' by the reference processor. At the end of the evacuation pause, these discovered reference objects are processed - preserving (and copying) referent objects (and their reachable graphs) as appropriate.
Reviewed-by: ysr, jwilhelm, brutisso, stefank, tonyp
author | johnc |
---|---|
date | Thu, 22 Sep 2011 10:57:37 -0700 |
parents | f0ecbe78fc7b |
children | 811ec3d0833b |
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/g1BlockOffsetTable.inline.hpp" | |
27 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" | |
28 #include "gc_implementation/g1/g1OopClosures.inline.hpp" | |
29 #include "gc_implementation/g1/heapRegion.inline.hpp" | |
30 #include "gc_implementation/g1/heapRegionRemSet.hpp" | |
31 #include "gc_implementation/g1/heapRegionSeq.inline.hpp" | |
32 #include "memory/genOopClosures.inline.hpp" | |
33 #include "memory/iterator.hpp" | |
34 #include "oops/oop.inline.hpp" | |
342 | 35 |
942
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
36 int HeapRegion::LogOfHRGrainBytes = 0; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
37 int HeapRegion::LogOfHRGrainWords = 0; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
38 int HeapRegion::GrainBytes = 0; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
39 int HeapRegion::GrainWords = 0; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
40 int HeapRegion::CardsPerRegion = 0; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
41 |
342 | 42 HeapRegionDCTOC::HeapRegionDCTOC(G1CollectedHeap* g1, |
43 HeapRegion* hr, OopClosure* cl, | |
44 CardTableModRefBS::PrecisionStyle precision, | |
45 FilterKind fk) : | |
46 ContiguousSpaceDCTOC(hr, cl, precision, NULL), | |
47 _hr(hr), _fk(fk), _g1(g1) | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
48 { } |
342 | 49 |
50 FilterOutOfRegionClosure::FilterOutOfRegionClosure(HeapRegion* r, | |
51 OopClosure* oc) : | |
52 _r_bottom(r->bottom()), _r_end(r->end()), | |
53 _oc(oc), _out_of_region(0) | |
54 {} | |
55 | |
56 class VerifyLiveClosure: public OopClosure { | |
811 | 57 private: |
342 | 58 G1CollectedHeap* _g1h; |
59 CardTableModRefBS* _bs; | |
60 oop _containing_obj; | |
61 bool _failures; | |
62 int _n_failures; | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
63 VerifyOption _vo; |
342 | 64 public: |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
65 // _vo == UsePrevMarking -> use "prev" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
66 // _vo == UseNextMarking -> use "next" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
67 // _vo == UseMarkWord -> use mark word from object header. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
68 VerifyLiveClosure(G1CollectedHeap* g1h, VerifyOption vo) : |
342 | 69 _g1h(g1h), _bs(NULL), _containing_obj(NULL), |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
70 _failures(false), _n_failures(0), _vo(vo) |
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"); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
99 assert(!_g1h->is_obj_dead_cond(_containing_obj, _vo), |
811 | 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) || |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
106 _g1h->is_obj_dead_cond(obj, _vo)) { |
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:"); | |
3766 | 163 gclog_or_tty->print_cr("Field "PTR_FORMAT" " |
164 "of obj "PTR_FORMAT", " | |
165 "in region "HR_FORMAT, | |
166 p, (void*) _containing_obj, | |
167 HR_FORMAT_PARAMS(from)); | |
342 | 168 _containing_obj->print_on(gclog_or_tty); |
3766 | 169 gclog_or_tty->print_cr("points to obj "PTR_FORMAT" " |
170 "in region "HR_FORMAT, | |
171 (void*) obj, | |
172 HR_FORMAT_PARAMS(to)); | |
342 | 173 obj->print_on(gclog_or_tty); |
174 gclog_or_tty->print_cr("Obj head CTE = %d, field CTE = %d.", | |
175 cv_obj, cv_field); | |
176 gclog_or_tty->print_cr("----------"); | |
177 _failures = true; | |
178 if (!failed) _n_failures++; | |
179 } | |
180 } | |
181 } | |
182 } | |
183 } | |
184 }; | |
185 | |
186 template<class ClosureType> | |
187 HeapWord* walk_mem_region_loop(ClosureType* cl, G1CollectedHeap* g1h, | |
188 HeapRegion* hr, | |
189 HeapWord* cur, HeapWord* top) { | |
190 oop cur_oop = oop(cur); | |
191 int oop_size = cur_oop->size(); | |
192 HeapWord* next_obj = cur + oop_size; | |
193 while (next_obj < top) { | |
194 // Keep filtering the remembered set. | |
195 if (!g1h->is_obj_dead(cur_oop, hr)) { | |
196 // Bottom lies entirely below top, so we can call the | |
197 // non-memRegion version of oop_iterate below. | |
198 cur_oop->oop_iterate(cl); | |
199 } | |
200 cur = next_obj; | |
201 cur_oop = oop(cur); | |
202 oop_size = cur_oop->size(); | |
203 next_obj = cur + oop_size; | |
204 } | |
205 return cur; | |
206 } | |
207 | |
208 void HeapRegionDCTOC::walk_mem_region_with_cl(MemRegion mr, | |
209 HeapWord* bottom, | |
210 HeapWord* top, | |
211 OopClosure* cl) { | |
212 G1CollectedHeap* g1h = _g1; | |
213 | |
214 int oop_size; | |
215 | |
216 OopClosure* cl2 = cl; | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
217 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
218 // If we are scanning the remembered sets looking for refs |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
219 // into the collection set during an evacuation pause then |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
220 // we will want to 'discover' reference objects that point |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
221 // to referents in the collection set. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
222 // |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
223 // Unfortunately it is an instance of FilterIntoCSClosure |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
224 // that is iterated over the reference fields of oops in |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
225 // mr (and not the G1ParPushHeapRSClosure - which is the |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
226 // cl parameter). |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
227 // If we set the _ref_processor field in the FilterIntoCSClosure |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
228 // instance, all the reference objects that are walked |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
229 // (regardless of whether their referent object's are in |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
230 // the cset) will be 'discovered'. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
231 // |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
232 // The G1STWIsAlive closure considers a referent object that |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
233 // is outside the cset as alive. The G1CopyingKeepAliveClosure |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
234 // skips referents that are not in the cset. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
235 // |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
236 // Therefore reference objects in mr with a referent that is |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
237 // outside the cset should be OK. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
238 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
239 ReferenceProcessor* rp = _cl->_ref_processor; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
240 if (rp != NULL) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
241 assert(rp == _g1->ref_processor_stw(), "should be stw"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
242 assert(_fk == IntoCSFilterKind, "should be looking for refs into CS"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
243 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
244 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
245 FilterIntoCSClosure intoCSFilt(this, g1h, cl, rp); |
342 | 246 FilterOutOfRegionClosure outOfRegionFilt(_hr, cl); |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
247 |
342 | 248 switch (_fk) { |
249 case IntoCSFilterKind: cl2 = &intoCSFilt; break; | |
250 case OutOfRegionFilterKind: cl2 = &outOfRegionFilt; break; | |
251 } | |
252 | |
253 // Start filtering what we add to the remembered set. If the object is | |
254 // not considered dead, either because it is marked (in the mark bitmap) | |
255 // or it was allocated after marking finished, then we add it. Otherwise | |
256 // we can safely ignore the object. | |
257 if (!g1h->is_obj_dead(oop(bottom), _hr)) { | |
258 oop_size = oop(bottom)->oop_iterate(cl2, mr); | |
259 } else { | |
260 oop_size = oop(bottom)->size(); | |
261 } | |
262 | |
263 bottom += oop_size; | |
264 | |
265 if (bottom < top) { | |
266 // We replicate the loop below for several kinds of possible filters. | |
267 switch (_fk) { | |
268 case NoFilterKind: | |
269 bottom = walk_mem_region_loop(cl, g1h, _hr, bottom, top); | |
270 break; | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
271 |
342 | 272 case IntoCSFilterKind: { |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
273 FilterIntoCSClosure filt(this, g1h, cl, rp); |
342 | 274 bottom = walk_mem_region_loop(&filt, g1h, _hr, bottom, top); |
275 break; | |
276 } | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
277 |
342 | 278 case OutOfRegionFilterKind: { |
279 FilterOutOfRegionClosure filt(_hr, cl); | |
280 bottom = walk_mem_region_loop(&filt, g1h, _hr, bottom, top); | |
281 break; | |
282 } | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
283 |
342 | 284 default: |
285 ShouldNotReachHere(); | |
286 } | |
287 | |
288 // Last object. Need to do dead-obj filtering here too. | |
289 if (!g1h->is_obj_dead(oop(bottom), _hr)) { | |
290 oop(bottom)->oop_iterate(cl2, mr); | |
291 } | |
292 } | |
293 } | |
294 | |
942
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
295 // 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
|
296 // 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
|
297 // heaps a bit more efficiently. |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
298 #define MIN_REGION_SIZE ( 1024 * 1024 ) |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
299 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
300 // 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
|
301 // 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
|
302 // 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
|
303 // 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
|
304 // marking. |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
305 #define MAX_REGION_SIZE ( 32 * 1024 * 1024 ) |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
306 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
307 // 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
|
308 // 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
|
309 #define TARGET_REGION_NUMBER 2048 |
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 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
|
312 // region_size in bytes |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
313 uintx region_size = G1HeapRegionSize; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
314 if (FLAG_IS_DEFAULT(G1HeapRegionSize)) { |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
315 // 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
|
316 // 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
|
317 // 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
|
318 // 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
|
319 // 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
|
320 // size manually for some -Xms / -Xmx combos. |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
321 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
322 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
|
323 (uintx) MIN_REGION_SIZE); |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
324 } |
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 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
|
327 // 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
|
328 // 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
|
329 // <= what we've calculated so far. |
1485
fb57d4cf76c2
6931180: Migration to recent versions of MS Platform SDK
prr
parents:
1394
diff
changeset
|
330 region_size = ((uintx)1 << region_size_log); |
942
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
331 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
332 // 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
|
333 if (region_size < MIN_REGION_SIZE) { |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
334 region_size = MIN_REGION_SIZE; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
335 } else if (region_size > MAX_REGION_SIZE) { |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
336 region_size = MAX_REGION_SIZE; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
337 } |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
338 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
339 // And recalculate the log. |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
340 region_size_log = log2_long((jlong) region_size); |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
341 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
342 // Now, set up the globals. |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
343 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
|
344 LogOfHRGrainBytes = region_size_log; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
345 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
346 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
|
347 LogOfHRGrainWords = LogOfHRGrainBytes - LogHeapWordSize; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
348 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
349 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
|
350 // 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
|
351 // MIN_REGION_SIZE and MAX_REGION_SIZE. |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
352 GrainBytes = (int) region_size; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
353 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
354 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
|
355 GrainWords = GrainBytes >> LogHeapWordSize; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
356 guarantee(1 << LogOfHRGrainWords == GrainWords, "sanity"); |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
357 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
358 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
|
359 CardsPerRegion = GrainBytes >> CardTableModRefBS::card_shift; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
360 } |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
361 |
342 | 362 void HeapRegion::reset_after_compaction() { |
363 G1OffsetTableContigSpace::reset_after_compaction(); | |
364 // After a compaction the mark bitmap is invalid, so we must | |
365 // treat all objects as being inside the unmarked area. | |
366 zero_marked_bytes(); | |
367 init_top_at_mark_start(); | |
368 } | |
369 | |
370 DirtyCardToOopClosure* | |
371 HeapRegion::new_dcto_closure(OopClosure* cl, | |
372 CardTableModRefBS::PrecisionStyle precision, | |
373 HeapRegionDCTOC::FilterKind fk) { | |
374 return new HeapRegionDCTOC(G1CollectedHeap::heap(), | |
375 this, cl, precision, fk); | |
376 } | |
377 | |
378 void HeapRegion::hr_clear(bool par, bool clear_space) { | |
2152 | 379 assert(_humongous_type == NotHumongous, |
380 "we should have already filtered out humongous regions"); | |
381 assert(_humongous_start_region == NULL, | |
382 "we should have already filtered out humongous regions"); | |
383 assert(_end == _orig_end, | |
384 "we should have already filtered out humongous regions"); | |
385 | |
342 | 386 _in_collection_set = false; |
387 | |
388 set_young_index_in_cset(-1); | |
389 uninstall_surv_rate_group(); | |
390 set_young_type(NotYoung); | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2152
diff
changeset
|
391 reset_pre_dummy_top(); |
342 | 392 |
393 if (!par) { | |
394 // If this is parallel, this will be done later. | |
395 HeapRegionRemSet* hrrs = rem_set(); | |
396 if (hrrs != NULL) hrrs->clear(); | |
355 | 397 _claimed = InitialClaimValue; |
342 | 398 } |
399 zero_marked_bytes(); | |
400 set_sort_index(-1); | |
401 | |
402 _offsets.resize(HeapRegion::GrainWords); | |
403 init_top_at_mark_start(); | |
356 | 404 if (clear_space) clear(SpaceDecorator::Mangle); |
342 | 405 } |
406 | |
3317
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
407 void HeapRegion::par_clear() { |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
408 assert(used() == 0, "the region should have been already cleared"); |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
409 assert(capacity() == (size_t) HeapRegion::GrainBytes, |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
410 "should be back to normal"); |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
411 HeapRegionRemSet* hrrs = rem_set(); |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
412 hrrs->clear(); |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
413 CardTableModRefBS* ct_bs = |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
414 (CardTableModRefBS*)G1CollectedHeap::heap()->barrier_set(); |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
415 ct_bs->clear(MemRegion(bottom(), end())); |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
416 } |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
417 |
342 | 418 // <PREDICTION> |
419 void HeapRegion::calc_gc_efficiency() { | |
420 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
421 _gc_efficiency = (double) garbage_bytes() / | |
422 g1h->predict_region_elapsed_time_ms(this, false); | |
423 } | |
424 // </PREDICTION> | |
425 | |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
426 void HeapRegion::set_startsHumongous(HeapWord* new_top, HeapWord* new_end) { |
2152 | 427 assert(!isHumongous(), "sanity / pre-condition"); |
1886
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
428 assert(end() == _orig_end, |
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
429 "Should be normal before the humongous object allocation"); |
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
430 assert(top() == bottom(), "should be empty"); |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
431 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
|
432 |
355 | 433 _humongous_type = StartsHumongous; |
342 | 434 _humongous_start_region = this; |
1886
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
435 |
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
436 set_end(new_end); |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
437 _offsets.set_for_starts_humongous(new_top); |
1886
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
438 } |
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
439 |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
440 void HeapRegion::set_continuesHumongous(HeapRegion* first_hr) { |
2152 | 441 assert(!isHumongous(), "sanity / pre-condition"); |
1886
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
442 assert(end() == _orig_end, |
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
443 "Should be normal before the humongous object allocation"); |
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
444 assert(top() == bottom(), "should be empty"); |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
445 assert(first_hr->startsHumongous(), "pre-condition"); |
1886
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
446 |
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
447 _humongous_type = ContinuesHumongous; |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
448 _humongous_start_region = first_hr; |
342 | 449 } |
450 | |
2152 | 451 void HeapRegion::set_notHumongous() { |
452 assert(isHumongous(), "pre-condition"); | |
453 | |
454 if (startsHumongous()) { | |
455 assert(top() <= end(), "pre-condition"); | |
456 set_end(_orig_end); | |
457 if (top() > end()) { | |
458 // at least one "continues humongous" region after it | |
459 set_top(end()); | |
460 } | |
461 } else { | |
462 // continues humongous | |
463 assert(end() == _orig_end, "sanity"); | |
464 } | |
465 | |
466 assert(capacity() == (size_t) HeapRegion::GrainBytes, "pre-condition"); | |
467 _humongous_type = NotHumongous; | |
468 _humongous_start_region = NULL; | |
469 } | |
470 | |
342 | 471 bool HeapRegion::claimHeapRegion(jint claimValue) { |
472 jint current = _claimed; | |
473 if (current != claimValue) { | |
474 jint res = Atomic::cmpxchg(claimValue, &_claimed, current); | |
475 if (res == current) { | |
476 return true; | |
477 } | |
478 } | |
479 return false; | |
480 } | |
481 | |
482 HeapWord* HeapRegion::next_block_start_careful(HeapWord* addr) { | |
483 HeapWord* low = addr; | |
484 HeapWord* high = end(); | |
485 while (low < high) { | |
486 size_t diff = pointer_delta(high, low); | |
487 // Must add one below to bias toward the high amount. Otherwise, if | |
488 // "high" were at the desired value, and "low" were one less, we | |
489 // would not converge on "high". This is not symmetric, because | |
490 // we set "high" to a block start, which might be the right one, | |
491 // which we don't do for "low". | |
492 HeapWord* middle = low + (diff+1)/2; | |
493 if (middle == high) return high; | |
494 HeapWord* mid_bs = block_start_careful(middle); | |
495 if (mid_bs < addr) { | |
496 low = middle; | |
497 } else { | |
498 high = mid_bs; | |
499 } | |
500 } | |
501 assert(low == high && low >= addr, "Didn't work."); | |
502 return low; | |
503 } | |
504 | |
356 | 505 void HeapRegion::initialize(MemRegion mr, bool clear_space, bool mangle_space) { |
506 G1OffsetTableContigSpace::initialize(mr, false, mangle_space); | |
342 | 507 hr_clear(false/*par*/, clear_space); |
508 } | |
509 #ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away | |
510 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list | |
511 #endif // _MSC_VER | |
512 | |
513 | |
514 HeapRegion:: | |
3766 | 515 HeapRegion(size_t hrs_index, G1BlockOffsetSharedArray* sharedOffsetArray, |
516 MemRegion mr, bool is_zeroed) | |
342 | 517 : G1OffsetTableContigSpace(sharedOffsetArray, mr, is_zeroed), |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
518 _hrs_index(hrs_index), |
355 | 519 _humongous_type(NotHumongous), _humongous_start_region(NULL), |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3772
diff
changeset
|
520 _in_collection_set(false), |
342 | 521 _next_in_special_set(NULL), _orig_end(NULL), |
355 | 522 _claimed(InitialClaimValue), _evacuation_failed(false), |
342 | 523 _prev_marked_bytes(0), _next_marked_bytes(0), _sort_index(-1), |
3978
f0ecbe78fc7b
7092238: G1: Uninitialized field gc_efficiency in G1PrintRegionLivenessInfo output
tonyp
parents:
3830
diff
changeset
|
524 _gc_efficiency(0.0), |
342 | 525 _young_type(NotYoung), _next_young_region(NULL), |
2152 | 526 _next_dirty_cards_region(NULL), _next(NULL), _pending_removal(false), |
527 #ifdef ASSERT | |
528 _containing_set(NULL), | |
529 #endif // ASSERT | |
530 _young_index_in_cset(-1), _surv_rate_group(NULL), _age_index(-1), | |
531 _rem_set(NULL), _recorded_rs_length(0), _predicted_elapsed_time_ms(0), | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1388
diff
changeset
|
532 _predicted_bytes_to_copy(0) |
342 | 533 { |
534 _orig_end = mr.end(); | |
535 // Note that initialize() will set the start of the unmarked area of the | |
536 // region. | |
356 | 537 this->initialize(mr, !is_zeroed, SpaceDecorator::Mangle); |
538 set_top(bottom()); | |
539 set_saved_mark(); | |
342 | 540 |
541 _rem_set = new HeapRegionRemSet(sharedOffsetArray, this); | |
542 | |
543 assert(HeapRegionRemSet::num_par_rem_sets() > 0, "Invariant."); | |
544 // In case the region is allocated during a pause, note the top. | |
545 // We haven't done any counting on a brand new region. | |
546 _top_at_conc_mark_count = bottom(); | |
547 } | |
548 | |
549 class NextCompactionHeapRegionClosure: public HeapRegionClosure { | |
550 const HeapRegion* _target; | |
551 bool _target_seen; | |
552 HeapRegion* _last; | |
553 CompactibleSpace* _res; | |
554 public: | |
555 NextCompactionHeapRegionClosure(const HeapRegion* target) : | |
556 _target(target), _target_seen(false), _res(NULL) {} | |
557 bool doHeapRegion(HeapRegion* cur) { | |
558 if (_target_seen) { | |
559 if (!cur->isHumongous()) { | |
560 _res = cur; | |
561 return true; | |
562 } | |
563 } else if (cur == _target) { | |
564 _target_seen = true; | |
565 } | |
566 return false; | |
567 } | |
568 CompactibleSpace* result() { return _res; } | |
569 }; | |
570 | |
571 CompactibleSpace* HeapRegion::next_compaction_space() const { | |
572 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
573 // cast away const-ness | |
574 HeapRegion* r = (HeapRegion*) this; | |
575 NextCompactionHeapRegionClosure blk(r); | |
576 g1h->heap_region_iterate_from(r, &blk); | |
577 return blk.result(); | |
578 } | |
579 | |
580 void HeapRegion::save_marks() { | |
581 set_saved_mark(); | |
582 } | |
583 | |
584 void HeapRegion::oops_in_mr_iterate(MemRegion mr, OopClosure* cl) { | |
585 HeapWord* p = mr.start(); | |
586 HeapWord* e = mr.end(); | |
587 oop obj; | |
588 while (p < e) { | |
589 obj = oop(p); | |
590 p += obj->oop_iterate(cl); | |
591 } | |
592 assert(p == e, "bad memregion: doesn't end on obj boundary"); | |
593 } | |
594 | |
595 #define HeapRegion_OOP_SINCE_SAVE_MARKS_DEFN(OopClosureType, nv_suffix) \ | |
596 void HeapRegion::oop_since_save_marks_iterate##nv_suffix(OopClosureType* cl) { \ | |
597 ContiguousSpace::oop_since_save_marks_iterate##nv_suffix(cl); \ | |
598 } | |
599 SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(HeapRegion_OOP_SINCE_SAVE_MARKS_DEFN) | |
600 | |
601 | |
602 void HeapRegion::oop_before_save_marks_iterate(OopClosure* cl) { | |
603 oops_in_mr_iterate(MemRegion(bottom(), saved_mark_word()), cl); | |
604 } | |
605 | |
606 HeapWord* | |
607 HeapRegion::object_iterate_mem_careful(MemRegion mr, | |
608 ObjectClosure* cl) { | |
609 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
610 // We used to use "block_start_careful" here. But we're actually happy | |
611 // to update the BOT while we do this... | |
612 HeapWord* cur = block_start(mr.start()); | |
613 mr = mr.intersection(used_region()); | |
614 if (mr.is_empty()) return NULL; | |
615 // Otherwise, find the obj that extends onto mr.start(). | |
616 | |
617 assert(cur <= mr.start() | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
618 && (oop(cur)->klass_or_null() == NULL || |
342 | 619 cur + oop(cur)->size() > mr.start()), |
620 "postcondition of block_start"); | |
621 oop obj; | |
622 while (cur < mr.end()) { | |
623 obj = oop(cur); | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
624 if (obj->klass_or_null() == NULL) { |
342 | 625 // Ran into an unparseable point. |
626 return cur; | |
627 } else if (!g1h->is_obj_dead(obj)) { | |
628 cl->do_object(obj); | |
629 } | |
630 if (cl->abort()) return cur; | |
631 // The check above must occur before the operation below, since an | |
632 // abort might invalidate the "size" operation. | |
633 cur += obj->size(); | |
634 } | |
635 return NULL; | |
636 } | |
637 | |
638 HeapWord* | |
639 HeapRegion:: | |
640 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
|
641 FilterOutOfRegionClosure* cl, |
3317
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
642 bool filter_young, |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
643 jbyte* card_ptr) { |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
644 // Currently, we should only have to clean the card if filter_young |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
645 // is true and vice versa. |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
646 if (filter_young) { |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
647 assert(card_ptr != NULL, "pre-condition"); |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
648 } else { |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
649 assert(card_ptr == NULL, "pre-condition"); |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
650 } |
342 | 651 G1CollectedHeap* g1h = G1CollectedHeap::heap(); |
652 | |
653 // If we're within a stop-world GC, then we might look at a card in a | |
654 // GC alloc region that extends onto a GC LAB, which may not be | |
655 // parseable. Stop such at the "saved_mark" of the region. | |
656 if (G1CollectedHeap::heap()->is_gc_active()) { | |
657 mr = mr.intersection(used_region_at_save_marks()); | |
658 } else { | |
659 mr = mr.intersection(used_region()); | |
660 } | |
661 if (mr.is_empty()) return NULL; | |
662 // Otherwise, find the obj that extends onto mr.start(). | |
663 | |
1666
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
664 // 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
|
665 // 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
|
666 // 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
|
667 // 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
|
668 // 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
|
669 // 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
|
670 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
|
671 return NULL; |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
672 } |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
673 |
1705 | 674 assert(!is_young(), "check value of filter_young"); |
675 | |
3317
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
676 // We can only clean the card here, after we make the decision that |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
677 // the card is not young. And we only clean the card if we have been |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
678 // asked to (i.e., card_ptr != NULL). |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
679 if (card_ptr != NULL) { |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
680 *card_ptr = CardTableModRefBS::clean_card_val(); |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
681 // We must complete this write before we do any of the reads below. |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
682 OrderAccess::storeload(); |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
683 } |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
684 |
342 | 685 // We used to use "block_start_careful" here. But we're actually happy |
686 // to update the BOT while we do this... | |
687 HeapWord* cur = block_start(mr.start()); | |
688 assert(cur <= mr.start(), "Postcondition"); | |
689 | |
690 while (cur <= mr.start()) { | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
691 if (oop(cur)->klass_or_null() == NULL) { |
342 | 692 // Ran into an unparseable point. |
693 return cur; | |
694 } | |
695 // Otherwise... | |
696 int sz = oop(cur)->size(); | |
697 if (cur + sz > mr.start()) break; | |
698 // Otherwise, go on. | |
699 cur = cur + sz; | |
700 } | |
701 oop obj; | |
702 obj = oop(cur); | |
703 // If we finish this loop... | |
704 assert(cur <= mr.start() | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
705 && obj->klass_or_null() != NULL |
342 | 706 && cur + obj->size() > mr.start(), |
707 "Loop postcondition"); | |
708 if (!g1h->is_obj_dead(obj)) { | |
709 obj->oop_iterate(cl, mr); | |
710 } | |
711 | |
712 HeapWord* next; | |
713 while (cur < mr.end()) { | |
714 obj = oop(cur); | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
715 if (obj->klass_or_null() == NULL) { |
342 | 716 // Ran into an unparseable point. |
717 return cur; | |
718 }; | |
719 // Otherwise: | |
720 next = (cur + obj->size()); | |
721 if (!g1h->is_obj_dead(obj)) { | |
722 if (next < mr.end()) { | |
723 obj->oop_iterate(cl); | |
724 } else { | |
725 // this obj spans the boundary. If it's an array, stop at the | |
726 // boundary. | |
727 if (obj->is_objArray()) { | |
728 obj->oop_iterate(cl, mr); | |
729 } else { | |
730 obj->oop_iterate(cl); | |
731 } | |
732 } | |
733 } | |
734 cur = next; | |
735 } | |
736 return NULL; | |
737 } | |
738 | |
739 void HeapRegion::print() const { print_on(gclog_or_tty); } | |
740 void HeapRegion::print_on(outputStream* st) const { | |
741 if (isHumongous()) { | |
742 if (startsHumongous()) | |
743 st->print(" HS"); | |
744 else | |
745 st->print(" HC"); | |
746 } else { | |
747 st->print(" "); | |
748 } | |
749 if (in_collection_set()) | |
750 st->print(" CS"); | |
751 else | |
752 st->print(" "); | |
753 if (is_young()) | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1388
diff
changeset
|
754 st->print(is_survivor() ? " SU" : " Y "); |
342 | 755 else |
756 st->print(" "); | |
757 if (is_empty()) | |
758 st->print(" F"); | |
759 else | |
760 st->print(" "); | |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
761 st->print(" %5d", _gc_time_stamp); |
1388 | 762 st->print(" PTAMS "PTR_FORMAT" NTAMS "PTR_FORMAT, |
763 prev_top_at_mark_start(), next_top_at_mark_start()); | |
342 | 764 G1OffsetTableContigSpace::print_on(st); |
765 } | |
766 | |
811 | 767 void HeapRegion::verify(bool allow_dirty) const { |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
768 bool dummy = false; |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
769 verify(allow_dirty, VerifyOption_G1UsePrevMarking, /* failures */ &dummy); |
811 | 770 } |
771 | |
342 | 772 // This really ought to be commoned up into OffsetTableContigSpace somehow. |
773 // We would need a mechanism to make that code skip dead objects. | |
774 | |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
775 void HeapRegion::verify(bool allow_dirty, |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
776 VerifyOption vo, |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
777 bool* failures) const { |
342 | 778 G1CollectedHeap* g1 = G1CollectedHeap::heap(); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
779 *failures = false; |
342 | 780 HeapWord* p = bottom(); |
781 HeapWord* prev_p = NULL; | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
782 VerifyLiveClosure vl_cl(g1, vo); |
1718
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
783 bool is_humongous = isHumongous(); |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
784 bool do_bot_verify = !is_young(); |
1718
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
785 size_t object_num = 0; |
342 | 786 while (p < top()) { |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
787 oop obj = oop(p); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
788 size_t obj_size = obj->size(); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
789 object_num += 1; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
790 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
791 if (is_humongous != g1->isHumongous(obj_size)) { |
1718
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
792 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
|
793 SIZE_FORMAT" words) in a %shumongous region", |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
794 p, g1->isHumongous(obj_size) ? "" : "non-", |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
795 obj_size, is_humongous ? "" : "non-"); |
1718
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
796 *failures = true; |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
797 return; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
798 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
799 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
800 // 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
|
801 // appropriate messasge. |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
802 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
|
803 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
804 return; |
1718
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
805 } |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
806 |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
807 if (!g1->is_obj_dead_cond(obj, this, vo)) { |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
808 if (obj->is_oop()) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
809 klassOop klass = obj->klass(); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
810 if (!klass->is_perm()) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
811 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
|
812 "not in perm", klass, obj); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
813 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
814 return; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
815 } else if (!klass->is_klass()) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
816 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
|
817 "not a klass", klass, obj); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
818 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
819 return; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
820 } else { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
821 vl_cl.set_containing_obj(obj); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
822 obj->oop_iterate(&vl_cl); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
823 if (vl_cl.failures()) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
824 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
825 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
826 if (G1MaxVerifyFailures >= 0 && |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
827 vl_cl.n_failures() >= G1MaxVerifyFailures) { |
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 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
830 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
831 } else { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
832 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
|
833 *failures = true; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
834 return; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
835 } |
342 | 836 } |
837 prev_p = p; | |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
838 p += obj_size; |
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 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
841 if (p != top()) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
842 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
|
843 "does not match top "PTR_FORMAT, p, top()); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
844 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
845 return; |
342 | 846 } |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
847 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
848 HeapWord* the_end = end(); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
849 assert(p == top(), "it should still hold"); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
850 // 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
|
851 // 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
|
852 // 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
|
853 if (p < the_end) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
854 // Look up top |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
855 HeapWord* addr_1 = p; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
856 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
|
857 if (b_start_1 != p) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
858 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
|
859 " yielded "PTR_FORMAT", expecting "PTR_FORMAT, |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
860 addr_1, b_start_1, p); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
861 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
862 return; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
863 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
864 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
865 // Look up top + 1 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
866 HeapWord* addr_2 = p + 1; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
867 if (addr_2 < the_end) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
868 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
|
869 if (b_start_2 != p) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
870 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
|
871 " yielded "PTR_FORMAT", expecting "PTR_FORMAT, |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
872 addr_2, b_start_2, p); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
873 *failures = true; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
874 return; |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
875 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
876 } |
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 // Look up an address between top and end |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
879 size_t diff = pointer_delta(the_end, p) / 2; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
880 HeapWord* addr_3 = p + diff; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
881 if (addr_3 < the_end) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
882 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
|
883 if (b_start_3 != 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 + diff: "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_3, b_start_3, p); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
887 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
888 return; |
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 // Loook up end - 1 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
893 HeapWord* addr_4 = the_end - 1; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
894 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
|
895 if (b_start_4 != p) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
896 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
|
897 " yielded "PTR_FORMAT", expecting "PTR_FORMAT, |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
898 addr_4, b_start_4, p); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
899 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
900 return; |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
901 } |
342 | 902 } |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
903 |
1718
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
904 if (is_humongous && object_num > 1) { |
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
905 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
|
906 "but has "SIZE_FORMAT", objects", |
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
907 bottom(), end(), object_num); |
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
908 *failures = true; |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
909 return; |
342 | 910 } |
911 } | |
912 | |
913 // G1OffsetTableContigSpace code; copied from space.cpp. Hope this can go | |
914 // away eventually. | |
915 | |
356 | 916 void G1OffsetTableContigSpace::initialize(MemRegion mr, bool clear_space, bool mangle_space) { |
342 | 917 // false ==> we'll do the clearing if there's clearing to be done. |
356 | 918 ContiguousSpace::initialize(mr, false, mangle_space); |
342 | 919 _offsets.zero_bottom_entry(); |
920 _offsets.initialize_threshold(); | |
356 | 921 if (clear_space) clear(mangle_space); |
342 | 922 } |
923 | |
356 | 924 void G1OffsetTableContigSpace::clear(bool mangle_space) { |
925 ContiguousSpace::clear(mangle_space); | |
342 | 926 _offsets.zero_bottom_entry(); |
927 _offsets.initialize_threshold(); | |
928 } | |
929 | |
930 void G1OffsetTableContigSpace::set_bottom(HeapWord* new_bottom) { | |
931 Space::set_bottom(new_bottom); | |
932 _offsets.set_bottom(new_bottom); | |
933 } | |
934 | |
935 void G1OffsetTableContigSpace::set_end(HeapWord* new_end) { | |
936 Space::set_end(new_end); | |
937 _offsets.resize(new_end - bottom()); | |
938 } | |
939 | |
940 void G1OffsetTableContigSpace::print() const { | |
941 print_short(); | |
942 gclog_or_tty->print_cr(" [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " | |
943 INTPTR_FORMAT ", " INTPTR_FORMAT ")", | |
944 bottom(), top(), _offsets.threshold(), end()); | |
945 } | |
946 | |
947 HeapWord* G1OffsetTableContigSpace::initialize_threshold() { | |
948 return _offsets.initialize_threshold(); | |
949 } | |
950 | |
951 HeapWord* G1OffsetTableContigSpace::cross_threshold(HeapWord* start, | |
952 HeapWord* end) { | |
953 _offsets.alloc_block(start, end); | |
954 return _offsets.threshold(); | |
955 } | |
956 | |
957 HeapWord* G1OffsetTableContigSpace::saved_mark_word() const { | |
958 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
959 assert( _gc_time_stamp <= g1h->get_gc_time_stamp(), "invariant" ); | |
960 if (_gc_time_stamp < g1h->get_gc_time_stamp()) | |
961 return top(); | |
962 else | |
963 return ContiguousSpace::saved_mark_word(); | |
964 } | |
965 | |
966 void G1OffsetTableContigSpace::set_saved_mark() { | |
967 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
968 unsigned curr_gc_time_stamp = g1h->get_gc_time_stamp(); | |
969 | |
970 if (_gc_time_stamp < curr_gc_time_stamp) { | |
971 // The order of these is important, as another thread might be | |
972 // about to start scanning this region. If it does so after | |
973 // set_saved_mark and before _gc_time_stamp = ..., then the latter | |
974 // will be false, and it will pick up top() as the high water mark | |
975 // of region. If it does so after _gc_time_stamp = ..., then it | |
976 // will pick up the right saved_mark_word() as the high water mark | |
977 // of the region. Either way, the behaviour will be correct. | |
978 ContiguousSpace::set_saved_mark(); | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
979 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
|
980 _gc_time_stamp = curr_gc_time_stamp; |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2152
diff
changeset
|
981 // No need to do another barrier to flush the writes above. If |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2152
diff
changeset
|
982 // this is called in parallel with other threads trying to |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2152
diff
changeset
|
983 // allocate into the region, the caller should call this while |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2152
diff
changeset
|
984 // holding a lock and when the lock is released the writes will be |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2152
diff
changeset
|
985 // flushed. |
342 | 986 } |
987 } | |
988 | |
989 G1OffsetTableContigSpace:: | |
990 G1OffsetTableContigSpace(G1BlockOffsetSharedArray* sharedOffsetArray, | |
991 MemRegion mr, bool is_zeroed) : | |
992 _offsets(sharedOffsetArray, mr), | |
993 _par_alloc_lock(Mutex::leaf, "OffsetTableContigSpace par alloc lock", true), | |
994 _gc_time_stamp(0) | |
995 { | |
996 _offsets.set_space(this); | |
356 | 997 initialize(mr, !is_zeroed, SpaceDecorator::Mangle); |
342 | 998 } |