Mercurial > hg > truffle
annotate src/share/vm/gc_implementation/g1/heapRegion.cpp @ 2152:0fa27f37d4d4
6977804: G1: remove the zero-filling thread
Summary: This changeset removes the zero-filling thread from G1 and collapses the two free region lists we had before (the "free" and "unclean" lists) into one. The new free list uses the new heap region sets / lists abstractions that we'll ultimately use it to keep track of all regions in the heap. A heap region set was also introduced for the humongous regions. Finally, this change increases the concurrency between the thread that completes freeing regions (after a cleanup pause) and the rest of the system (before we'd have to wait for said thread to complete before allocating a new region). The changest also includes a lot of refactoring and code simplification.
Reviewed-by: jcoomes, johnc
author | tonyp |
---|---|
date | Wed, 19 Jan 2011 19:30:42 -0500 |
parents | 2250ee17e258 |
children | d25d4ca69222 abdfc822206f |
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); | |
363 | |
364 if (!par) { | |
365 // If this is parallel, this will be done later. | |
366 HeapRegionRemSet* hrrs = rem_set(); | |
367 if (hrrs != NULL) hrrs->clear(); | |
355 | 368 _claimed = InitialClaimValue; |
342 | 369 } |
370 zero_marked_bytes(); | |
371 set_sort_index(-1); | |
372 | |
373 _offsets.resize(HeapRegion::GrainWords); | |
374 init_top_at_mark_start(); | |
356 | 375 if (clear_space) clear(SpaceDecorator::Mangle); |
342 | 376 } |
377 | |
378 // <PREDICTION> | |
379 void HeapRegion::calc_gc_efficiency() { | |
380 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
381 _gc_efficiency = (double) garbage_bytes() / | |
382 g1h->predict_region_elapsed_time_ms(this, false); | |
383 } | |
384 // </PREDICTION> | |
385 | |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
386 void HeapRegion::set_startsHumongous(HeapWord* new_top, HeapWord* new_end) { |
2152 | 387 assert(!isHumongous(), "sanity / pre-condition"); |
1886
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
388 assert(end() == _orig_end, |
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
389 "Should be normal before the humongous object allocation"); |
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
390 assert(top() == bottom(), "should be empty"); |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
391 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
|
392 |
355 | 393 _humongous_type = StartsHumongous; |
342 | 394 _humongous_start_region = this; |
1886
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
395 |
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
396 set_end(new_end); |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
397 _offsets.set_for_starts_humongous(new_top); |
1886
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
398 } |
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
399 |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
400 void HeapRegion::set_continuesHumongous(HeapRegion* first_hr) { |
2152 | 401 assert(!isHumongous(), "sanity / pre-condition"); |
1886
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
402 assert(end() == _orig_end, |
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
403 "Should be normal before the humongous object allocation"); |
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
404 assert(top() == bottom(), "should be empty"); |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
405 assert(first_hr->startsHumongous(), "pre-condition"); |
1886
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
406 |
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
407 _humongous_type = ContinuesHumongous; |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
408 _humongous_start_region = first_hr; |
342 | 409 } |
410 | |
2152 | 411 void HeapRegion::set_notHumongous() { |
412 assert(isHumongous(), "pre-condition"); | |
413 | |
414 if (startsHumongous()) { | |
415 assert(top() <= end(), "pre-condition"); | |
416 set_end(_orig_end); | |
417 if (top() > end()) { | |
418 // at least one "continues humongous" region after it | |
419 set_top(end()); | |
420 } | |
421 } else { | |
422 // continues humongous | |
423 assert(end() == _orig_end, "sanity"); | |
424 } | |
425 | |
426 assert(capacity() == (size_t) HeapRegion::GrainBytes, "pre-condition"); | |
427 _humongous_type = NotHumongous; | |
428 _humongous_start_region = NULL; | |
429 } | |
430 | |
342 | 431 bool HeapRegion::claimHeapRegion(jint claimValue) { |
432 jint current = _claimed; | |
433 if (current != claimValue) { | |
434 jint res = Atomic::cmpxchg(claimValue, &_claimed, current); | |
435 if (res == current) { | |
436 return true; | |
437 } | |
438 } | |
439 return false; | |
440 } | |
441 | |
442 HeapWord* HeapRegion::next_block_start_careful(HeapWord* addr) { | |
443 HeapWord* low = addr; | |
444 HeapWord* high = end(); | |
445 while (low < high) { | |
446 size_t diff = pointer_delta(high, low); | |
447 // Must add one below to bias toward the high amount. Otherwise, if | |
448 // "high" were at the desired value, and "low" were one less, we | |
449 // would not converge on "high". This is not symmetric, because | |
450 // we set "high" to a block start, which might be the right one, | |
451 // which we don't do for "low". | |
452 HeapWord* middle = low + (diff+1)/2; | |
453 if (middle == high) return high; | |
454 HeapWord* mid_bs = block_start_careful(middle); | |
455 if (mid_bs < addr) { | |
456 low = middle; | |
457 } else { | |
458 high = mid_bs; | |
459 } | |
460 } | |
461 assert(low == high && low >= addr, "Didn't work."); | |
462 return low; | |
463 } | |
464 | |
356 | 465 void HeapRegion::initialize(MemRegion mr, bool clear_space, bool mangle_space) { |
466 G1OffsetTableContigSpace::initialize(mr, false, mangle_space); | |
342 | 467 hr_clear(false/*par*/, clear_space); |
468 } | |
469 #ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away | |
470 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list | |
471 #endif // _MSC_VER | |
472 | |
473 | |
474 HeapRegion:: | |
475 HeapRegion(G1BlockOffsetSharedArray* sharedOffsetArray, | |
476 MemRegion mr, bool is_zeroed) | |
477 : G1OffsetTableContigSpace(sharedOffsetArray, mr, is_zeroed), | |
478 _next_fk(HeapRegionDCTOC::NoFilterKind), | |
479 _hrs_index(-1), | |
355 | 480 _humongous_type(NotHumongous), _humongous_start_region(NULL), |
342 | 481 _in_collection_set(false), _is_gc_alloc_region(false), |
482 _next_in_special_set(NULL), _orig_end(NULL), | |
355 | 483 _claimed(InitialClaimValue), _evacuation_failed(false), |
342 | 484 _prev_marked_bytes(0), _next_marked_bytes(0), _sort_index(-1), |
485 _young_type(NotYoung), _next_young_region(NULL), | |
2152 | 486 _next_dirty_cards_region(NULL), _next(NULL), _pending_removal(false), |
487 #ifdef ASSERT | |
488 _containing_set(NULL), | |
489 #endif // ASSERT | |
490 _young_index_in_cset(-1), _surv_rate_group(NULL), _age_index(-1), | |
491 _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
|
492 _predicted_bytes_to_copy(0) |
342 | 493 { |
494 _orig_end = mr.end(); | |
495 // Note that initialize() will set the start of the unmarked area of the | |
496 // region. | |
356 | 497 this->initialize(mr, !is_zeroed, SpaceDecorator::Mangle); |
498 set_top(bottom()); | |
499 set_saved_mark(); | |
342 | 500 |
501 _rem_set = new HeapRegionRemSet(sharedOffsetArray, this); | |
502 | |
503 assert(HeapRegionRemSet::num_par_rem_sets() > 0, "Invariant."); | |
504 // In case the region is allocated during a pause, note the top. | |
505 // We haven't done any counting on a brand new region. | |
506 _top_at_conc_mark_count = bottom(); | |
507 } | |
508 | |
509 class NextCompactionHeapRegionClosure: public HeapRegionClosure { | |
510 const HeapRegion* _target; | |
511 bool _target_seen; | |
512 HeapRegion* _last; | |
513 CompactibleSpace* _res; | |
514 public: | |
515 NextCompactionHeapRegionClosure(const HeapRegion* target) : | |
516 _target(target), _target_seen(false), _res(NULL) {} | |
517 bool doHeapRegion(HeapRegion* cur) { | |
518 if (_target_seen) { | |
519 if (!cur->isHumongous()) { | |
520 _res = cur; | |
521 return true; | |
522 } | |
523 } else if (cur == _target) { | |
524 _target_seen = true; | |
525 } | |
526 return false; | |
527 } | |
528 CompactibleSpace* result() { return _res; } | |
529 }; | |
530 | |
531 CompactibleSpace* HeapRegion::next_compaction_space() const { | |
532 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
533 // cast away const-ness | |
534 HeapRegion* r = (HeapRegion*) this; | |
535 NextCompactionHeapRegionClosure blk(r); | |
536 g1h->heap_region_iterate_from(r, &blk); | |
537 return blk.result(); | |
538 } | |
539 | |
540 void HeapRegion::save_marks() { | |
541 set_saved_mark(); | |
542 } | |
543 | |
544 void HeapRegion::oops_in_mr_iterate(MemRegion mr, OopClosure* cl) { | |
545 HeapWord* p = mr.start(); | |
546 HeapWord* e = mr.end(); | |
547 oop obj; | |
548 while (p < e) { | |
549 obj = oop(p); | |
550 p += obj->oop_iterate(cl); | |
551 } | |
552 assert(p == e, "bad memregion: doesn't end on obj boundary"); | |
553 } | |
554 | |
555 #define HeapRegion_OOP_SINCE_SAVE_MARKS_DEFN(OopClosureType, nv_suffix) \ | |
556 void HeapRegion::oop_since_save_marks_iterate##nv_suffix(OopClosureType* cl) { \ | |
557 ContiguousSpace::oop_since_save_marks_iterate##nv_suffix(cl); \ | |
558 } | |
559 SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(HeapRegion_OOP_SINCE_SAVE_MARKS_DEFN) | |
560 | |
561 | |
562 void HeapRegion::oop_before_save_marks_iterate(OopClosure* cl) { | |
563 oops_in_mr_iterate(MemRegion(bottom(), saved_mark_word()), cl); | |
564 } | |
565 | |
566 HeapWord* | |
567 HeapRegion::object_iterate_mem_careful(MemRegion mr, | |
568 ObjectClosure* cl) { | |
569 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
570 // We used to use "block_start_careful" here. But we're actually happy | |
571 // to update the BOT while we do this... | |
572 HeapWord* cur = block_start(mr.start()); | |
573 mr = mr.intersection(used_region()); | |
574 if (mr.is_empty()) return NULL; | |
575 // Otherwise, find the obj that extends onto mr.start(). | |
576 | |
577 assert(cur <= mr.start() | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
578 && (oop(cur)->klass_or_null() == NULL || |
342 | 579 cur + oop(cur)->size() > mr.start()), |
580 "postcondition of block_start"); | |
581 oop obj; | |
582 while (cur < mr.end()) { | |
583 obj = oop(cur); | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
584 if (obj->klass_or_null() == NULL) { |
342 | 585 // Ran into an unparseable point. |
586 return cur; | |
587 } else if (!g1h->is_obj_dead(obj)) { | |
588 cl->do_object(obj); | |
589 } | |
590 if (cl->abort()) return cur; | |
591 // The check above must occur before the operation below, since an | |
592 // abort might invalidate the "size" operation. | |
593 cur += obj->size(); | |
594 } | |
595 return NULL; | |
596 } | |
597 | |
598 HeapWord* | |
599 HeapRegion:: | |
600 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
|
601 FilterOutOfRegionClosure* cl, |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
602 bool filter_young) { |
342 | 603 G1CollectedHeap* g1h = G1CollectedHeap::heap(); |
604 | |
605 // If we're within a stop-world GC, then we might look at a card in a | |
606 // GC alloc region that extends onto a GC LAB, which may not be | |
607 // parseable. Stop such at the "saved_mark" of the region. | |
608 if (G1CollectedHeap::heap()->is_gc_active()) { | |
609 mr = mr.intersection(used_region_at_save_marks()); | |
610 } else { | |
611 mr = mr.intersection(used_region()); | |
612 } | |
613 if (mr.is_empty()) return NULL; | |
614 // Otherwise, find the obj that extends onto mr.start(). | |
615 | |
1666
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
616 // 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
|
617 // 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
|
618 // 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
|
619 // 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
|
620 // 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
|
621 // 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
|
622 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
|
623 return NULL; |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
624 } |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
625 |
1705 | 626 assert(!is_young(), "check value of filter_young"); |
627 | |
342 | 628 // We used to use "block_start_careful" here. But we're actually happy |
629 // to update the BOT while we do this... | |
630 HeapWord* cur = block_start(mr.start()); | |
631 assert(cur <= mr.start(), "Postcondition"); | |
632 | |
633 while (cur <= mr.start()) { | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
634 if (oop(cur)->klass_or_null() == NULL) { |
342 | 635 // Ran into an unparseable point. |
636 return cur; | |
637 } | |
638 // Otherwise... | |
639 int sz = oop(cur)->size(); | |
640 if (cur + sz > mr.start()) break; | |
641 // Otherwise, go on. | |
642 cur = cur + sz; | |
643 } | |
644 oop obj; | |
645 obj = oop(cur); | |
646 // If we finish this loop... | |
647 assert(cur <= mr.start() | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
648 && obj->klass_or_null() != NULL |
342 | 649 && cur + obj->size() > mr.start(), |
650 "Loop postcondition"); | |
651 if (!g1h->is_obj_dead(obj)) { | |
652 obj->oop_iterate(cl, mr); | |
653 } | |
654 | |
655 HeapWord* next; | |
656 while (cur < mr.end()) { | |
657 obj = oop(cur); | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
658 if (obj->klass_or_null() == NULL) { |
342 | 659 // Ran into an unparseable point. |
660 return cur; | |
661 }; | |
662 // Otherwise: | |
663 next = (cur + obj->size()); | |
664 if (!g1h->is_obj_dead(obj)) { | |
665 if (next < mr.end()) { | |
666 obj->oop_iterate(cl); | |
667 } else { | |
668 // this obj spans the boundary. If it's an array, stop at the | |
669 // boundary. | |
670 if (obj->is_objArray()) { | |
671 obj->oop_iterate(cl, mr); | |
672 } else { | |
673 obj->oop_iterate(cl); | |
674 } | |
675 } | |
676 } | |
677 cur = next; | |
678 } | |
679 return NULL; | |
680 } | |
681 | |
682 void HeapRegion::print() const { print_on(gclog_or_tty); } | |
683 void HeapRegion::print_on(outputStream* st) const { | |
684 if (isHumongous()) { | |
685 if (startsHumongous()) | |
686 st->print(" HS"); | |
687 else | |
688 st->print(" HC"); | |
689 } else { | |
690 st->print(" "); | |
691 } | |
692 if (in_collection_set()) | |
693 st->print(" CS"); | |
694 else if (is_gc_alloc_region()) | |
695 st->print(" A "); | |
696 else | |
697 st->print(" "); | |
698 if (is_young()) | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1388
diff
changeset
|
699 st->print(is_survivor() ? " SU" : " Y "); |
342 | 700 else |
701 st->print(" "); | |
702 if (is_empty()) | |
703 st->print(" F"); | |
704 else | |
705 st->print(" "); | |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
706 st->print(" %5d", _gc_time_stamp); |
1388 | 707 st->print(" PTAMS "PTR_FORMAT" NTAMS "PTR_FORMAT, |
708 prev_top_at_mark_start(), next_top_at_mark_start()); | |
342 | 709 G1OffsetTableContigSpace::print_on(st); |
710 } | |
711 | |
811 | 712 void HeapRegion::verify(bool allow_dirty) const { |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
713 bool dummy = false; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
714 verify(allow_dirty, /* use_prev_marking */ true, /* failures */ &dummy); |
811 | 715 } |
716 | |
342 | 717 // This really ought to be commoned up into OffsetTableContigSpace somehow. |
718 // We would need a mechanism to make that code skip dead objects. | |
719 | |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
720 void HeapRegion::verify(bool allow_dirty, |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
721 bool use_prev_marking, |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
722 bool* failures) const { |
342 | 723 G1CollectedHeap* g1 = G1CollectedHeap::heap(); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
724 *failures = false; |
342 | 725 HeapWord* p = bottom(); |
726 HeapWord* prev_p = NULL; | |
811 | 727 VerifyLiveClosure vl_cl(g1, use_prev_marking); |
1718
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
728 bool is_humongous = isHumongous(); |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
729 bool do_bot_verify = !is_young(); |
1718
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
730 size_t object_num = 0; |
342 | 731 while (p < top()) { |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
732 oop obj = oop(p); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
733 size_t obj_size = obj->size(); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
734 object_num += 1; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
735 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
736 if (is_humongous != g1->isHumongous(obj_size)) { |
1718
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
737 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
|
738 SIZE_FORMAT" words) in a %shumongous region", |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
739 p, g1->isHumongous(obj_size) ? "" : "non-", |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
740 obj_size, is_humongous ? "" : "non-"); |
1718
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
741 *failures = true; |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
742 return; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
743 } |
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 // 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
|
746 // appropriate messasge. |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
747 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
|
748 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
749 return; |
1718
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
750 } |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
751 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
752 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
|
753 if (obj->is_oop()) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
754 klassOop klass = obj->klass(); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
755 if (!klass->is_perm()) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
756 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
|
757 "not in perm", klass, obj); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
758 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
759 return; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
760 } else if (!klass->is_klass()) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
761 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
|
762 "not a klass", klass, obj); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
763 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
764 return; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
765 } else { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
766 vl_cl.set_containing_obj(obj); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
767 obj->oop_iterate(&vl_cl); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
768 if (vl_cl.failures()) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
769 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
770 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
771 if (G1MaxVerifyFailures >= 0 && |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
772 vl_cl.n_failures() >= G1MaxVerifyFailures) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
773 return; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
774 } |
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 } else { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
777 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
|
778 *failures = true; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
779 return; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
780 } |
342 | 781 } |
782 prev_p = p; | |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
783 p += obj_size; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
784 } |
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 if (p != top()) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
787 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
|
788 "does not match top "PTR_FORMAT, p, top()); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
789 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
790 return; |
342 | 791 } |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
792 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
793 HeapWord* the_end = end(); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
794 assert(p == top(), "it should still hold"); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
795 // 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
|
796 // 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
|
797 // 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
|
798 if (p < the_end) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
799 // Look up top |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
800 HeapWord* addr_1 = p; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
801 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
|
802 if (b_start_1 != p) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
803 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
|
804 " yielded "PTR_FORMAT", expecting "PTR_FORMAT, |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
805 addr_1, b_start_1, p); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
806 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
807 return; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
808 } |
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 // Look up top + 1 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
811 HeapWord* addr_2 = p + 1; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
812 if (addr_2 < the_end) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
813 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
|
814 if (b_start_2 != p) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
815 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
|
816 " yielded "PTR_FORMAT", expecting "PTR_FORMAT, |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
817 addr_2, b_start_2, p); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
818 *failures = true; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
819 return; |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
820 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
821 } |
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 // Look up an address between top and end |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
824 size_t diff = pointer_delta(the_end, p) / 2; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
825 HeapWord* addr_3 = p + diff; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
826 if (addr_3 < the_end) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
827 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
|
828 if (b_start_3 != p) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
829 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
|
830 " yielded "PTR_FORMAT", expecting "PTR_FORMAT, |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
831 addr_3, b_start_3, p); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
832 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
833 return; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
834 } |
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 // Loook up end - 1 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
838 HeapWord* addr_4 = the_end - 1; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
839 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
|
840 if (b_start_4 != p) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
841 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
|
842 " yielded "PTR_FORMAT", expecting "PTR_FORMAT, |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
843 addr_4, b_start_4, p); |
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; |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
846 } |
342 | 847 } |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
848 |
1718
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
849 if (is_humongous && object_num > 1) { |
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
850 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
|
851 "but has "SIZE_FORMAT", objects", |
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
852 bottom(), end(), object_num); |
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
853 *failures = true; |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
854 return; |
342 | 855 } |
856 } | |
857 | |
858 // G1OffsetTableContigSpace code; copied from space.cpp. Hope this can go | |
859 // away eventually. | |
860 | |
356 | 861 void G1OffsetTableContigSpace::initialize(MemRegion mr, bool clear_space, bool mangle_space) { |
342 | 862 // false ==> we'll do the clearing if there's clearing to be done. |
356 | 863 ContiguousSpace::initialize(mr, false, mangle_space); |
342 | 864 _offsets.zero_bottom_entry(); |
865 _offsets.initialize_threshold(); | |
356 | 866 if (clear_space) clear(mangle_space); |
342 | 867 } |
868 | |
356 | 869 void G1OffsetTableContigSpace::clear(bool mangle_space) { |
870 ContiguousSpace::clear(mangle_space); | |
342 | 871 _offsets.zero_bottom_entry(); |
872 _offsets.initialize_threshold(); | |
873 } | |
874 | |
875 void G1OffsetTableContigSpace::set_bottom(HeapWord* new_bottom) { | |
876 Space::set_bottom(new_bottom); | |
877 _offsets.set_bottom(new_bottom); | |
878 } | |
879 | |
880 void G1OffsetTableContigSpace::set_end(HeapWord* new_end) { | |
881 Space::set_end(new_end); | |
882 _offsets.resize(new_end - bottom()); | |
883 } | |
884 | |
885 void G1OffsetTableContigSpace::print() const { | |
886 print_short(); | |
887 gclog_or_tty->print_cr(" [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " | |
888 INTPTR_FORMAT ", " INTPTR_FORMAT ")", | |
889 bottom(), top(), _offsets.threshold(), end()); | |
890 } | |
891 | |
892 HeapWord* G1OffsetTableContigSpace::initialize_threshold() { | |
893 return _offsets.initialize_threshold(); | |
894 } | |
895 | |
896 HeapWord* G1OffsetTableContigSpace::cross_threshold(HeapWord* start, | |
897 HeapWord* end) { | |
898 _offsets.alloc_block(start, end); | |
899 return _offsets.threshold(); | |
900 } | |
901 | |
902 HeapWord* G1OffsetTableContigSpace::saved_mark_word() const { | |
903 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
904 assert( _gc_time_stamp <= g1h->get_gc_time_stamp(), "invariant" ); | |
905 if (_gc_time_stamp < g1h->get_gc_time_stamp()) | |
906 return top(); | |
907 else | |
908 return ContiguousSpace::saved_mark_word(); | |
909 } | |
910 | |
911 void G1OffsetTableContigSpace::set_saved_mark() { | |
912 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
913 unsigned curr_gc_time_stamp = g1h->get_gc_time_stamp(); | |
914 | |
915 if (_gc_time_stamp < curr_gc_time_stamp) { | |
916 // The order of these is important, as another thread might be | |
917 // about to start scanning this region. If it does so after | |
918 // set_saved_mark and before _gc_time_stamp = ..., then the latter | |
919 // will be false, and it will pick up top() as the high water mark | |
920 // of region. If it does so after _gc_time_stamp = ..., then it | |
921 // will pick up the right saved_mark_word() as the high water mark | |
922 // of the region. Either way, the behaviour will be correct. | |
923 ContiguousSpace::set_saved_mark(); | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
924 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
|
925 _gc_time_stamp = curr_gc_time_stamp; |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
926 // The following fence is to force a flush of the writes above, but |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
927 // is strictly not needed because when an allocating worker thread |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
928 // calls set_saved_mark() it does so under the ParGCRareEvent_lock; |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
929 // when the lock is released, the write will be flushed. |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
930 // OrderAccess::fence(); |
342 | 931 } |
932 } | |
933 | |
934 G1OffsetTableContigSpace:: | |
935 G1OffsetTableContigSpace(G1BlockOffsetSharedArray* sharedOffsetArray, | |
936 MemRegion mr, bool is_zeroed) : | |
937 _offsets(sharedOffsetArray, mr), | |
938 _par_alloc_lock(Mutex::leaf, "OffsetTableContigSpace par alloc lock", true), | |
939 _gc_time_stamp(0) | |
940 { | |
941 _offsets.set_space(this); | |
356 | 942 initialize(mr, !is_zeroed, SpaceDecorator::Mangle); |
342 | 943 } |