Mercurial > hg > truffle
annotate src/share/vm/gc_implementation/g1/heapRegion.cpp @ 8733:9def4075da6d
8008079: G1: Add nextObject routine to CMBitMapRO and replace nextWord
Summary: Update the task local finger to the start of the next object when marking aborts, in order to avoid the redundant scanning of all 0's when the marking task restarts, if otherwise updating to the next word. In addition, reuse the routine nextObject() in routine iterate().
Reviewed-by: johnc, ysr
Contributed-by: tamao <tao.mao@oracle.com>
author | tamao |
---|---|
date | Tue, 05 Mar 2013 15:36:56 -0800 |
parents | 8fbf05030e24 |
children | e522a00b91aa 3a4805ad0005 |
rev | line source |
---|---|
342 | 1 /* |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
2 * Copyright (c) 2001, 2012, 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 |
3986
65a8ff39a6da
7095194: G1: HeapRegion::GrainBytes, GrainWords, and CardsPerRegion should be size_t
johnc
parents:
3983
diff
changeset
|
36 int HeapRegion::LogOfHRGrainBytes = 0; |
65a8ff39a6da
7095194: G1: HeapRegion::GrainBytes, GrainWords, and CardsPerRegion should be size_t
johnc
parents:
3983
diff
changeset
|
37 int HeapRegion::LogOfHRGrainWords = 0; |
65a8ff39a6da
7095194: G1: HeapRegion::GrainBytes, GrainWords, and CardsPerRegion should be size_t
johnc
parents:
3983
diff
changeset
|
38 size_t HeapRegion::GrainBytes = 0; |
65a8ff39a6da
7095194: G1: HeapRegion::GrainBytes, GrainWords, and CardsPerRegion should be size_t
johnc
parents:
3983
diff
changeset
|
39 size_t HeapRegion::GrainWords = 0; |
65a8ff39a6da
7095194: G1: HeapRegion::GrainBytes, GrainWords, and CardsPerRegion should be size_t
johnc
parents:
3983
diff
changeset
|
40 size_t HeapRegion::CardsPerRegion = 0; |
942
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
41 |
342 | 42 HeapRegionDCTOC::HeapRegionDCTOC(G1CollectedHeap* g1, |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6611
diff
changeset
|
43 HeapRegion* hr, ExtendedOopClosure* cl, |
342 | 44 CardTableModRefBS::PrecisionStyle precision, |
45 FilterKind fk) : | |
46 ContiguousSpaceDCTOC(hr, cl, precision, NULL), | |
6254
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6027
diff
changeset
|
47 _hr(hr), _fk(fk), _g1(g1) { } |
342 | 48 |
49 FilterOutOfRegionClosure::FilterOutOfRegionClosure(HeapRegion* r, | |
50 OopClosure* oc) : | |
6254
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6027
diff
changeset
|
51 _r_bottom(r->bottom()), _r_end(r->end()), _oc(oc) { } |
342 | 52 |
53 class VerifyLiveClosure: public OopClosure { | |
811 | 54 private: |
342 | 55 G1CollectedHeap* _g1h; |
56 CardTableModRefBS* _bs; | |
57 oop _containing_obj; | |
58 bool _failures; | |
59 int _n_failures; | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
60 VerifyOption _vo; |
342 | 61 public: |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
62 // _vo == UsePrevMarking -> use "prev" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
63 // _vo == UseNextMarking -> use "next" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
64 // _vo == UseMarkWord -> use mark word from object header. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
65 VerifyLiveClosure(G1CollectedHeap* g1h, VerifyOption vo) : |
342 | 66 _g1h(g1h), _bs(NULL), _containing_obj(NULL), |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
67 _failures(false), _n_failures(0), _vo(vo) |
342 | 68 { |
69 BarrierSet* bs = _g1h->barrier_set(); | |
70 if (bs->is_a(BarrierSet::CardTableModRef)) | |
71 _bs = (CardTableModRefBS*)bs; | |
72 } | |
73 | |
74 void set_containing_obj(oop obj) { | |
75 _containing_obj = obj; | |
76 } | |
77 | |
78 bool failures() { return _failures; } | |
79 int n_failures() { return _n_failures; } | |
80 | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
81 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
|
82 virtual void do_oop( oop* p) { do_oop_work(p); } |
342 | 83 |
1388 | 84 void print_object(outputStream* out, oop obj) { |
85 #ifdef PRODUCT | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6611
diff
changeset
|
86 Klass* k = obj->klass(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6611
diff
changeset
|
87 const char* class_name = InstanceKlass::cast(k)->external_name(); |
1388 | 88 out->print_cr("class name %s", class_name); |
89 #else // PRODUCT | |
90 obj->print_on(out); | |
91 #endif // PRODUCT | |
92 } | |
93 | |
4725
3b2b58fb1425
7123165: G1: output during parallel verification can get messed up
tonyp
parents:
4073
diff
changeset
|
94 template <class T> |
3b2b58fb1425
7123165: G1: output during parallel verification can get messed up
tonyp
parents:
4073
diff
changeset
|
95 void do_oop_work(T* p) { |
342 | 96 assert(_containing_obj != NULL, "Precondition"); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
97 assert(!_g1h->is_obj_dead_cond(_containing_obj, _vo), |
811 | 98 "Precondition"); |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
99 T heap_oop = oopDesc::load_heap_oop(p); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
100 if (!oopDesc::is_null(heap_oop)) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
101 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); |
342 | 102 bool failed = false; |
4725
3b2b58fb1425
7123165: G1: output during parallel verification can get messed up
tonyp
parents:
4073
diff
changeset
|
103 if (!_g1h->is_in_closed_subset(obj) || _g1h->is_obj_dead_cond(obj, _vo)) { |
3b2b58fb1425
7123165: G1: output during parallel verification can get messed up
tonyp
parents:
4073
diff
changeset
|
104 MutexLockerEx x(ParGCRareEvent_lock, |
3b2b58fb1425
7123165: G1: output during parallel verification can get messed up
tonyp
parents:
4073
diff
changeset
|
105 Mutex::_no_safepoint_check_flag); |
3b2b58fb1425
7123165: G1: output during parallel verification can get messed up
tonyp
parents:
4073
diff
changeset
|
106 |
342 | 107 if (!_failures) { |
108 gclog_or_tty->print_cr(""); | |
109 gclog_or_tty->print_cr("----------"); | |
110 } | |
111 if (!_g1h->is_in_closed_subset(obj)) { | |
1388 | 112 HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p); |
342 | 113 gclog_or_tty->print_cr("Field "PTR_FORMAT |
1388 | 114 " of live obj "PTR_FORMAT" in region " |
115 "["PTR_FORMAT", "PTR_FORMAT")", | |
116 p, (void*) _containing_obj, | |
117 from->bottom(), from->end()); | |
118 print_object(gclog_or_tty, _containing_obj); | |
119 gclog_or_tty->print_cr("points to obj "PTR_FORMAT" not in the heap", | |
120 (void*) obj); | |
121 } else { | |
122 HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p); | |
123 HeapRegion* to = _g1h->heap_region_containing((HeapWord*)obj); | |
124 gclog_or_tty->print_cr("Field "PTR_FORMAT | |
125 " of live obj "PTR_FORMAT" in region " | |
126 "["PTR_FORMAT", "PTR_FORMAT")", | |
127 p, (void*) _containing_obj, | |
128 from->bottom(), from->end()); | |
129 print_object(gclog_or_tty, _containing_obj); | |
130 gclog_or_tty->print_cr("points to dead obj "PTR_FORMAT" in region " | |
131 "["PTR_FORMAT", "PTR_FORMAT")", | |
132 (void*) obj, to->bottom(), to->end()); | |
133 print_object(gclog_or_tty, obj); | |
342 | 134 } |
135 gclog_or_tty->print_cr("----------"); | |
4725
3b2b58fb1425
7123165: G1: output during parallel verification can get messed up
tonyp
parents:
4073
diff
changeset
|
136 gclog_or_tty->flush(); |
342 | 137 _failures = true; |
138 failed = true; | |
139 _n_failures++; | |
140 } | |
141 | |
142 if (!_g1h->full_collection()) { | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
143 HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
144 HeapRegion* to = _g1h->heap_region_containing(obj); |
342 | 145 if (from != NULL && to != NULL && |
146 from != to && | |
147 !to->isHumongous()) { | |
148 jbyte cv_obj = *_bs->byte_for_const(_containing_obj); | |
149 jbyte cv_field = *_bs->byte_for_const(p); | |
150 const jbyte dirty = CardTableModRefBS::dirty_card_val(); | |
151 | |
152 bool is_bad = !(from->is_young() | |
153 || to->rem_set()->contains_reference(p) | |
154 || !G1HRRSFlushLogBuffersOnVerify && // buffers were not flushed | |
155 (_containing_obj->is_objArray() ? | |
156 cv_field == dirty | |
157 : cv_obj == dirty || cv_field == dirty)); | |
158 if (is_bad) { | |
4725
3b2b58fb1425
7123165: G1: output during parallel verification can get messed up
tonyp
parents:
4073
diff
changeset
|
159 MutexLockerEx x(ParGCRareEvent_lock, |
3b2b58fb1425
7123165: G1: output during parallel verification can get messed up
tonyp
parents:
4073
diff
changeset
|
160 Mutex::_no_safepoint_check_flag); |
3b2b58fb1425
7123165: G1: output during parallel verification can get messed up
tonyp
parents:
4073
diff
changeset
|
161 |
342 | 162 if (!_failures) { |
163 gclog_or_tty->print_cr(""); | |
164 gclog_or_tty->print_cr("----------"); | |
165 } | |
166 gclog_or_tty->print_cr("Missing rem set entry:"); | |
3766 | 167 gclog_or_tty->print_cr("Field "PTR_FORMAT" " |
168 "of obj "PTR_FORMAT", " | |
169 "in region "HR_FORMAT, | |
170 p, (void*) _containing_obj, | |
171 HR_FORMAT_PARAMS(from)); | |
342 | 172 _containing_obj->print_on(gclog_or_tty); |
3766 | 173 gclog_or_tty->print_cr("points to obj "PTR_FORMAT" " |
174 "in region "HR_FORMAT, | |
175 (void*) obj, | |
176 HR_FORMAT_PARAMS(to)); | |
342 | 177 obj->print_on(gclog_or_tty); |
178 gclog_or_tty->print_cr("Obj head CTE = %d, field CTE = %d.", | |
179 cv_obj, cv_field); | |
180 gclog_or_tty->print_cr("----------"); | |
4725
3b2b58fb1425
7123165: G1: output during parallel verification can get messed up
tonyp
parents:
4073
diff
changeset
|
181 gclog_or_tty->flush(); |
342 | 182 _failures = true; |
183 if (!failed) _n_failures++; | |
184 } | |
185 } | |
186 } | |
187 } | |
188 } | |
189 }; | |
190 | |
191 template<class ClosureType> | |
192 HeapWord* walk_mem_region_loop(ClosureType* cl, G1CollectedHeap* g1h, | |
193 HeapRegion* hr, | |
194 HeapWord* cur, HeapWord* top) { | |
195 oop cur_oop = oop(cur); | |
196 int oop_size = cur_oop->size(); | |
197 HeapWord* next_obj = cur + oop_size; | |
198 while (next_obj < top) { | |
199 // Keep filtering the remembered set. | |
200 if (!g1h->is_obj_dead(cur_oop, hr)) { | |
201 // Bottom lies entirely below top, so we can call the | |
202 // non-memRegion version of oop_iterate below. | |
203 cur_oop->oop_iterate(cl); | |
204 } | |
205 cur = next_obj; | |
206 cur_oop = oop(cur); | |
207 oop_size = cur_oop->size(); | |
208 next_obj = cur + oop_size; | |
209 } | |
210 return cur; | |
211 } | |
212 | |
213 void HeapRegionDCTOC::walk_mem_region_with_cl(MemRegion mr, | |
214 HeapWord* bottom, | |
215 HeapWord* top, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6611
diff
changeset
|
216 ExtendedOopClosure* cl) { |
342 | 217 G1CollectedHeap* g1h = _g1; |
218 int oop_size; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6611
diff
changeset
|
219 ExtendedOopClosure* cl2 = NULL; |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
220 |
3983
811ec3d0833b
7097053: G1: assert(da ? referent->is_oop() : referent->is_oop_or_null()) failed: referenceProcessor.cpp:1054
johnc
parents:
3979
diff
changeset
|
221 FilterIntoCSClosure intoCSFilt(this, g1h, cl); |
342 | 222 FilterOutOfRegionClosure outOfRegionFilt(_hr, cl); |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
223 |
342 | 224 switch (_fk) { |
3983
811ec3d0833b
7097053: G1: assert(da ? referent->is_oop() : referent->is_oop_or_null()) failed: referenceProcessor.cpp:1054
johnc
parents:
3979
diff
changeset
|
225 case NoFilterKind: cl2 = cl; break; |
342 | 226 case IntoCSFilterKind: cl2 = &intoCSFilt; break; |
227 case OutOfRegionFilterKind: cl2 = &outOfRegionFilt; break; | |
3983
811ec3d0833b
7097053: G1: assert(da ? referent->is_oop() : referent->is_oop_or_null()) failed: referenceProcessor.cpp:1054
johnc
parents:
3979
diff
changeset
|
228 default: ShouldNotReachHere(); |
342 | 229 } |
230 | |
231 // Start filtering what we add to the remembered set. If the object is | |
232 // not considered dead, either because it is marked (in the mark bitmap) | |
233 // or it was allocated after marking finished, then we add it. Otherwise | |
234 // we can safely ignore the object. | |
235 if (!g1h->is_obj_dead(oop(bottom), _hr)) { | |
236 oop_size = oop(bottom)->oop_iterate(cl2, mr); | |
237 } else { | |
238 oop_size = oop(bottom)->size(); | |
239 } | |
240 | |
241 bottom += oop_size; | |
242 | |
243 if (bottom < top) { | |
244 // We replicate the loop below for several kinds of possible filters. | |
245 switch (_fk) { | |
246 case NoFilterKind: | |
247 bottom = walk_mem_region_loop(cl, g1h, _hr, bottom, top); | |
248 break; | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
249 |
342 | 250 case IntoCSFilterKind: { |
3983
811ec3d0833b
7097053: G1: assert(da ? referent->is_oop() : referent->is_oop_or_null()) failed: referenceProcessor.cpp:1054
johnc
parents:
3979
diff
changeset
|
251 FilterIntoCSClosure filt(this, g1h, cl); |
342 | 252 bottom = walk_mem_region_loop(&filt, g1h, _hr, bottom, top); |
253 break; | |
254 } | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
255 |
342 | 256 case OutOfRegionFilterKind: { |
257 FilterOutOfRegionClosure filt(_hr, cl); | |
258 bottom = walk_mem_region_loop(&filt, g1h, _hr, bottom, top); | |
259 break; | |
260 } | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
261 |
342 | 262 default: |
263 ShouldNotReachHere(); | |
264 } | |
265 | |
266 // Last object. Need to do dead-obj filtering here too. | |
267 if (!g1h->is_obj_dead(oop(bottom), _hr)) { | |
268 oop(bottom)->oop_iterate(cl2, mr); | |
269 } | |
270 } | |
271 } | |
272 | |
942
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
273 // 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
|
274 // 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
|
275 // heaps a bit more efficiently. |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
276 #define MIN_REGION_SIZE ( 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 // 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
|
279 // 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
|
280 // 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
|
281 // 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
|
282 // marking. |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
283 #define MAX_REGION_SIZE ( 32 * 1024 * 1024 ) |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
284 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
285 // 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
|
286 // 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
|
287 #define TARGET_REGION_NUMBER 2048 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
288 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
289 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
|
290 // region_size in bytes |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
291 uintx region_size = G1HeapRegionSize; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
292 if (FLAG_IS_DEFAULT(G1HeapRegionSize)) { |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
293 // 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
|
294 // 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
|
295 // 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
|
296 // 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
|
297 // 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
|
298 // size manually for some -Xms / -Xmx combos. |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
299 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
300 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
|
301 (uintx) MIN_REGION_SIZE); |
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 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
304 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
|
305 // 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
|
306 // 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
|
307 // <= what we've calculated so far. |
1485
fb57d4cf76c2
6931180: Migration to recent versions of MS Platform SDK
prr
parents:
1394
diff
changeset
|
308 region_size = ((uintx)1 << region_size_log); |
942
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 // 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
|
311 if (region_size < MIN_REGION_SIZE) { |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
312 region_size = MIN_REGION_SIZE; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
313 } else if (region_size > MAX_REGION_SIZE) { |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
314 region_size = MAX_REGION_SIZE; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
315 } |
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 // And recalculate the log. |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
318 region_size_log = log2_long((jlong) region_size); |
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 // Now, set up the globals. |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
321 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
|
322 LogOfHRGrainBytes = region_size_log; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
323 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
324 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
|
325 LogOfHRGrainWords = LogOfHRGrainBytes - LogHeapWordSize; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
326 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
327 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
|
328 // 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
|
329 // MIN_REGION_SIZE and MAX_REGION_SIZE. |
3986
65a8ff39a6da
7095194: G1: HeapRegion::GrainBytes, GrainWords, and CardsPerRegion should be size_t
johnc
parents:
3983
diff
changeset
|
330 GrainBytes = (size_t)region_size; |
942
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
331 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
332 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
|
333 GrainWords = GrainBytes >> LogHeapWordSize; |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
334 guarantee((size_t) 1 << LogOfHRGrainWords == GrainWords, "sanity"); |
942
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
335 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
336 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
|
337 CardsPerRegion = GrainBytes >> CardTableModRefBS::card_shift; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
338 } |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
866
diff
changeset
|
339 |
342 | 340 void HeapRegion::reset_after_compaction() { |
341 G1OffsetTableContigSpace::reset_after_compaction(); | |
342 // After a compaction the mark bitmap is invalid, so we must | |
343 // treat all objects as being inside the unmarked area. | |
344 zero_marked_bytes(); | |
345 init_top_at_mark_start(); | |
346 } | |
347 | |
348 void HeapRegion::hr_clear(bool par, bool clear_space) { | |
2152 | 349 assert(_humongous_type == NotHumongous, |
350 "we should have already filtered out humongous regions"); | |
351 assert(_humongous_start_region == NULL, | |
352 "we should have already filtered out humongous regions"); | |
353 assert(_end == _orig_end, | |
354 "we should have already filtered out humongous regions"); | |
355 | |
342 | 356 _in_collection_set = false; |
357 | |
358 set_young_index_in_cset(-1); | |
359 uninstall_surv_rate_group(); | |
360 set_young_type(NotYoung); | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2152
diff
changeset
|
361 reset_pre_dummy_top(); |
342 | 362 |
363 if (!par) { | |
364 // If this is parallel, this will be done later. | |
365 HeapRegionRemSet* hrrs = rem_set(); | |
366 if (hrrs != NULL) hrrs->clear(); | |
355 | 367 _claimed = InitialClaimValue; |
342 | 368 } |
369 zero_marked_bytes(); | |
370 | |
371 _offsets.resize(HeapRegion::GrainWords); | |
372 init_top_at_mark_start(); | |
356 | 373 if (clear_space) clear(SpaceDecorator::Mangle); |
342 | 374 } |
375 | |
3317
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
376 void HeapRegion::par_clear() { |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
377 assert(used() == 0, "the region should have been already cleared"); |
3986
65a8ff39a6da
7095194: G1: HeapRegion::GrainBytes, GrainWords, and CardsPerRegion should be size_t
johnc
parents:
3983
diff
changeset
|
378 assert(capacity() == HeapRegion::GrainBytes, "should be back to normal"); |
3317
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
379 HeapRegionRemSet* hrrs = rem_set(); |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
380 hrrs->clear(); |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
381 CardTableModRefBS* ct_bs = |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
382 (CardTableModRefBS*)G1CollectedHeap::heap()->barrier_set(); |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
383 ct_bs->clear(MemRegion(bottom(), end())); |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
384 } |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
385 |
342 | 386 void HeapRegion::calc_gc_efficiency() { |
6611 | 387 // GC efficiency is the ratio of how much space would be |
388 // reclaimed over how long we predict it would take to reclaim it. | |
342 | 389 G1CollectedHeap* g1h = G1CollectedHeap::heap(); |
4912
a9647476d1a4
7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents:
4839
diff
changeset
|
390 G1CollectorPolicy* g1p = g1h->g1_policy(); |
6611 | 391 |
392 // Retrieve a prediction of the elapsed time for this region for | |
393 // a mixed gc because the region will only be evacuated during a | |
394 // mixed gc. | |
395 double region_elapsed_time_ms = | |
396 g1p->predict_region_elapsed_time_ms(this, false /* for_young_gc */); | |
397 _gc_efficiency = (double) reclaimable_bytes() / region_elapsed_time_ms; | |
342 | 398 } |
399 | |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
400 void HeapRegion::set_startsHumongous(HeapWord* new_top, HeapWord* new_end) { |
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(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
|
406 |
355 | 407 _humongous_type = StartsHumongous; |
342 | 408 _humongous_start_region = this; |
1886
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
409 |
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
410 set_end(new_end); |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
411 _offsets.set_for_starts_humongous(new_top); |
1886
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
412 } |
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
413 |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
414 void HeapRegion::set_continuesHumongous(HeapRegion* first_hr) { |
2152 | 415 assert(!isHumongous(), "sanity / pre-condition"); |
1886
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
416 assert(end() == _orig_end, |
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
417 "Should be normal before the humongous object allocation"); |
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
418 assert(top() == bottom(), "should be empty"); |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
419 assert(first_hr->startsHumongous(), "pre-condition"); |
1886
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
420 |
72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents:
1718
diff
changeset
|
421 _humongous_type = ContinuesHumongous; |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
422 _humongous_start_region = first_hr; |
342 | 423 } |
424 | |
2152 | 425 void HeapRegion::set_notHumongous() { |
426 assert(isHumongous(), "pre-condition"); | |
427 | |
428 if (startsHumongous()) { | |
429 assert(top() <= end(), "pre-condition"); | |
430 set_end(_orig_end); | |
431 if (top() > end()) { | |
432 // at least one "continues humongous" region after it | |
433 set_top(end()); | |
434 } | |
435 } else { | |
436 // continues humongous | |
437 assert(end() == _orig_end, "sanity"); | |
438 } | |
439 | |
3986
65a8ff39a6da
7095194: G1: HeapRegion::GrainBytes, GrainWords, and CardsPerRegion should be size_t
johnc
parents:
3983
diff
changeset
|
440 assert(capacity() == HeapRegion::GrainBytes, "pre-condition"); |
2152 | 441 _humongous_type = NotHumongous; |
442 _humongous_start_region = NULL; | |
443 } | |
444 | |
342 | 445 bool HeapRegion::claimHeapRegion(jint claimValue) { |
446 jint current = _claimed; | |
447 if (current != claimValue) { | |
448 jint res = Atomic::cmpxchg(claimValue, &_claimed, current); | |
449 if (res == current) { | |
450 return true; | |
451 } | |
452 } | |
453 return false; | |
454 } | |
455 | |
456 HeapWord* HeapRegion::next_block_start_careful(HeapWord* addr) { | |
457 HeapWord* low = addr; | |
458 HeapWord* high = end(); | |
459 while (low < high) { | |
460 size_t diff = pointer_delta(high, low); | |
461 // Must add one below to bias toward the high amount. Otherwise, if | |
462 // "high" were at the desired value, and "low" were one less, we | |
463 // would not converge on "high". This is not symmetric, because | |
464 // we set "high" to a block start, which might be the right one, | |
465 // which we don't do for "low". | |
466 HeapWord* middle = low + (diff+1)/2; | |
467 if (middle == high) return high; | |
468 HeapWord* mid_bs = block_start_careful(middle); | |
469 if (mid_bs < addr) { | |
470 low = middle; | |
471 } else { | |
472 high = mid_bs; | |
473 } | |
474 } | |
475 assert(low == high && low >= addr, "Didn't work."); | |
476 return low; | |
477 } | |
478 | |
479 #ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away | |
480 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list | |
481 #endif // _MSC_VER | |
482 | |
483 | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
484 HeapRegion::HeapRegion(uint hrs_index, |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
485 G1BlockOffsetSharedArray* sharedOffsetArray, |
6754
8fbf05030e24
7016955: G1: remove the is_zeroed parameter from the HeapRegion constructor
johnc
parents:
6725
diff
changeset
|
486 MemRegion mr) : |
8fbf05030e24
7016955: G1: remove the is_zeroed parameter from the HeapRegion constructor
johnc
parents:
6725
diff
changeset
|
487 G1OffsetTableContigSpace(sharedOffsetArray, mr), |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3978
diff
changeset
|
488 _hrs_index(hrs_index), |
355 | 489 _humongous_type(NotHumongous), _humongous_start_region(NULL), |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3772
diff
changeset
|
490 _in_collection_set(false), |
342 | 491 _next_in_special_set(NULL), _orig_end(NULL), |
355 | 492 _claimed(InitialClaimValue), _evacuation_failed(false), |
6011 | 493 _prev_marked_bytes(0), _next_marked_bytes(0), _gc_efficiency(0.0), |
342 | 494 _young_type(NotYoung), _next_young_region(NULL), |
2152 | 495 _next_dirty_cards_region(NULL), _next(NULL), _pending_removal(false), |
496 #ifdef ASSERT | |
497 _containing_set(NULL), | |
498 #endif // ASSERT | |
499 _young_index_in_cset(-1), _surv_rate_group(NULL), _age_index(-1), | |
500 _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
|
501 _predicted_bytes_to_copy(0) |
342 | 502 { |
503 _orig_end = mr.end(); | |
504 // Note that initialize() will set the start of the unmarked area of the | |
505 // region. | |
6754
8fbf05030e24
7016955: G1: remove the is_zeroed parameter from the HeapRegion constructor
johnc
parents:
6725
diff
changeset
|
506 hr_clear(false /*par*/, false /*clear_space*/); |
356 | 507 set_top(bottom()); |
508 set_saved_mark(); | |
342 | 509 |
510 _rem_set = new HeapRegionRemSet(sharedOffsetArray, this); | |
511 | |
512 assert(HeapRegionRemSet::num_par_rem_sets() > 0, "Invariant."); | |
513 } | |
514 | |
6254
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6027
diff
changeset
|
515 CompactibleSpace* HeapRegion::next_compaction_space() const { |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6027
diff
changeset
|
516 // We're not using an iterator given that it will wrap around when |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6027
diff
changeset
|
517 // it reaches the last region and this is not what we want here. |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6027
diff
changeset
|
518 G1CollectedHeap* g1h = G1CollectedHeap::heap(); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6027
diff
changeset
|
519 uint index = hrs_index() + 1; |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6027
diff
changeset
|
520 while (index < g1h->n_regions()) { |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6027
diff
changeset
|
521 HeapRegion* hr = g1h->region_at(index); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6027
diff
changeset
|
522 if (!hr->isHumongous()) { |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6027
diff
changeset
|
523 return hr; |
342 | 524 } |
6254
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6027
diff
changeset
|
525 index += 1; |
342 | 526 } |
6254
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6027
diff
changeset
|
527 return NULL; |
342 | 528 } |
529 | |
530 void HeapRegion::save_marks() { | |
531 set_saved_mark(); | |
532 } | |
533 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6611
diff
changeset
|
534 void HeapRegion::oops_in_mr_iterate(MemRegion mr, ExtendedOopClosure* cl) { |
342 | 535 HeapWord* p = mr.start(); |
536 HeapWord* e = mr.end(); | |
537 oop obj; | |
538 while (p < e) { | |
539 obj = oop(p); | |
540 p += obj->oop_iterate(cl); | |
541 } | |
542 assert(p == e, "bad memregion: doesn't end on obj boundary"); | |
543 } | |
544 | |
545 #define HeapRegion_OOP_SINCE_SAVE_MARKS_DEFN(OopClosureType, nv_suffix) \ | |
546 void HeapRegion::oop_since_save_marks_iterate##nv_suffix(OopClosureType* cl) { \ | |
547 ContiguousSpace::oop_since_save_marks_iterate##nv_suffix(cl); \ | |
548 } | |
549 SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(HeapRegion_OOP_SINCE_SAVE_MARKS_DEFN) | |
550 | |
551 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6611
diff
changeset
|
552 void HeapRegion::oop_before_save_marks_iterate(ExtendedOopClosure* cl) { |
342 | 553 oops_in_mr_iterate(MemRegion(bottom(), saved_mark_word()), cl); |
554 } | |
555 | |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
556 void HeapRegion::note_self_forwarding_removal_start(bool during_initial_mark, |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
557 bool during_conc_mark) { |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
558 // We always recreate the prev marking info and we'll explicitly |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
559 // mark all objects we find to be self-forwarded on the prev |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
560 // bitmap. So all objects need to be below PTAMS. |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
561 _prev_top_at_mark_start = top(); |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
562 _prev_marked_bytes = 0; |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
563 |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
564 if (during_initial_mark) { |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
565 // During initial-mark, we'll also explicitly mark all objects |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
566 // we find to be self-forwarded on the next bitmap. So all |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
567 // objects need to be below NTAMS. |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
568 _next_top_at_mark_start = top(); |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
569 _next_marked_bytes = 0; |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
570 } else if (during_conc_mark) { |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
571 // During concurrent mark, all objects in the CSet (including |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
572 // the ones we find to be self-forwarded) are implicitly live. |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
573 // So all objects need to be above NTAMS. |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
574 _next_top_at_mark_start = bottom(); |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
575 _next_marked_bytes = 0; |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
576 } |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
577 } |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
578 |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
579 void HeapRegion::note_self_forwarding_removal_end(bool during_initial_mark, |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
580 bool during_conc_mark, |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
581 size_t marked_bytes) { |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
582 assert(0 <= marked_bytes && marked_bytes <= used(), |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
583 err_msg("marked: "SIZE_FORMAT" used: "SIZE_FORMAT, |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
584 marked_bytes, used())); |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
585 _prev_marked_bytes = marked_bytes; |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
586 } |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4725
diff
changeset
|
587 |
342 | 588 HeapWord* |
589 HeapRegion::object_iterate_mem_careful(MemRegion mr, | |
590 ObjectClosure* cl) { | |
591 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
592 // We used to use "block_start_careful" here. But we're actually happy | |
593 // to update the BOT while we do this... | |
594 HeapWord* cur = block_start(mr.start()); | |
595 mr = mr.intersection(used_region()); | |
596 if (mr.is_empty()) return NULL; | |
597 // Otherwise, find the obj that extends onto mr.start(). | |
598 | |
599 assert(cur <= mr.start() | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
600 && (oop(cur)->klass_or_null() == NULL || |
342 | 601 cur + oop(cur)->size() > mr.start()), |
602 "postcondition of block_start"); | |
603 oop obj; | |
604 while (cur < mr.end()) { | |
605 obj = oop(cur); | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
606 if (obj->klass_or_null() == NULL) { |
342 | 607 // Ran into an unparseable point. |
608 return cur; | |
609 } else if (!g1h->is_obj_dead(obj)) { | |
610 cl->do_object(obj); | |
611 } | |
612 if (cl->abort()) return cur; | |
613 // The check above must occur before the operation below, since an | |
614 // abort might invalidate the "size" operation. | |
615 cur += obj->size(); | |
616 } | |
617 return NULL; | |
618 } | |
619 | |
620 HeapWord* | |
621 HeapRegion:: | |
622 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
|
623 FilterOutOfRegionClosure* cl, |
3317
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
624 bool filter_young, |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
625 jbyte* card_ptr) { |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
626 // Currently, we should only have to clean the card if filter_young |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
627 // is true and vice versa. |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
628 if (filter_young) { |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
629 assert(card_ptr != NULL, "pre-condition"); |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
630 } else { |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
631 assert(card_ptr == NULL, "pre-condition"); |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
632 } |
342 | 633 G1CollectedHeap* g1h = G1CollectedHeap::heap(); |
634 | |
635 // If we're within a stop-world GC, then we might look at a card in a | |
636 // GC alloc region that extends onto a GC LAB, which may not be | |
637 // parseable. Stop such at the "saved_mark" of the region. | |
4839 | 638 if (g1h->is_gc_active()) { |
342 | 639 mr = mr.intersection(used_region_at_save_marks()); |
640 } else { | |
641 mr = mr.intersection(used_region()); | |
642 } | |
643 if (mr.is_empty()) return NULL; | |
644 // Otherwise, find the obj that extends onto mr.start(). | |
645 | |
1666
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
646 // 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
|
647 // 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
|
648 // 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
|
649 // 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
|
650 // 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
|
651 // 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
|
652 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
|
653 return NULL; |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
654 } |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1552
diff
changeset
|
655 |
1705 | 656 assert(!is_young(), "check value of filter_young"); |
657 | |
3317
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
658 // We can only clean the card here, after we make the decision that |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
659 // the card is not young. And we only clean the card if we have been |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
660 // asked to (i.e., card_ptr != NULL). |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
661 if (card_ptr != NULL) { |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
662 *card_ptr = CardTableModRefBS::clean_card_val(); |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
663 // We must complete this write before we do any of the reads below. |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
664 OrderAccess::storeload(); |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
665 } |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
2433
diff
changeset
|
666 |
4839 | 667 // Cache the boundaries of the memory region in some const locals |
668 HeapWord* const start = mr.start(); | |
669 HeapWord* const end = mr.end(); | |
670 | |
342 | 671 // We used to use "block_start_careful" here. But we're actually happy |
672 // to update the BOT while we do this... | |
4839 | 673 HeapWord* cur = block_start(start); |
674 assert(cur <= start, "Postcondition"); | |
675 | |
676 oop obj; | |
342 | 677 |
4839 | 678 HeapWord* next = cur; |
679 while (next <= start) { | |
680 cur = next; | |
681 obj = oop(cur); | |
682 if (obj->klass_or_null() == NULL) { | |
342 | 683 // Ran into an unparseable point. |
684 return cur; | |
685 } | |
686 // Otherwise... | |
4839 | 687 next = (cur + obj->size()); |
342 | 688 } |
4839 | 689 |
690 // If we finish the above loop...We have a parseable object that | |
691 // begins on or before the start of the memory region, and ends | |
692 // inside or spans the entire region. | |
693 | |
694 assert(obj == oop(cur), "sanity"); | |
695 assert(cur <= start && | |
696 obj->klass_or_null() != NULL && | |
697 (cur + obj->size()) > start, | |
342 | 698 "Loop postcondition"); |
4839 | 699 |
342 | 700 if (!g1h->is_obj_dead(obj)) { |
701 obj->oop_iterate(cl, mr); | |
702 } | |
703 | |
4839 | 704 while (cur < end) { |
342 | 705 obj = oop(cur); |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
706 if (obj->klass_or_null() == NULL) { |
342 | 707 // Ran into an unparseable point. |
708 return cur; | |
709 }; | |
4839 | 710 |
342 | 711 // Otherwise: |
712 next = (cur + obj->size()); | |
4839 | 713 |
342 | 714 if (!g1h->is_obj_dead(obj)) { |
4839 | 715 if (next < end || !obj->is_objArray()) { |
716 // This object either does not span the MemRegion | |
717 // boundary, or if it does it's not an array. | |
718 // Apply closure to whole object. | |
342 | 719 obj->oop_iterate(cl); |
720 } else { | |
4839 | 721 // This obj is an array that spans the boundary. |
722 // Stop at the boundary. | |
723 obj->oop_iterate(cl, mr); | |
342 | 724 } |
725 } | |
726 cur = next; | |
727 } | |
728 return NULL; | |
729 } | |
730 | |
731 void HeapRegion::print() const { print_on(gclog_or_tty); } | |
732 void HeapRegion::print_on(outputStream* st) const { | |
733 if (isHumongous()) { | |
734 if (startsHumongous()) | |
735 st->print(" HS"); | |
736 else | |
737 st->print(" HC"); | |
738 } else { | |
739 st->print(" "); | |
740 } | |
741 if (in_collection_set()) | |
742 st->print(" CS"); | |
743 else | |
744 st->print(" "); | |
745 if (is_young()) | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1388
diff
changeset
|
746 st->print(is_survivor() ? " SU" : " Y "); |
342 | 747 else |
748 st->print(" "); | |
749 if (is_empty()) | |
750 st->print(" F"); | |
751 else | |
752 st->print(" "); | |
4073
53074c2c4600
7099849: G1: include heap region information in hs_err files
tonyp
parents:
4023
diff
changeset
|
753 st->print(" TS %5d", _gc_time_stamp); |
1388 | 754 st->print(" PTAMS "PTR_FORMAT" NTAMS "PTR_FORMAT, |
755 prev_top_at_mark_start(), next_top_at_mark_start()); | |
342 | 756 G1OffsetTableContigSpace::print_on(st); |
757 } | |
758 | |
6008 | 759 void HeapRegion::verify() const { |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
760 bool dummy = false; |
6008 | 761 verify(VerifyOption_G1UsePrevMarking, /* failures */ &dummy); |
811 | 762 } |
763 | |
342 | 764 // This really ought to be commoned up into OffsetTableContigSpace somehow. |
765 // We would need a mechanism to make that code skip dead objects. | |
766 | |
6008 | 767 void HeapRegion::verify(VerifyOption vo, |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
768 bool* failures) const { |
342 | 769 G1CollectedHeap* g1 = G1CollectedHeap::heap(); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
770 *failures = false; |
342 | 771 HeapWord* p = bottom(); |
772 HeapWord* prev_p = NULL; | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
773 VerifyLiveClosure vl_cl(g1, vo); |
1718
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
774 bool is_humongous = isHumongous(); |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
775 bool do_bot_verify = !is_young(); |
1718
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
776 size_t object_num = 0; |
342 | 777 while (p < top()) { |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
778 oop obj = oop(p); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
779 size_t obj_size = obj->size(); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
780 object_num += 1; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
781 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
782 if (is_humongous != g1->isHumongous(obj_size)) { |
1718
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
783 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
|
784 SIZE_FORMAT" words) in a %shumongous region", |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
785 p, g1->isHumongous(obj_size) ? "" : "non-", |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
786 obj_size, is_humongous ? "" : "non-"); |
1718
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
787 *failures = true; |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
788 return; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
789 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
790 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
791 // If it returns false, verify_for_object() will output the |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
792 // appropriate messasge. |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
793 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
|
794 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
795 return; |
1718
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
796 } |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
797 |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
798 if (!g1->is_obj_dead_cond(obj, this, vo)) { |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
799 if (obj->is_oop()) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6611
diff
changeset
|
800 Klass* klass = obj->klass(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6611
diff
changeset
|
801 if (!klass->is_metadata()) { |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
802 gclog_or_tty->print_cr("klass "PTR_FORMAT" of object "PTR_FORMAT" " |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6611
diff
changeset
|
803 "not metadata", klass, obj); |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
804 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
805 return; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
806 } else if (!klass->is_klass()) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
807 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
|
808 "not a klass", klass, obj); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
809 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
810 return; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
811 } else { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
812 vl_cl.set_containing_obj(obj); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6611
diff
changeset
|
813 obj->oop_iterate_no_header(&vl_cl); |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
814 if (vl_cl.failures()) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
815 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
816 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
817 if (G1MaxVerifyFailures >= 0 && |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
818 vl_cl.n_failures() >= G1MaxVerifyFailures) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
819 return; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
820 } |
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 } else { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
823 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
|
824 *failures = true; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
825 return; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
826 } |
342 | 827 } |
828 prev_p = p; | |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
829 p += obj_size; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
830 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
831 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
832 if (p != top()) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
833 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
|
834 "does not match top "PTR_FORMAT, p, top()); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
835 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
836 return; |
342 | 837 } |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
838 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
839 HeapWord* the_end = end(); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
840 assert(p == top(), "it should still hold"); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
841 // 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
|
842 // 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
|
843 // 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
|
844 if (p < the_end) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
845 // Look up top |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
846 HeapWord* addr_1 = p; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
847 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
|
848 if (b_start_1 != p) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
849 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
|
850 " yielded "PTR_FORMAT", expecting "PTR_FORMAT, |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
851 addr_1, b_start_1, p); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
852 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
853 return; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
854 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
855 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
856 // Look up top + 1 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
857 HeapWord* addr_2 = p + 1; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
858 if (addr_2 < the_end) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
859 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
|
860 if (b_start_2 != p) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
861 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
|
862 " yielded "PTR_FORMAT", expecting "PTR_FORMAT, |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
863 addr_2, b_start_2, p); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
864 *failures = true; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
865 return; |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
866 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
867 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
868 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
869 // Look up an address between top and end |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
870 size_t diff = pointer_delta(the_end, p) / 2; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
871 HeapWord* addr_3 = p + diff; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
872 if (addr_3 < the_end) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
873 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
|
874 if (b_start_3 != p) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
875 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
|
876 " yielded "PTR_FORMAT", expecting "PTR_FORMAT, |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
877 addr_3, b_start_3, p); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
878 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
879 return; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
880 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
881 } |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
882 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
883 // Loook up end - 1 |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
884 HeapWord* addr_4 = the_end - 1; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
885 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
|
886 if (b_start_4 != p) { |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
887 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
|
888 " yielded "PTR_FORMAT", expecting "PTR_FORMAT, |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
889 addr_4, b_start_4, p); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
890 *failures = true; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
1972
diff
changeset
|
891 return; |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
892 } |
342 | 893 } |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
894 |
1718
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
895 if (is_humongous && object_num > 1) { |
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
896 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
|
897 "but has "SIZE_FORMAT", objects", |
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
898 bottom(), end(), object_num); |
bb847e31b836
6974928: G1: sometimes humongous objects are allocated in young regions
tonyp
parents:
1705
diff
changeset
|
899 *failures = true; |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
942
diff
changeset
|
900 return; |
342 | 901 } |
902 } | |
903 | |
904 // G1OffsetTableContigSpace code; copied from space.cpp. Hope this can go | |
905 // away eventually. | |
906 | |
356 | 907 void G1OffsetTableContigSpace::clear(bool mangle_space) { |
908 ContiguousSpace::clear(mangle_space); | |
342 | 909 _offsets.zero_bottom_entry(); |
910 _offsets.initialize_threshold(); | |
911 } | |
912 | |
913 void G1OffsetTableContigSpace::set_bottom(HeapWord* new_bottom) { | |
914 Space::set_bottom(new_bottom); | |
915 _offsets.set_bottom(new_bottom); | |
916 } | |
917 | |
918 void G1OffsetTableContigSpace::set_end(HeapWord* new_end) { | |
919 Space::set_end(new_end); | |
920 _offsets.resize(new_end - bottom()); | |
921 } | |
922 | |
923 void G1OffsetTableContigSpace::print() const { | |
924 print_short(); | |
925 gclog_or_tty->print_cr(" [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " | |
926 INTPTR_FORMAT ", " INTPTR_FORMAT ")", | |
927 bottom(), top(), _offsets.threshold(), end()); | |
928 } | |
929 | |
930 HeapWord* G1OffsetTableContigSpace::initialize_threshold() { | |
931 return _offsets.initialize_threshold(); | |
932 } | |
933 | |
934 HeapWord* G1OffsetTableContigSpace::cross_threshold(HeapWord* start, | |
935 HeapWord* end) { | |
936 _offsets.alloc_block(start, end); | |
937 return _offsets.threshold(); | |
938 } | |
939 | |
940 HeapWord* G1OffsetTableContigSpace::saved_mark_word() const { | |
941 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
942 assert( _gc_time_stamp <= g1h->get_gc_time_stamp(), "invariant" ); | |
943 if (_gc_time_stamp < g1h->get_gc_time_stamp()) | |
944 return top(); | |
945 else | |
946 return ContiguousSpace::saved_mark_word(); | |
947 } | |
948 | |
949 void G1OffsetTableContigSpace::set_saved_mark() { | |
950 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
951 unsigned curr_gc_time_stamp = g1h->get_gc_time_stamp(); | |
952 | |
953 if (_gc_time_stamp < curr_gc_time_stamp) { | |
954 // The order of these is important, as another thread might be | |
955 // about to start scanning this region. If it does so after | |
956 // set_saved_mark and before _gc_time_stamp = ..., then the latter | |
957 // will be false, and it will pick up top() as the high water mark | |
958 // of region. If it does so after _gc_time_stamp = ..., then it | |
959 // will pick up the right saved_mark_word() as the high water mark | |
960 // of the region. Either way, the behaviour will be correct. | |
961 ContiguousSpace::set_saved_mark(); | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
962 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
|
963 _gc_time_stamp = curr_gc_time_stamp; |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2152
diff
changeset
|
964 // 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
|
965 // 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
|
966 // 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
|
967 // 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
|
968 // flushed. |
342 | 969 } |
970 } | |
971 | |
972 G1OffsetTableContigSpace:: | |
973 G1OffsetTableContigSpace(G1BlockOffsetSharedArray* sharedOffsetArray, | |
6754
8fbf05030e24
7016955: G1: remove the is_zeroed parameter from the HeapRegion constructor
johnc
parents:
6725
diff
changeset
|
974 MemRegion mr) : |
342 | 975 _offsets(sharedOffsetArray, mr), |
976 _par_alloc_lock(Mutex::leaf, "OffsetTableContigSpace par alloc lock", true), | |
977 _gc_time_stamp(0) | |
978 { | |
979 _offsets.set_space(this); | |
6754
8fbf05030e24
7016955: G1: remove the is_zeroed parameter from the HeapRegion constructor
johnc
parents:
6725
diff
changeset
|
980 // false ==> we'll do the clearing if there's clearing to be done. |
8fbf05030e24
7016955: G1: remove the is_zeroed parameter from the HeapRegion constructor
johnc
parents:
6725
diff
changeset
|
981 ContiguousSpace::initialize(mr, false, SpaceDecorator::Mangle); |
8fbf05030e24
7016955: G1: remove the is_zeroed parameter from the HeapRegion constructor
johnc
parents:
6725
diff
changeset
|
982 _offsets.zero_bottom_entry(); |
8fbf05030e24
7016955: G1: remove the is_zeroed parameter from the HeapRegion constructor
johnc
parents:
6725
diff
changeset
|
983 _offsets.initialize_threshold(); |
342 | 984 } |