Mercurial > hg > truffle
annotate src/share/vm/gc_implementation/g1/heapRegionSet.hpp @ 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 | a2f7274eb6ef |
children | 58fc1b1523dc |
rev | line source |
---|---|
2152 | 1 /* |
4830
0b3d1ec6eaee
7097586: G1: improve the per-space output when using jmap -heap
tonyp
parents:
4072
diff
changeset
|
2 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. |
2152 | 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 * | |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
20 * or visit www.oracle.com if you need additional information or have any | |
21 * questions. | |
22 * | |
23 */ | |
24 | |
25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSET_HPP | |
26 #define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSET_HPP | |
27 | |
28 #include "gc_implementation/g1/heapRegion.hpp" | |
29 | |
30 // Large buffer for some cases where the output might be larger than normal. | |
2361 | 31 #define HRS_ERR_MSG_BUFSZ 512 |
32 typedef FormatBuffer<HRS_ERR_MSG_BUFSZ> hrs_err_msg; | |
2152 | 33 |
34 // Set verification will be forced either if someone defines | |
35 // HEAP_REGION_SET_FORCE_VERIFY to be 1, or in builds in which | |
36 // asserts are compiled in. | |
37 #ifndef HEAP_REGION_SET_FORCE_VERIFY | |
38 #define HEAP_REGION_SET_FORCE_VERIFY defined(ASSERT) | |
39 #endif // HEAP_REGION_SET_FORCE_VERIFY | |
40 | |
41 //////////////////// HeapRegionSetBase //////////////////// | |
42 | |
43 // Base class for all the classes that represent heap region sets. It | |
44 // contains the basic attributes that each set needs to maintain | |
45 // (e.g., length, region num, used bytes sum) plus any shared | |
46 // functionality (e.g., verification). | |
47 | |
2361 | 48 class hrs_ext_msg; |
2152 | 49 |
4072 | 50 typedef enum { |
51 HRSPhaseNone, | |
52 HRSPhaseEvacuation, | |
53 HRSPhaseCleanup, | |
54 HRSPhaseFullGC | |
55 } HRSPhase; | |
56 | |
57 class HRSPhaseSetter; | |
58 | |
2152 | 59 class HeapRegionSetBase VALUE_OBJ_CLASS_SPEC { |
2361 | 60 friend class hrs_ext_msg; |
4072 | 61 friend class HRSPhaseSetter; |
4830
0b3d1ec6eaee
7097586: G1: improve the per-space output when using jmap -heap
tonyp
parents:
4072
diff
changeset
|
62 friend class VMStructs; |
2152 | 63 |
64 protected: | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4830
diff
changeset
|
65 static uint _unrealistically_long_length; |
2152 | 66 |
67 // The number of regions added to the set. If the set contains | |
68 // only humongous regions, this reflects only 'starts humongous' | |
69 // regions and does not include 'continues humongous' ones. | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4830
diff
changeset
|
70 uint _length; |
2152 | 71 |
72 // The total number of regions represented by the set. If the set | |
73 // does not contain humongous regions, this should be the same as | |
74 // _length. If the set contains only humongous regions, this will | |
75 // include the 'continues humongous' regions. | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4830
diff
changeset
|
76 uint _region_num; |
2152 | 77 |
78 // We don't keep track of the total capacity explicitly, we instead | |
79 // recalculate it based on _region_num and the heap region size. | |
80 | |
81 // The sum of used bytes in the all the regions in the set. | |
82 size_t _total_used_bytes; | |
83 | |
84 const char* _name; | |
85 | |
86 bool _verify_in_progress; | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4830
diff
changeset
|
87 uint _calc_length; |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4830
diff
changeset
|
88 uint _calc_region_num; |
2152 | 89 size_t _calc_total_capacity_bytes; |
90 size_t _calc_total_used_bytes; | |
91 | |
4072 | 92 // This is here so that it can be used in the subclasses to assert |
93 // something different depending on which phase the GC is in. This | |
94 // can be particularly helpful in the check_mt_safety() methods. | |
95 static HRSPhase _phase; | |
96 | |
97 // Only used by HRSPhaseSetter. | |
98 static void clear_phase(); | |
99 static void set_phase(HRSPhase phase); | |
100 | |
2152 | 101 // verify_region() is used to ensure that the contents of a region |
102 // added to / removed from a set are consistent. Different sets | |
103 // make different assumptions about the regions added to them. So | |
104 // each set can override verify_region_extra(), which is called | |
105 // from verify_region(), and do any extra verification it needs to | |
106 // perform in that. | |
107 virtual const char* verify_region_extra(HeapRegion* hr) { return NULL; } | |
108 bool verify_region(HeapRegion* hr, | |
109 HeapRegionSetBase* expected_containing_set); | |
110 | |
111 // Indicates whether all regions in the set should be humongous or | |
112 // not. Only used during verification. | |
113 virtual bool regions_humongous() = 0; | |
114 | |
115 // Indicates whether all regions in the set should be empty or | |
116 // not. Only used during verification. | |
117 virtual bool regions_empty() = 0; | |
118 | |
119 // Subclasses can optionally override this to do MT safety protocol | |
120 // checks. It is called in an assert from all methods that perform | |
121 // updates on the set (and subclasses should also call it too). | |
122 virtual bool check_mt_safety() { return true; } | |
123 | |
124 // fill_in_ext_msg() writes the the values of the set's attributes | |
2361 | 125 // in the custom err_msg (hrs_ext_msg). fill_in_ext_msg_extra() |
2152 | 126 // allows subclasses to append further information. |
2361 | 127 virtual void fill_in_ext_msg_extra(hrs_ext_msg* msg) { } |
128 void fill_in_ext_msg(hrs_ext_msg* msg, const char* message); | |
2152 | 129 |
130 // It updates the fields of the set to reflect hr being added to | |
131 // the set. | |
132 inline void update_for_addition(HeapRegion* hr); | |
133 | |
134 // It updates the fields of the set to reflect hr being added to | |
135 // the set and tags the region appropriately. | |
136 inline void add_internal(HeapRegion* hr); | |
137 | |
138 // It updates the fields of the set to reflect hr being removed | |
139 // from the set. | |
140 inline void update_for_removal(HeapRegion* hr); | |
141 | |
142 // It updates the fields of the set to reflect hr being removed | |
143 // from the set and tags the region appropriately. | |
144 inline void remove_internal(HeapRegion* hr); | |
145 | |
146 // It clears all the fields of the sets. Note: it will not iterate | |
147 // over the set and remove regions from it. It assumes that the | |
148 // caller has already done so. It will literally just clear the fields. | |
149 virtual void clear(); | |
150 | |
151 HeapRegionSetBase(const char* name); | |
152 | |
153 public: | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4830
diff
changeset
|
154 static void set_unrealistically_long_length(uint len); |
2152 | 155 |
156 const char* name() { return _name; } | |
157 | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4830
diff
changeset
|
158 uint length() { return _length; } |
2152 | 159 |
160 bool is_empty() { return _length == 0; } | |
161 | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4830
diff
changeset
|
162 uint region_num() { return _region_num; } |
2152 | 163 |
164 size_t total_capacity_bytes() { | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4830
diff
changeset
|
165 return (size_t) region_num() << HeapRegion::LogOfHRGrainBytes; |
2152 | 166 } |
167 | |
168 size_t total_used_bytes() { return _total_used_bytes; } | |
169 | |
170 virtual void verify(); | |
171 void verify_start(); | |
172 void verify_next_region(HeapRegion* hr); | |
173 void verify_end(); | |
174 | |
175 #if HEAP_REGION_SET_FORCE_VERIFY | |
176 void verify_optional() { | |
177 verify(); | |
178 } | |
179 #else // HEAP_REGION_SET_FORCE_VERIFY | |
180 void verify_optional() { } | |
181 #endif // HEAP_REGION_SET_FORCE_VERIFY | |
182 | |
183 virtual void print_on(outputStream* out, bool print_contents = false); | |
184 }; | |
185 | |
186 // Customized err_msg for heap region sets. Apart from a | |
187 // assert/guarantee-specific message it also prints out the values of | |
188 // the fields of the associated set. This can be very helpful in | |
189 // diagnosing failures. | |
190 | |
2361 | 191 class hrs_ext_msg : public hrs_err_msg { |
2152 | 192 public: |
2361 | 193 hrs_ext_msg(HeapRegionSetBase* set, const char* message) : hrs_err_msg("") { |
2152 | 194 set->fill_in_ext_msg(this, message); |
195 } | |
196 }; | |
197 | |
4072 | 198 class HRSPhaseSetter { |
199 public: | |
200 HRSPhaseSetter(HRSPhase phase) { | |
201 HeapRegionSetBase::set_phase(phase); | |
202 } | |
203 ~HRSPhaseSetter() { | |
204 HeapRegionSetBase::clear_phase(); | |
205 } | |
206 }; | |
207 | |
2152 | 208 // These two macros are provided for convenience, to keep the uses of |
209 // these two asserts a bit more concise. | |
210 | |
2361 | 211 #define hrs_assert_mt_safety_ok(_set_) \ |
2152 | 212 do { \ |
2361 | 213 assert((_set_)->check_mt_safety(), hrs_ext_msg((_set_), "MT safety")); \ |
2152 | 214 } while (0) |
215 | |
2361 | 216 #define hrs_assert_region_ok(_set_, _hr_, _expected_) \ |
2152 | 217 do { \ |
218 assert((_set_)->verify_region((_hr_), (_expected_)), \ | |
2361 | 219 hrs_ext_msg((_set_), "region verification")); \ |
2152 | 220 } while (0) |
221 | |
222 //////////////////// HeapRegionSet //////////////////// | |
223 | |
2361 | 224 #define hrs_assert_sets_match(_set1_, _set2_) \ |
2152 | 225 do { \ |
226 assert(((_set1_)->regions_humongous() == \ | |
227 (_set2_)->regions_humongous()) && \ | |
228 ((_set1_)->regions_empty() == (_set2_)->regions_empty()), \ | |
2361 | 229 hrs_err_msg("the contents of set %s and set %s should match", \ |
2152 | 230 (_set1_)->name(), (_set2_)->name())); \ |
231 } while (0) | |
232 | |
233 // This class represents heap region sets whose members are not | |
234 // explicitly tracked. It's helpful to group regions using such sets | |
235 // so that we can reason about all the region groups in the heap using | |
236 // the same interface (namely, the HeapRegionSetBase API). | |
237 | |
238 class HeapRegionSet : public HeapRegionSetBase { | |
239 protected: | |
240 virtual const char* verify_region_extra(HeapRegion* hr) { | |
241 if (hr->next() != NULL) { | |
242 return "next() should always be NULL as we do not link the regions"; | |
243 } | |
244 | |
245 return HeapRegionSetBase::verify_region_extra(hr); | |
246 } | |
247 | |
248 HeapRegionSet(const char* name) : HeapRegionSetBase(name) { | |
249 clear(); | |
250 } | |
251 | |
252 public: | |
253 // It adds hr to the set. The region should not be a member of | |
254 // another set. | |
255 inline void add(HeapRegion* hr); | |
256 | |
257 // It removes hr from the set. The region should be a member of | |
258 // this set. | |
259 inline void remove(HeapRegion* hr); | |
260 | |
261 // It removes a region from the set. Instead of updating the fields | |
262 // of the set to reflect this removal, it accumulates the updates | |
263 // in proxy_set. The idea is that proxy_set is thread-local to | |
264 // avoid multiple threads updating the fields of the set | |
265 // concurrently and having to synchronize. The method | |
266 // update_from_proxy() will update the fields of the set from the | |
267 // proxy_set. | |
268 inline void remove_with_proxy(HeapRegion* hr, HeapRegionSet* proxy_set); | |
269 | |
270 // After multiple calls to remove_with_proxy() the updates to the | |
271 // fields of the set are accumulated in proxy_set. This call | |
272 // updates the fields of the set from proxy_set. | |
273 void update_from_proxy(HeapRegionSet* proxy_set); | |
274 }; | |
275 | |
276 //////////////////// HeapRegionLinkedList //////////////////// | |
277 | |
278 // A set that links all the regions added to it in a singly-linked | |
279 // list. We should try to avoid doing operations that iterate over | |
280 // such lists in performance critical paths. Typically we should | |
281 // add / remove one region at a time or concatenate two lists. All | |
282 // those operations are done in constant time. | |
283 | |
284 class HeapRegionLinkedListIterator; | |
285 | |
286 class HeapRegionLinkedList : public HeapRegionSetBase { | |
287 friend class HeapRegionLinkedListIterator; | |
288 | |
289 private: | |
290 HeapRegion* _head; | |
291 HeapRegion* _tail; | |
292 | |
293 // These are provided for use by the friend classes. | |
294 HeapRegion* head() { return _head; } | |
295 HeapRegion* tail() { return _tail; } | |
296 | |
297 protected: | |
2361 | 298 virtual void fill_in_ext_msg_extra(hrs_ext_msg* msg); |
2152 | 299 |
300 // See the comment for HeapRegionSetBase::clear() | |
301 virtual void clear(); | |
302 | |
303 HeapRegionLinkedList(const char* name) : HeapRegionSetBase(name) { | |
304 clear(); | |
305 } | |
306 | |
307 public: | |
2432
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
308 // It adds hr to the list as the new head. The region should not be |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
309 // a member of another set. |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
310 inline void add_as_head(HeapRegion* hr); |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
311 |
2152 | 312 // It adds hr to the list as the new tail. The region should not be |
313 // a member of another set. | |
314 inline void add_as_tail(HeapRegion* hr); | |
315 | |
316 // It removes and returns the head of the list. It assumes that the | |
317 // list is not empty so it will return a non-NULL value. | |
318 inline HeapRegion* remove_head(); | |
319 | |
320 // Convenience method. | |
321 inline HeapRegion* remove_head_or_null(); | |
322 | |
323 // It moves the regions from from_list to this list and empties | |
324 // from_list. The new regions will appear in the same order as they | |
2432
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
325 // were in from_list and be linked in the beginning of this list. |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
326 void add_as_head(HeapRegionLinkedList* from_list); |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
327 |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
328 // It moves the regions from from_list to this list and empties |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
329 // from_list. The new regions will appear in the same order as they |
2152 | 330 // were in from_list and be linked in the end of this list. |
331 void add_as_tail(HeapRegionLinkedList* from_list); | |
332 | |
333 // It empties the list by removing all regions from it. | |
334 void remove_all(); | |
335 | |
336 // It removes all regions in the list that are pending for removal | |
337 // (i.e., they have been tagged with "pending_removal"). The list | |
338 // must not be empty, target_count should reflect the exact number | |
339 // of regions that are pending for removal in the list, and | |
340 // target_count should be > 1 (currently, we never need to remove a | |
341 // single region using this). | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4830
diff
changeset
|
342 void remove_all_pending(uint target_count); |
2152 | 343 |
344 virtual void verify(); | |
345 | |
346 virtual void print_on(outputStream* out, bool print_contents = false); | |
347 }; | |
348 | |
2361 | 349 //////////////////// HeapRegionLinkedListIterator //////////////////// |
2152 | 350 |
2361 | 351 // Iterator class that provides a convenient way to iterate over the |
352 // regions of a HeapRegionLinkedList instance. | |
2152 | 353 |
354 class HeapRegionLinkedListIterator : public StackObj { | |
355 private: | |
356 HeapRegionLinkedList* _list; | |
357 HeapRegion* _curr; | |
358 | |
359 public: | |
360 bool more_available() { | |
361 return _curr != NULL; | |
362 } | |
363 | |
364 HeapRegion* get_next() { | |
365 assert(more_available(), | |
366 "get_next() should be called when more regions are available"); | |
367 | |
368 // If we are going to introduce a count in the iterator we should | |
369 // do the "cycle" check. | |
370 | |
371 HeapRegion* hr = _curr; | |
372 assert(_list->verify_region(hr, _list), "region verification"); | |
373 _curr = hr->next(); | |
374 return hr; | |
375 } | |
376 | |
377 HeapRegionLinkedListIterator(HeapRegionLinkedList* list) | |
378 : _curr(NULL), _list(list) { | |
379 _curr = list->head(); | |
380 } | |
381 }; | |
382 | |
383 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSET_HPP |