Mercurial > hg > graal-jvmci-8
annotate src/share/vm/gc_implementation/g1/heapRegion.cpp @ 3285:49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
Summary: It introduces non-product cmd line parameter G1DummyRegionsPerGC which indicates how many "dummy" regions to allocate at the end of each GC. This allows the G1 heap to grow artificially and makes concurrent marking cycles more frequent irrespective of what the application that is running is doing. The dummy regions will be found totally empty during cleanup so this parameter can also be used to stress the concurrent cleanup operation.
Reviewed-by: brutisso, johnc
author | tonyp |
---|---|
date | Tue, 19 Apr 2011 15:46:59 -0400 |
parents | abdfc822206f |
children | 0654ee04b214 063382f9b575 |
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) | |
48 {} | |
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; | |
811 | 63 bool _use_prev_marking; |
342 | 64 public: |
811 | 65 // use_prev_marking == true -> use "prev" marking information, |
66 // use_prev_marking == false -> use "next" marking information | |
67 VerifyLiveClosure(G1CollectedHeap* g1h, bool use_prev_marking) : | |
342 | 68 _g1h(g1h), _bs(NULL), _containing_obj(NULL), |
811 | 69 _failures(false), _n_failures(0), _use_prev_marking(use_prev_marking) |
342 | 70 { |
71 BarrierSet* bs = _g1h->barrier_set(); | |
72 if (bs->is_a(BarrierSet::CardTableModRef)) | |
73 _bs = (CardTableModRefBS*)bs; | |
74 } | |
75 | |
76 void set_containing_obj(oop obj) { | |
77 _containing_obj = obj; | |
78 } | |
79 | |
80 bool failures() { return _failures; } | |
81 int n_failures() { return _n_failures; } | |
82 | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
83 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
|
84 virtual void do_oop( oop* p) { do_oop_work(p); } |
342 | 85 |
1388 | 86 void print_object(outputStream* out, oop obj) { |
87 #ifdef PRODUCT | |
88 klassOop k = obj->klass(); | |
89 const char* class_name = instanceKlass::cast(k)->external_name(); | |
90 out->print_cr("class name %s", class_name); | |
91 #else // PRODUCT | |
92 obj->print_on(out); | |
93 #endif // PRODUCT | |
94 } | |
95 | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
96 template <class T> void do_oop_work(T* p) { |
342 | 97 assert(_containing_obj != NULL, "Precondition"); |
811 | 98 assert(!_g1h->is_obj_dead_cond(_containing_obj, _use_prev_marking), |
99 "Precondition"); | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
100 T heap_oop = oopDesc::load_heap_oop(p); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
101 if (!oopDesc::is_null(heap_oop)) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
102 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); |
342 | 103 bool failed = false; |
811 | 104 if (!_g1h->is_in_closed_subset(obj) || |
105 _g1h->is_obj_dead_cond(obj, _use_prev_marking)) { | |
342 | 106 if (!_failures) { |
107 gclog_or_tty->print_cr(""); | |
108 gclog_or_tty->print_cr("----------"); | |
109 } | |
110 if (!_g1h->is_in_closed_subset(obj)) { | |
1388 | 111 HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p); |
342 | 112 gclog_or_tty->print_cr("Field "PTR_FORMAT |
1388 | 113 " of live obj "PTR_FORMAT" in region " |
114 "["PTR_FORMAT", "PTR_FORMAT")", | |
115 p, (void*) _containing_obj, | |
116 from->bottom(), from->end()); | |
117 print_object(gclog_or_tty, _containing_obj); | |
118 gclog_or_tty->print_cr("points to obj "PTR_FORMAT" not in the heap", | |
119 (void*) obj); | |
120 } else { | |
121 HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p); | |
122 HeapRegion* to = _g1h->heap_region_containing((HeapWord*)obj); | |
123 gclog_or_tty->print_cr("Field "PTR_FORMAT | |
124 " of live obj "PTR_FORMAT" in region " | |
125 "["PTR_FORMAT", "PTR_FORMAT")", | |
126 p, (void*) _containing_obj, | |
127 from->bottom(), from->end()); | |
128 print_object(gclog_or_tty, _containing_obj); | |
129 gclog_or_tty->print_cr("points to dead obj "PTR_FORMAT" in region " | |
130 "["PTR_FORMAT", "PTR_FORMAT")", | |
131 (void*) obj, to->bottom(), to->end()); | |
132 print_object(gclog_or_tty, obj); | |
342 | 133 } |
134 gclog_or_tty->print_cr("----------"); | |
135 _failures = true; | |
136 failed = true; | |
137 _n_failures++; | |
138 } | |
139 | |
140 if (!_g1h->full_collection()) { | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
141 HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
142 HeapRegion* to = _g1h->heap_region_containing(obj); |
342 | 143 if (from != NULL && to != NULL && |
144 from != to && | |
145 !to->isHumongous()) { | |
146 jbyte cv_obj = *_bs->byte_for_const(_containing_obj); | |
147 jbyte cv_field = *_bs->byte_for_const(p); | |
148 const jbyte dirty = CardTableModRefBS::dirty_card_val(); | |
149 | |
150 bool is_bad = !(from->is_young() | |
151 || to->rem_set()->contains_reference(p) | |
152 || !G1HRRSFlushLogBuffersOnVerify && // buffers were not flushed | |
153 (_containing_obj->is_objArray() ? | |
154 cv_field == dirty | |
155 : cv_obj == dirty || cv_field == dirty)); | |
156 if (is_bad) { | |
157 if (!_failures) { | |
158 gclog_or_tty->print_cr(""); | |
159 gclog_or_tty->print_cr("----------"); | |
160 } | |
161 gclog_or_tty->print_cr("Missing rem set entry:"); | |
162 gclog_or_tty->print_cr("Field "PTR_FORMAT | |
163 " of obj "PTR_FORMAT | |
164 ", in region %d ["PTR_FORMAT | |
165 ", "PTR_FORMAT"),", | |
166 p, (void*) _containing_obj, | |
167 from->hrs_index(), | |
168 from->bottom(), | |
169 from->end()); | |
170 _containing_obj->print_on(gclog_or_tty); | |
171 gclog_or_tty->print_cr("points to obj "PTR_FORMAT | |
172 " in region %d ["PTR_FORMAT | |
173 ", "PTR_FORMAT").", | |
174 (void*) obj, to->hrs_index(), | |
175 to->bottom(), to->end()); | |
176 obj->print_on(gclog_or_tty); | |
177 gclog_or_tty->print_cr("Obj head CTE = %d, field CTE = %d.", | |
178 cv_obj, cv_field); | |
179 gclog_or_tty->print_cr("----------"); | |
180 _failures = true; | |
181 if (!failed) _n_failures++; | |
182 } | |
183 } | |
184 } | |
185 } | |
186 } | |
187 }; | |
188 | |
189 template<class ClosureType> | |
190 HeapWord* walk_mem_region_loop(ClosureType* cl, G1CollectedHeap* g1h, | |
191 HeapRegion* hr, | |
192 HeapWord* cur, HeapWord* top) { | |
193 oop cur_oop = oop(cur); | |
194 int oop_size = cur_oop->size(); | |
195 HeapWord* next_obj = cur + oop_size; | |
196 while (next_obj < top) { | |
197 // Keep filtering the remembered set. | |
198 if (!g1h->is_obj_dead(cur_oop, hr)) { | |
199 // Bottom lies entirely below top, so we can call the | |
200 // non-memRegion version of oop_iterate below. | |
201 cur_oop->oop_iterate(cl); | |
202 } | |
203 cur = next_obj; | |
204 cur_oop = oop(cur); | |
205 oop_size = cur_oop->size(); | |
206 next_obj = cur + oop_size; | |
207 } | |
208 return cur; | |
209 } | |
210 | |
211 void HeapRegionDCTOC::walk_mem_region_with_cl(MemRegion mr, | |
212 HeapWord* bottom, | |
213 HeapWord* top, | |
214 OopClosure* cl) { | |
215 G1CollectedHeap* g1h = _g1; | |
216 | |
217 int oop_size; | |
218 | |
219 OopClosure* cl2 = cl; | |
220 FilterIntoCSClosure intoCSFilt(this, g1h, cl); | |
221 FilterOutOfRegionClosure outOfRegionFilt(_hr, cl); | |
222 switch (_fk) { | |
223 case IntoCSFilterKind: cl2 = &intoCSFilt; break; | |
224 case OutOfRegionFilterKind: cl2 = &outOfRegionFilt; break; | |
225 } | |
226 | |
227 // Start filtering what we add to the remembered set. If the object is | |
228 // not considered dead, either because it is marked (in the mark bitmap) | |
229 // or it was allocated after marking finished, then we add it. Otherwise | |
230 // we can safely ignore the object. | |
231 if (!g1h->is_obj_dead(oop(bottom), _hr)) { | |
232 oop_size = oop(bottom)->oop_iterate(cl2, mr); | |
233 } else { | |
234 oop_size = oop(bottom)->size(); | |
235 } | |
236 | |
237 bottom += oop_size; | |
238 | |
239 if (bottom < top) { | |
240 // We replicate the loop below for several kinds of possible filters. | |
241 switch (_fk) { | |
242 case NoFilterKind: | |
243 bottom = walk_mem_region_loop(cl, g1h, _hr, bottom, top); | |
244 break; | |
245 case IntoCSFilterKind: { | |
246 FilterIntoCSClosure filt(this, g1h, cl); | |
247 bottom = walk_mem_region_loop(&filt, g1h, _hr, bottom, top); | |
248 break; | |
249 } | |
250 case OutOfRegionFilterKind: { | |
251 FilterOutOfRegionClosure filt(_hr, cl); | |
252 bottom = walk_mem_region_loop(&filt, g1h, _hr, bottom, top); | |
253 break; | |
254 } | |
255 default: | |
256 ShouldNotReachHere(); | |
257 } | |
258 | |
259 // Last object. Need to do dead-obj filtering here too. | |
260 if (!g1h->is_obj_dead(oop(bottom), _hr)) { | |
261 oop(bottom)->oop_iterate(cl2, mr); | |
262 } | |
263 } | |
264 } | |
265 | |
942
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
266 // 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
|
267 // 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
|
268 // heaps a bit more efficiently. |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
269 #define MIN_REGION_SIZE ( 1024 * 1024 ) |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
270 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
271 // 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
|
272 // 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
|
273 // 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
|
274 // 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
|
275 // marking. |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
276 #define MAX_REGION_SIZE ( 32 * 1024 * 1024 ) |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
277 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
278 // 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
|
279 // 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
|
280 #define TARGET_REGION_NUMBER 2048 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
281 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
282 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
|
283 // region_size in bytes |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
284 uintx region_size = G1HeapRegionSize; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
285 if (FLAG_IS_DEFAULT(G1HeapRegionSize)) { |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
286 // 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
|
287 // 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
|
288 // 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
|
289 // 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
|
290 // 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
|
291 // size manually for some -Xms / -Xmx combos. |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
292 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
293 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
|
294 (uintx) MIN_REGION_SIZE); |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
295 } |
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 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
|
298 // 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
|
299 // 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
|
300 // <= what we've calculated so far. |
1485
fb57d4cf76c2
6931180: Migration to recent versions of MS Platform SDK
prr
parents:
1394
diff
changeset
|
301 region_size = ((uintx)1 << region_size_log); |
942
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
302 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
303 // 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
|
304 if (region_size < MIN_REGION_SIZE) { |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
305 region_size = MIN_REGION_SIZE; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
306 } else if (region_size > MAX_REGION_SIZE) { |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
307 region_size = MAX_REGION_SIZE; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
308 } |
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 // And recalculate the log. |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
311 region_size_log = log2_long((jlong) region_size); |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
312 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
313 // Now, set up the globals. |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
314 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
|
315 LogOfHRGrainBytes = region_size_log; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
316 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
317 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
|
318 LogOfHRGrainWords = LogOfHRGrainBytes - LogHeapWordSize; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
319 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
320 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
|
321 // 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
|
322 // MIN_REGION_SIZE and MAX_REGION_SIZE. |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
323 GrainBytes = (int) 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 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
|
326 GrainWords = GrainBytes >> LogHeapWordSize; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
327 guarantee(1 << LogOfHRGrainWords == GrainWords, "sanity"); |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
328 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
329 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
|
330 CardsPerRegion = GrainBytes >> CardTableModRefBS::card_shift; |
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 |
342 | 333 void HeapRegion::reset_after_compaction() { |
334 G1OffsetTableContigSpace::reset_after_compaction(); | |
335 // After a compaction the mark bitmap is invalid, so we must | |
336 // treat all objects as being inside the unmarked area. | |
337 zero_marked_bytes(); | |
338 init_top_at_mark_start(); | |
339 } | |
340 | |
341 DirtyCardToOopClosure* | |
342 HeapRegion::new_dcto_closure(OopClosure* cl, | |
343 CardTableModRefBS::PrecisionStyle precision, | |
344 HeapRegionDCTOC::FilterKind fk) { | |
345 return new HeapRegionDCTOC(G1CollectedHeap::heap(), | |
346 this, cl, precision, fk); | |
347 } | |
348 | |
349 void HeapRegion::hr_clear(bool par, bool clear_space) { | |
2152 | 350 assert(_humongous_type == NotHumongous, |
351 "we should have already filtered out humongous regions"); | |
352 assert(_humongous_start_region == NULL, | |
353 "we should have already filtered out humongous regions"); | |
354 assert(_end == _orig_end, | |
355 "we should have already filtered out humongous regions"); | |
356 | |
342 | 357 _in_collection_set = false; |
358 _is_gc_alloc_region = false; | |
359 | |
360 set_young_index_in_cset(-1); | |
361 uninstall_surv_rate_group(); | |
362 set_young_type(NotYoung); | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2152
diff
changeset
|
363 reset_pre_dummy_top(); |
342 | 364 |
365 if (!par) { | |
366 // If this is parallel, this will be done later. | |
367 HeapRegionRemSet* hrrs = rem_set(); | |
368 if (hrrs != NULL) hrrs->clear(); | |
355 | 369 _claimed = InitialClaimValue; |
342 | 370 } |
371 zero_marked_bytes(); | |
372 set_sort_index(-1); | |
373 | |
374 _offsets.resize(HeapRegion::GrainWords); | |
375 init_top_at_mark_start(); | |
356 | 376 if (clear_space) clear(SpaceDecorator::Mangle); |
342 | 377 } |
378 | |
379 // <PREDICTION> | |
380 void HeapRegion::calc_gc_efficiency() { | |
381 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
382 _gc_efficiency = (double) garbage_bytes() / | |
383 g1h->predict_region_elapsed_time_ms(this, false); | |
384 } | |
385 // </PREDICTION> | |
386 | |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
387 void HeapRegion::set_startsHumongous(HeapWord* new_top, HeapWord* new_end) { |
2152 | 388 assert(!isHumongous(), "sanity / pre-condition"); |
1886
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
389 assert(end() == _orig_end, |
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
390 "Should be normal before the humongous object allocation"); |
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
391 assert(top() == bottom(), "should be empty"); |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
392 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
|
393 |
355 | 394 _humongous_type = StartsHumongous; |
342 | 395 _humongous_start_region = this; |
1886
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
396 |
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
397 set_end(new_end); |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
398 _offsets.set_for_starts_humongous(new_top); |
1886
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
399 } |
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
400 |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
401 void HeapRegion::set_continuesHumongous(HeapRegion* first_hr) { |
2152 | 402 assert(!isHumongous(), "sanity / pre-condition"); |
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 | |
2152 | 412 void HeapRegion::set_notHumongous() { |
413 assert(isHumongous(), "pre-condition"); | |
414 | |
415 if (startsHumongous()) { | |
416 assert(top() <= end(), "pre-condition"); | |
417 set_end(_orig_end); | |
418 if (top() > end()) { | |
419 // at least one "continues humongous" region after it | |
420 set_top(end()); | |
421 } | |
422 } else { | |
423 // continues humongous | |
424 assert(end() == _orig_end, "sanity"); | |
425 } | |
426 | |
427 assert(capacity() == (size_t) HeapRegion::GrainBytes, "pre-condition"); | |
428 _humongous_type = NotHumongous; | |
429 _humongous_start_region = NULL; | |
430 } | |
431 | |
342 | 432 bool HeapRegion::claimHeapRegion(jint claimValue) { |
433 jint current = _claimed; | |
434 if (current != claimValue) { | |
435 jint res = Atomic::cmpxchg(claimValue, &_claimed, current); | |
436 if (res == current) { | |
437 return true; | |
438 } | |
439 } | |
440 return false; | |
441 } | |
442 | |
443 HeapWord* HeapRegion::next_block_start_careful(HeapWord* addr) { | |
444 HeapWord* low = addr; | |
445 HeapWord* high = end(); | |
446 while (low < high) { | |
447 size_t diff = pointer_delta(high, low); | |
448 // Must add one below to bias toward the high amount. Otherwise, if | |
449 // "high" were at the desired value, and "low" were one less, we | |
450 // would not converge on "high". This is not symmetric, because | |
451 // we set "high" to a block start, which might be the right one, | |
452 // which we don't do for "low". | |
453 HeapWord* middle = low + (diff+1)/2; | |
454 if (middle == high) return high; | |
455 HeapWord* mid_bs = block_start_careful(middle); | |
456 if (mid_bs < addr) { | |
457 low = middle; | |
458 } else { | |
459 high = mid_bs; | |
460 } | |
461 } | |
462 assert(low == high && low >= addr, "Didn't work."); | |
463 return low; | |
464 } | |
465 | |
356 | 466 void HeapRegion::initialize(MemRegion mr, bool clear_space, bool mangle_space) { |
467 G1OffsetTableContigSpace::initialize(mr, false, mangle_space); | |
342 | 468 hr_clear(false/*par*/, clear_space); |
469 } | |
470 #ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away | |
471 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list | |
472 #endif // _MSC_VER | |
473 | |
474 | |
475 HeapRegion:: | |
476 HeapRegion(G1BlockOffsetSharedArray* sharedOffsetArray, | |
477 MemRegion mr, bool is_zeroed) | |
478 : G1OffsetTableContigSpace(sharedOffsetArray, mr, is_zeroed), | |
479 _next_fk(HeapRegionDCTOC::NoFilterKind), | |
480 _hrs_index(-1), | |
355 | 481 _humongous_type(NotHumongous), _humongous_start_region(NULL), |
342 | 482 _in_collection_set(false), _is_gc_alloc_region(false), |
483 _next_in_special_set(NULL), _orig_end(NULL), | |
355 | 484 _claimed(InitialClaimValue), _evacuation_failed(false), |
342 | 485 _prev_marked_bytes(0), _next_marked_bytes(0), _sort_index(-1), |
486 _young_type(NotYoung), _next_young_region(NULL), | |
2152 | 487 _next_dirty_cards_region(NULL), _next(NULL), _pending_removal(false), |
488 #ifdef ASSERT | |
489 _containing_set(NULL), | |
490 #endif // ASSERT | |
491 _young_index_in_cset(-1), _surv_rate_group(NULL), _age_index(-1), | |
492 _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
|
493 _predicted_bytes_to_copy(0) |
342 | 494 { |
495 _orig_end = mr.end(); | |
496 // Note that initialize() will set the start of the unmarked area of the | |
497 // region. | |
356 | 498 this->initialize(mr, !is_zeroed, SpaceDecorator::Mangle); |
499 set_top(bottom()); | |
500 set_saved_mark(); | |
342 | 501 |
502 _rem_set = new HeapRegionRemSet(sharedOffsetArray, this); | |
503 | |
504 assert(HeapRegionRemSet::num_par_rem_sets() > 0, "Invariant."); | |
505 // In case the region is allocated during a pause, note the top. | |
506 // We haven't done any counting on a brand new region. | |
507 _top_at_conc_mark_count = bottom(); | |
508 } | |
509 | |
510 class NextCompactionHeapRegionClosure: public HeapRegionClosure { | |
511 const HeapRegion* _target; | |
512 bool _target_seen; | |
513 HeapRegion* _last; | |
514 CompactibleSpace* _res; | |
515 public: | |
516 NextCompactionHeapRegionClosure(const HeapRegion* target) : | |
517 _target(target), _target_seen(false), _res(NULL) {} | |
518 bool doHeapRegion(HeapRegion* cur) { | |
519 if (_target_seen) { | |
520 if (!cur->isHumongous()) { | |
521 _res = cur; | |
522 return true; | |
523 } | |
524 } else if (cur == _target) { | |
525 _target_seen = true; | |
526 } | |
527 return false; | |
528 } | |
529 CompactibleSpace* result() { return _res; } | |
530 }; | |
531 | |
532 CompactibleSpace* HeapRegion::next_compaction_space() const { | |
533 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
534 // cast away const-ness | |
535 HeapRegion* r = (HeapRegion*) this; | |
536 NextCompactionHeapRegionClosure blk(r); | |
537 g1h->heap_region_iterate_from(r, &blk); | |
538 return blk.result(); | |
539 } | |
540 | |
541 void HeapRegion::save_marks() { | |
542 set_saved_mark(); | |
543 } | |
544 | |
545 void HeapRegion::oops_in_mr_iterate(MemRegion mr, OopClosure* cl) { | |
546 HeapWord* p = mr.start(); | |
547 HeapWord* e = mr.end(); | |
548 oop obj; | |
549 while (p < e) { | |
550 obj = oop(p); | |
551 p += obj->oop_iterate(cl); | |
552 } | |
553 assert(p == e, "bad memregion: doesn't end on obj boundary"); | |
554 } | |
555 | |
556 #define HeapRegion_OOP_SINCE_SAVE_MARKS_DEFN(OopClosureType, nv_suffix) \ | |
557 void HeapRegion::oop_since_save_marks_iterate##nv_suffix(OopClosureType* cl) { \ | |
558 ContiguousSpace::oop_since_save_marks_iterate##nv_suffix(cl); \ | |
559 } | |
560 SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(HeapRegion_OOP_SINCE_SAVE_MARKS_DEFN) | |
561 | |
562 | |
563 void HeapRegion::oop_before_save_marks_iterate(OopClosure* cl) { | |
564 oops_in_mr_iterate(MemRegion(bottom(), saved_mark_word()), cl); | |
565 } | |
566 | |
567 HeapWord* | |
568 HeapRegion::object_iterate_mem_careful(MemRegion mr, | |
569 ObjectClosure* cl) { | |
570 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
571 // We used to use "block_start_careful" here. But we're actually happy | |
572 // to update the BOT while we do this... | |
573 HeapWord* cur = block_start(mr.start()); | |
574 mr = mr.intersection(used_region()); | |
575 if (mr.is_empty()) return NULL; | |
576 // Otherwise, find the obj that extends onto mr.start(). | |
577 | |
578 assert(cur <= mr.start() | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
579 && (oop(cur)->klass_or_null() == NULL || |
342 | 580 cur + oop(cur)->size() > mr.start()), |
581 "postcondition of block_start"); | |
582 oop obj; | |
583 while (cur < mr.end()) { | |
584 obj = oop(cur); | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
585 if (obj->klass_or_null() == NULL) { |
342 | 586 // Ran into an unparseable point. |
587 return cur; | |
588 } else if (!g1h->is_obj_dead(obj)) { | |
589 cl->do_object(obj); | |
590 } | |
591 if (cl->abort()) return cur; | |
592 // The check above must occur before the operation below, since an | |
593 // abort might invalidate the "size" operation. | |
594 cur += obj->size(); | |
595 } | |
596 return NULL; | |
597 } | |
598 | |
599 HeapWord* | |
600 HeapRegion:: | |
601 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
|
602 FilterOutOfRegionClosure* cl, |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
603 bool filter_young) { |
342 | 604 G1CollectedHeap* g1h = G1CollectedHeap::heap(); |
605 | |
606 // If we're within a stop-world GC, then we might look at a card in a | |
607 // GC alloc region that extends onto a GC LAB, which may not be | |
608 // parseable. Stop such at the "saved_mark" of the region. | |
609 if (G1CollectedHeap::heap()->is_gc_active()) { | |
610 mr = mr.intersection(used_region_at_save_marks()); | |
611 } else { | |
612 mr = mr.intersection(used_region()); | |
613 } | |
614 if (mr.is_empty()) return NULL; | |
615 // Otherwise, find the obj that extends onto mr.start(). | |
616 | |
1666
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
617 // 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
|
618 // 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
|
619 // 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
|
620 // 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
|
621 // 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
|
622 // 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
|
623 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
|
624 return NULL; |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
625 } |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
626 |
1705 | 627 assert(!is_young(), "check value of filter_young"); |
628 | |
342 | 629 // We used to use "block_start_careful" here. But we're actually happy |
630 // to update the BOT while we do this... | |
631 HeapWord* cur = block_start(mr.start()); | |
632 assert(cur <= mr.start(), "Postcondition"); | |
633 | |
634 while (cur <= mr.start()) { | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
635 if (oop(cur)->klass_or_null() == NULL) { |
342 | 636 // Ran into an unparseable point. |
637 return cur; | |
638 } | |
639 // Otherwise... | |
640 int sz = oop(cur)->size(); | |
641 if (cur + sz > mr.start()) break; | |
642 // Otherwise, go on. | |
643 cur = cur + sz; | |
644 } | |
645 oop obj; | |
646 obj = oop(cur); | |
647 // If we finish this loop... | |
648 assert(cur <= mr.start() | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
649 && obj->klass_or_null() != NULL |
342 | 650 && cur + obj->size() > mr.start(), |
651 "Loop postcondition"); | |
652 if (!g1h->is_obj_dead(obj)) { | |
653 obj->oop_iterate(cl, mr); | |
654 } | |
655 | |
656 HeapWord* next; | |
657 while (cur < mr.end()) { | |
658 obj = oop(cur); | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
659 if (obj->klass_or_null() == NULL) { |
342 | 660 // Ran into an unparseable point. |
661 return cur; | |
662 }; | |
663 // Otherwise: | |
664 next = (cur + obj->size()); | |
665 if (!g1h->is_obj_dead(obj)) { | |
666 if (next < mr.end()) { | |
667 obj->oop_iterate(cl); | |
668 } else { | |
669 // this obj spans the boundary. If it's an array, stop at the | |
670 // boundary. | |
671 if (obj->is_objArray()) { | |
672 obj->oop_iterate(cl, mr); | |
673 } else { | |
674 obj->oop_iterate(cl); | |
675 } | |
676 } | |
677 } | |
678 cur = next; | |
679 } | |
680 return NULL; | |
681 } | |
682 | |
683 void HeapRegion::print() const { print_on(gclog_or_tty); } | |
684 void HeapRegion::print_on(outputStream* st) const { | |
685 if (isHumongous()) { | |
686 if (startsHumongous()) | |
687 st->print(" HS"); | |
688 else | |
689 st->print(" HC"); | |
690 } else { | |
691 st->print(" "); | |
692 } | |
693 if (in_collection_set()) | |
694 st->print(" CS"); | |
695 else if (is_gc_alloc_region()) | |
696 st->print(" A "); | |
697 else | |
698 st->print(" "); | |
699 if (is_young()) | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1388
diff
changeset
|
700 st->print(is_survivor() ? " SU" : " Y "); |
342 | 701 else |
702 st->print(" "); | |
703 if (is_empty()) | |
704 st->print(" F"); | |
705 else | |
706 st->print(" "); | |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
707 st->print(" %5d", _gc_time_stamp); |
1388 | 708 st->print(" PTAMS "PTR_FORMAT" NTAMS "PTR_FORMAT, |
709 prev_top_at_mark_start(), next_top_at_mark_start()); | |
342 | 710 G1OffsetTableContigSpace::print_on(st); |
711 } | |
712 | |
811 | 713 void HeapRegion::verify(bool allow_dirty) const { |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
714 bool dummy = false; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
715 verify(allow_dirty, /* use_prev_marking */ true, /* failures */ &dummy); |
811 | 716 } |
717 | |
342 | 718 // This really ought to be commoned up into OffsetTableContigSpace somehow. |
719 // We would need a mechanism to make that code skip dead objects. | |
720 | |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
721 void HeapRegion::verify(bool allow_dirty, |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
722 bool use_prev_marking, |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
723 bool* failures) const { |
342 | 724 G1CollectedHeap* g1 = G1CollectedHeap::heap(); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
725 *failures = false; |
342 | 726 HeapWord* p = bottom(); |
727 HeapWord* prev_p = NULL; | |
811 | 728 VerifyLiveClosure vl_cl(g1, use_prev_marking); |
1718
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
729 bool is_humongous = isHumongous(); |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
730 bool do_bot_verify = !is_young(); |
1718
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
731 size_t object_num = 0; |
342 | 732 while (p < top()) { |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
733 oop obj = oop(p); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
734 size_t obj_size = obj->size(); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
735 object_num += 1; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
736 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
737 if (is_humongous != g1->isHumongous(obj_size)) { |
1718
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
738 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
|
739 SIZE_FORMAT" words) in a %shumongous region", |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
740 p, g1->isHumongous(obj_size) ? "" : "non-", |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
741 obj_size, is_humongous ? "" : "non-"); |
1718
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
742 *failures = true; |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
743 return; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
744 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
745 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
746 // 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
|
747 // appropriate messasge. |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
748 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
|
749 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
750 return; |
1718
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
751 } |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
752 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
753 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
|
754 if (obj->is_oop()) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
755 klassOop klass = obj->klass(); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
756 if (!klass->is_perm()) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
757 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
|
758 "not in perm", klass, obj); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
759 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
760 return; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
761 } else if (!klass->is_klass()) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
762 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
|
763 "not a klass", klass, obj); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
764 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
765 return; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
766 } else { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
767 vl_cl.set_containing_obj(obj); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
768 obj->oop_iterate(&vl_cl); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
769 if (vl_cl.failures()) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
770 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
771 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
772 if (G1MaxVerifyFailures >= 0 && |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
773 vl_cl.n_failures() >= G1MaxVerifyFailures) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
774 return; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
775 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
776 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
777 } else { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
778 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
|
779 *failures = true; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
780 return; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
781 } |
342 | 782 } |
783 prev_p = p; | |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
784 p += obj_size; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
785 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
786 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
787 if (p != top()) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
788 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
|
789 "does not match top "PTR_FORMAT, p, top()); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
790 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
791 return; |
342 | 792 } |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
793 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
794 HeapWord* the_end = end(); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
795 assert(p == top(), "it should still hold"); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
796 // 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
|
797 // 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
|
798 // 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
|
799 if (p < the_end) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
800 // Look up top |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
801 HeapWord* addr_1 = p; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
802 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
|
803 if (b_start_1 != p) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
804 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
|
805 " yielded "PTR_FORMAT", expecting "PTR_FORMAT, |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
806 addr_1, b_start_1, p); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
807 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
808 return; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
809 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
810 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
811 // Look up top + 1 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
812 HeapWord* addr_2 = p + 1; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
813 if (addr_2 < the_end) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
814 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
|
815 if (b_start_2 != p) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
816 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
|
817 " yielded "PTR_FORMAT", expecting "PTR_FORMAT, |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
818 addr_2, b_start_2, p); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
819 *failures = true; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
820 return; |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
821 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
822 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
823 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
824 // Look up an address between top and end |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
825 size_t diff = pointer_delta(the_end, p) / 2; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
826 HeapWord* addr_3 = p + diff; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
827 if (addr_3 < the_end) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
828 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
|
829 if (b_start_3 != p) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
830 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
|
831 " yielded "PTR_FORMAT", expecting "PTR_FORMAT, |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
832 addr_3, b_start_3, p); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
833 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
834 return; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
835 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
836 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
837 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
838 // Loook up end - 1 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
839 HeapWord* addr_4 = the_end - 1; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
840 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
|
841 if (b_start_4 != p) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
842 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
|
843 " yielded "PTR_FORMAT", expecting "PTR_FORMAT, |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
844 addr_4, b_start_4, p); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
845 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
846 return; |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
847 } |
342 | 848 } |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
849 |
1718
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
850 if (is_humongous && object_num > 1) { |
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
851 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
|
852 "but has "SIZE_FORMAT", objects", |
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
853 bottom(), end(), object_num); |
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
854 *failures = true; |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
855 return; |
342 | 856 } |
857 } | |
858 | |
859 // G1OffsetTableContigSpace code; copied from space.cpp. Hope this can go | |
860 // away eventually. | |
861 | |
356 | 862 void G1OffsetTableContigSpace::initialize(MemRegion mr, bool clear_space, bool mangle_space) { |
342 | 863 // false ==> we'll do the clearing if there's clearing to be done. |
356 | 864 ContiguousSpace::initialize(mr, false, mangle_space); |
342 | 865 _offsets.zero_bottom_entry(); |
866 _offsets.initialize_threshold(); | |
356 | 867 if (clear_space) clear(mangle_space); |
342 | 868 } |
869 | |
356 | 870 void G1OffsetTableContigSpace::clear(bool mangle_space) { |
871 ContiguousSpace::clear(mangle_space); | |
342 | 872 _offsets.zero_bottom_entry(); |
873 _offsets.initialize_threshold(); | |
874 } | |
875 | |
876 void G1OffsetTableContigSpace::set_bottom(HeapWord* new_bottom) { | |
877 Space::set_bottom(new_bottom); | |
878 _offsets.set_bottom(new_bottom); | |
879 } | |
880 | |
881 void G1OffsetTableContigSpace::set_end(HeapWord* new_end) { | |
882 Space::set_end(new_end); | |
883 _offsets.resize(new_end - bottom()); | |
884 } | |
885 | |
886 void G1OffsetTableContigSpace::print() const { | |
887 print_short(); | |
888 gclog_or_tty->print_cr(" [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " | |
889 INTPTR_FORMAT ", " INTPTR_FORMAT ")", | |
890 bottom(), top(), _offsets.threshold(), end()); | |
891 } | |
892 | |
893 HeapWord* G1OffsetTableContigSpace::initialize_threshold() { | |
894 return _offsets.initialize_threshold(); | |
895 } | |
896 | |
897 HeapWord* G1OffsetTableContigSpace::cross_threshold(HeapWord* start, | |
898 HeapWord* end) { | |
899 _offsets.alloc_block(start, end); | |
900 return _offsets.threshold(); | |
901 } | |
902 | |
903 HeapWord* G1OffsetTableContigSpace::saved_mark_word() const { | |
904 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
905 assert( _gc_time_stamp <= g1h->get_gc_time_stamp(), "invariant" ); | |
906 if (_gc_time_stamp < g1h->get_gc_time_stamp()) | |
907 return top(); | |
908 else | |
909 return ContiguousSpace::saved_mark_word(); | |
910 } | |
911 | |
912 void G1OffsetTableContigSpace::set_saved_mark() { | |
913 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
914 unsigned curr_gc_time_stamp = g1h->get_gc_time_stamp(); | |
915 | |
916 if (_gc_time_stamp < curr_gc_time_stamp) { | |
917 // The order of these is important, as another thread might be | |
918 // about to start scanning this region. If it does so after | |
919 // set_saved_mark and before _gc_time_stamp = ..., then the latter | |
920 // will be false, and it will pick up top() as the high water mark | |
921 // of region. If it does so after _gc_time_stamp = ..., then it | |
922 // will pick up the right saved_mark_word() as the high water mark | |
923 // of the region. Either way, the behaviour will be correct. | |
924 ContiguousSpace::set_saved_mark(); | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
925 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
|
926 _gc_time_stamp = curr_gc_time_stamp; |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2152
diff
changeset
|
927 // 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
|
928 // 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
|
929 // 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
|
930 // 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
|
931 // flushed. |
342 | 932 } |
933 } | |
934 | |
935 G1OffsetTableContigSpace:: | |
936 G1OffsetTableContigSpace(G1BlockOffsetSharedArray* sharedOffsetArray, | |
937 MemRegion mr, bool is_zeroed) : | |
938 _offsets(sharedOffsetArray, mr), | |
939 _par_alloc_lock(Mutex::leaf, "OffsetTableContigSpace par alloc lock", true), | |
940 _gc_time_stamp(0) | |
941 { | |
942 _offsets.set_space(this); | |
356 | 943 initialize(mr, !is_zeroed, SpaceDecorator::Mangle); |
342 | 944 } |