13 *
14 * You should have received a copy of the GNU General Public License version
15 * 2 along with this work; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24 #include "precompiled.hpp"
25 #include "memory/allocation.hpp"
26 #include "gc/shenandoah/shenandoahBrooksPointer.hpp"
27 #include "gc/shenandoah/shenandoahHeapRegionSet.inline.hpp"
28 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
29 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
30 #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
31 #include "gc/shenandoah/shenandoahTraversalGC.hpp"
32 #include "gc/shared/space.inline.hpp"
33 #include "memory/iterator.inline.hpp"
34 #include "memory/resourceArea.hpp"
35 #include "memory/universe.hpp"
36 #include "oops/oop.inline.hpp"
37 #include "runtime/java.hpp"
38 #include "runtime/mutexLocker.hpp"
39 #include "runtime/os.hpp"
40 #include "runtime/safepoint.hpp"
41
42 size_t ShenandoahHeapRegion::RegionCount = 0;
43 size_t ShenandoahHeapRegion::RegionSizeBytes = 0;
44 size_t ShenandoahHeapRegion::RegionSizeWords = 0;
45 size_t ShenandoahHeapRegion::RegionSizeBytesShift = 0;
46 size_t ShenandoahHeapRegion::RegionSizeWordsShift = 0;
47 size_t ShenandoahHeapRegion::RegionSizeBytesMask = 0;
48 size_t ShenandoahHeapRegion::RegionSizeWordsMask = 0;
49 size_t ShenandoahHeapRegion::HumongousThresholdBytes = 0;
50 size_t ShenandoahHeapRegion::HumongousThresholdWords = 0;
51 size_t ShenandoahHeapRegion::MaxTLABSizeBytes = 0;
52 size_t ShenandoahHeapRegion::MaxTLABSizeWords = 0;
77
78 size_t ShenandoahHeapRegion::region_number() const {
79 return _region_number;
80 }
81
82 void ShenandoahHeapRegion::report_illegal_transition(const char *method) {
83 ResourceMark rm;
84 stringStream ss;
85 ss.print("Illegal region state transition from \"%s\", at %s\n ", region_state_to_string(_state), method);
86 print_on(&ss);
87 fatal("%s", ss.as_string());
88 }
89
90 void ShenandoahHeapRegion::make_regular_allocation() {
91 _heap->assert_heaplock_owned_by_current_thread();
92
93 switch (_state) {
94 case _empty_uncommitted:
95 do_commit();
96 case _empty_committed:
97 _state = _regular;
98 case _regular:
99 case _pinned:
100 return;
101 default:
102 report_illegal_transition("regular allocation");
103 }
104 }
105
106 void ShenandoahHeapRegion::make_regular_bypass() {
107 _heap->assert_heaplock_owned_by_current_thread();
108 assert (_heap->is_full_gc_in_progress() || _heap->is_degenerated_gc_in_progress(),
109 "only for full or degen GC");
110
111 switch (_state) {
112 case _empty_uncommitted:
113 do_commit();
114 case _empty_committed:
115 case _cset:
116 case _humongous_start:
117 case _humongous_cont:
118 _state = _regular;
119 return;
120 case _pinned_cset:
121 _state = _pinned;
122 return;
123 case _regular:
124 case _pinned:
125 return;
126 default:
127 report_illegal_transition("regular bypass");
128 }
129 }
130
131 void ShenandoahHeapRegion::make_humongous_start() {
132 _heap->assert_heaplock_owned_by_current_thread();
133 switch (_state) {
134 case _empty_uncommitted:
135 do_commit();
136 case _empty_committed:
137 _state = _humongous_start;
138 return;
139 default:
140 report_illegal_transition("humongous start allocation");
141 }
142 }
143
144 void ShenandoahHeapRegion::make_humongous_start_bypass() {
145 _heap->assert_heaplock_owned_by_current_thread();
146 assert (_heap->is_full_gc_in_progress(), "only for full GC");
147
148 switch (_state) {
149 case _empty_committed:
150 case _regular:
151 case _humongous_start:
152 case _humongous_cont:
153 _state = _humongous_start;
154 return;
155 default:
156 report_illegal_transition("humongous start bypass");
157 }
158 }
159
160 void ShenandoahHeapRegion::make_humongous_cont() {
161 _heap->assert_heaplock_owned_by_current_thread();
162 switch (_state) {
163 case _empty_uncommitted:
164 do_commit();
165 case _empty_committed:
166 _state = _humongous_cont;
167 return;
168 default:
169 report_illegal_transition("humongous continuation allocation");
170 }
171 }
172
173 void ShenandoahHeapRegion::make_humongous_cont_bypass() {
174 _heap->assert_heaplock_owned_by_current_thread();
175 assert (_heap->is_full_gc_in_progress(), "only for full GC");
176
177 switch (_state) {
178 case _empty_committed:
179 case _regular:
180 case _humongous_start:
181 case _humongous_cont:
182 _state = _humongous_cont;
183 return;
184 default:
185 report_illegal_transition("humongous continuation bypass");
186 }
187 }
188
189 void ShenandoahHeapRegion::make_pinned() {
190 _heap->assert_heaplock_owned_by_current_thread();
191 switch (_state) {
192 case _regular:
193 assert (_critical_pins == 0, "sanity");
194 _state = _pinned;
195 case _pinned_cset:
196 case _pinned:
197 _critical_pins++;
198 return;
199 case _humongous_start:
200 assert (_critical_pins == 0, "sanity");
201 _state = _pinned_humongous_start;
202 case _pinned_humongous_start:
203 _critical_pins++;
204 return;
205 case _cset:
206 guarantee(_heap->cancelled_gc(), "only valid when evac has been cancelled");
207 assert (_critical_pins == 0, "sanity");
208 _state = _pinned_cset;
209 _critical_pins++;
210 return;
211 default:
212 report_illegal_transition("pinning");
213 }
214 }
215
216 void ShenandoahHeapRegion::make_unpinned() {
217 _heap->assert_heaplock_owned_by_current_thread();
218 switch (_state) {
219 case _pinned:
220 assert (_critical_pins > 0, "sanity");
221 _critical_pins--;
222 if (_critical_pins == 0) {
223 _state = _regular;
224 }
225 return;
226 case _regular:
227 case _humongous_start:
228 assert (_critical_pins == 0, "sanity");
229 return;
230 case _pinned_cset:
231 guarantee(_heap->cancelled_gc(), "only valid when evac has been cancelled");
232 assert (_critical_pins > 0, "sanity");
233 _critical_pins--;
234 if (_critical_pins == 0) {
235 _state = _cset;
236 }
237 return;
238 case _pinned_humongous_start:
239 assert (_critical_pins > 0, "sanity");
240 _critical_pins--;
241 if (_critical_pins == 0) {
242 _state = _humongous_start;
243 }
244 return;
245 default:
246 report_illegal_transition("unpinning");
247 }
248 }
249
250 void ShenandoahHeapRegion::make_cset() {
251 _heap->assert_heaplock_owned_by_current_thread();
252 switch (_state) {
253 case _regular:
254 _state = _cset;
255 case _cset:
256 return;
257 default:
258 report_illegal_transition("cset");
259 }
260 }
261
262 void ShenandoahHeapRegion::make_trash() {
263 _heap->assert_heaplock_owned_by_current_thread();
264 switch (_state) {
265 case _cset:
266 // Reclaiming cset regions
267 case _humongous_start:
268 case _humongous_cont:
269 // Reclaiming humongous regions
270 case _regular:
271 // Immediate region reclaim
272 _state = _trash;
273 return;
274 default:
275 report_illegal_transition("trashing");
276 }
277 }
278
279 void ShenandoahHeapRegion::make_trash_immediate() {
280 make_trash();
281
282 // On this path, we know there are no marked objects in the region,
283 // tell marking context about it to bypass bitmap resets.
284 _heap->complete_marking_context()->reset_top_bitmap(this);
285 }
286
287 void ShenandoahHeapRegion::make_empty() {
288 _heap->assert_heaplock_owned_by_current_thread();
289 switch (_state) {
290 case _trash:
291 _state = _empty_committed;
292 _empty_time = os::elapsedTime();
293 return;
294 default:
295 report_illegal_transition("emptying");
296 }
297 }
298
299 void ShenandoahHeapRegion::make_uncommitted() {
300 _heap->assert_heaplock_owned_by_current_thread();
301 switch (_state) {
302 case _empty_committed:
303 do_uncommit();
304 _state = _empty_uncommitted;
305 return;
306 default:
307 report_illegal_transition("uncommiting");
308 }
309 }
310
311 void ShenandoahHeapRegion::make_committed_bypass() {
312 _heap->assert_heaplock_owned_by_current_thread();
313 assert (_heap->is_full_gc_in_progress(), "only for full GC");
314
315 switch (_state) {
316 case _empty_uncommitted:
317 do_commit();
318 _state = _empty_committed;
319 return;
320 default:
321 report_illegal_transition("commit bypass");
322 }
323 }
324
325 void ShenandoahHeapRegion::clear_live_data() {
326 OrderAccess::release_store_fence<size_t>(&_live_data, 0);
327 }
328
329 void ShenandoahHeapRegion::reset_alloc_metadata() {
330 _tlab_allocs = 0;
331 _gclab_allocs = 0;
332 _shared_allocs = 0;
333 _seqnum_first_alloc_mutator = 0;
334 _seqnum_last_alloc_mutator = 0;
335 _seqnum_first_alloc_gc = 0;
336 _seqnum_last_alloc_gc = 0;
337 }
338
660 }
661
662 void ShenandoahHeapRegion::do_commit() {
663 if (!os::commit_memory((char *) _reserved.start(), _reserved.byte_size(), false)) {
664 report_java_out_of_memory("Unable to commit region");
665 }
666 if (!_heap->commit_bitmap_slice(this)) {
667 report_java_out_of_memory("Unable to commit bitmaps for region");
668 }
669 _heap->increase_committed(ShenandoahHeapRegion::region_size_bytes());
670 }
671
672 void ShenandoahHeapRegion::do_uncommit() {
673 if (!os::uncommit_memory((char *) _reserved.start(), _reserved.byte_size())) {
674 report_java_out_of_memory("Unable to uncommit region");
675 }
676 if (!_heap->uncommit_bitmap_slice(this)) {
677 report_java_out_of_memory("Unable to uncommit bitmaps for region");
678 }
679 _heap->decrease_committed(ShenandoahHeapRegion::region_size_bytes());
680 }
|
13 *
14 * You should have received a copy of the GNU General Public License version
15 * 2 along with this work; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24 #include "precompiled.hpp"
25 #include "memory/allocation.hpp"
26 #include "gc/shenandoah/shenandoahBrooksPointer.hpp"
27 #include "gc/shenandoah/shenandoahHeapRegionSet.inline.hpp"
28 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
29 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
30 #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
31 #include "gc/shenandoah/shenandoahTraversalGC.hpp"
32 #include "gc/shared/space.inline.hpp"
33 #include "jfr/jfrEvents.hpp"
34 #include "memory/iterator.inline.hpp"
35 #include "memory/resourceArea.hpp"
36 #include "memory/universe.hpp"
37 #include "oops/oop.inline.hpp"
38 #include "runtime/java.hpp"
39 #include "runtime/mutexLocker.hpp"
40 #include "runtime/os.hpp"
41 #include "runtime/safepoint.hpp"
42
43 size_t ShenandoahHeapRegion::RegionCount = 0;
44 size_t ShenandoahHeapRegion::RegionSizeBytes = 0;
45 size_t ShenandoahHeapRegion::RegionSizeWords = 0;
46 size_t ShenandoahHeapRegion::RegionSizeBytesShift = 0;
47 size_t ShenandoahHeapRegion::RegionSizeWordsShift = 0;
48 size_t ShenandoahHeapRegion::RegionSizeBytesMask = 0;
49 size_t ShenandoahHeapRegion::RegionSizeWordsMask = 0;
50 size_t ShenandoahHeapRegion::HumongousThresholdBytes = 0;
51 size_t ShenandoahHeapRegion::HumongousThresholdWords = 0;
52 size_t ShenandoahHeapRegion::MaxTLABSizeBytes = 0;
53 size_t ShenandoahHeapRegion::MaxTLABSizeWords = 0;
78
79 size_t ShenandoahHeapRegion::region_number() const {
80 return _region_number;
81 }
82
83 void ShenandoahHeapRegion::report_illegal_transition(const char *method) {
84 ResourceMark rm;
85 stringStream ss;
86 ss.print("Illegal region state transition from \"%s\", at %s\n ", region_state_to_string(_state), method);
87 print_on(&ss);
88 fatal("%s", ss.as_string());
89 }
90
91 void ShenandoahHeapRegion::make_regular_allocation() {
92 _heap->assert_heaplock_owned_by_current_thread();
93
94 switch (_state) {
95 case _empty_uncommitted:
96 do_commit();
97 case _empty_committed:
98 set_state(_regular);
99 case _regular:
100 case _pinned:
101 return;
102 default:
103 report_illegal_transition("regular allocation");
104 }
105 }
106
107 void ShenandoahHeapRegion::make_regular_bypass() {
108 _heap->assert_heaplock_owned_by_current_thread();
109 assert (_heap->is_full_gc_in_progress() || _heap->is_degenerated_gc_in_progress(),
110 "only for full or degen GC");
111
112 switch (_state) {
113 case _empty_uncommitted:
114 do_commit();
115 case _empty_committed:
116 case _cset:
117 case _humongous_start:
118 case _humongous_cont:
119 set_state(_regular);
120 return;
121 case _pinned_cset:
122 set_state(_pinned);
123 return;
124 case _regular:
125 case _pinned:
126 return;
127 default:
128 report_illegal_transition("regular bypass");
129 }
130 }
131
132 void ShenandoahHeapRegion::make_humongous_start() {
133 _heap->assert_heaplock_owned_by_current_thread();
134 switch (_state) {
135 case _empty_uncommitted:
136 do_commit();
137 case _empty_committed:
138 set_state(_humongous_start);
139 return;
140 default:
141 report_illegal_transition("humongous start allocation");
142 }
143 }
144
145 void ShenandoahHeapRegion::make_humongous_start_bypass() {
146 _heap->assert_heaplock_owned_by_current_thread();
147 assert (_heap->is_full_gc_in_progress(), "only for full GC");
148
149 switch (_state) {
150 case _empty_committed:
151 case _regular:
152 case _humongous_start:
153 case _humongous_cont:
154 set_state(_humongous_start);
155 return;
156 default:
157 report_illegal_transition("humongous start bypass");
158 }
159 }
160
161 void ShenandoahHeapRegion::make_humongous_cont() {
162 _heap->assert_heaplock_owned_by_current_thread();
163 switch (_state) {
164 case _empty_uncommitted:
165 do_commit();
166 case _empty_committed:
167 set_state(_humongous_cont);
168 return;
169 default:
170 report_illegal_transition("humongous continuation allocation");
171 }
172 }
173
174 void ShenandoahHeapRegion::make_humongous_cont_bypass() {
175 _heap->assert_heaplock_owned_by_current_thread();
176 assert (_heap->is_full_gc_in_progress(), "only for full GC");
177
178 switch (_state) {
179 case _empty_committed:
180 case _regular:
181 case _humongous_start:
182 case _humongous_cont:
183 set_state(_humongous_cont);
184 return;
185 default:
186 report_illegal_transition("humongous continuation bypass");
187 }
188 }
189
190 void ShenandoahHeapRegion::make_pinned() {
191 _heap->assert_heaplock_owned_by_current_thread();
192 switch (_state) {
193 case _regular:
194 assert (_critical_pins == 0, "sanity");
195 set_state(_pinned);
196 case _pinned_cset:
197 case _pinned:
198 _critical_pins++;
199 return;
200 case _humongous_start:
201 assert (_critical_pins == 0, "sanity");
202 set_state(_pinned_humongous_start);
203 case _pinned_humongous_start:
204 _critical_pins++;
205 return;
206 case _cset:
207 guarantee(_heap->cancelled_gc(), "only valid when evac has been cancelled");
208 assert (_critical_pins == 0, "sanity");
209 _state = _pinned_cset;
210 _critical_pins++;
211 return;
212 default:
213 report_illegal_transition("pinning");
214 }
215 }
216
217 void ShenandoahHeapRegion::make_unpinned() {
218 _heap->assert_heaplock_owned_by_current_thread();
219 switch (_state) {
220 case _pinned:
221 assert (_critical_pins > 0, "sanity");
222 _critical_pins--;
223 if (_critical_pins == 0) {
224 set_state(_regular);
225 }
226 return;
227 case _regular:
228 case _humongous_start:
229 assert (_critical_pins == 0, "sanity");
230 return;
231 case _pinned_cset:
232 guarantee(_heap->cancelled_gc(), "only valid when evac has been cancelled");
233 assert (_critical_pins > 0, "sanity");
234 _critical_pins--;
235 if (_critical_pins == 0) {
236 set_state(_cset);
237 }
238 return;
239 case _pinned_humongous_start:
240 assert (_critical_pins > 0, "sanity");
241 _critical_pins--;
242 if (_critical_pins == 0) {
243 set_state(_humongous_start);
244 }
245 return;
246 default:
247 report_illegal_transition("unpinning");
248 }
249 }
250
251 void ShenandoahHeapRegion::make_cset() {
252 _heap->assert_heaplock_owned_by_current_thread();
253 switch (_state) {
254 case _regular:
255 set_state(_cset);
256 case _cset:
257 return;
258 default:
259 report_illegal_transition("cset");
260 }
261 }
262
263 void ShenandoahHeapRegion::make_trash() {
264 _heap->assert_heaplock_owned_by_current_thread();
265 switch (_state) {
266 case _cset:
267 // Reclaiming cset regions
268 case _humongous_start:
269 case _humongous_cont:
270 // Reclaiming humongous regions
271 case _regular:
272 // Immediate region reclaim
273 set_state(_trash);
274 return;
275 default:
276 report_illegal_transition("trashing");
277 }
278 }
279
280 void ShenandoahHeapRegion::make_trash_immediate() {
281 make_trash();
282
283 // On this path, we know there are no marked objects in the region,
284 // tell marking context about it to bypass bitmap resets.
285 _heap->complete_marking_context()->reset_top_bitmap(this);
286 }
287
288 void ShenandoahHeapRegion::make_empty() {
289 _heap->assert_heaplock_owned_by_current_thread();
290 switch (_state) {
291 case _trash:
292 set_state(_empty_committed);
293 _empty_time = os::elapsedTime();
294 return;
295 default:
296 report_illegal_transition("emptying");
297 }
298 }
299
300 void ShenandoahHeapRegion::make_uncommitted() {
301 _heap->assert_heaplock_owned_by_current_thread();
302 switch (_state) {
303 case _empty_committed:
304 do_uncommit();
305 set_state(_empty_uncommitted);
306 return;
307 default:
308 report_illegal_transition("uncommiting");
309 }
310 }
311
312 void ShenandoahHeapRegion::make_committed_bypass() {
313 _heap->assert_heaplock_owned_by_current_thread();
314 assert (_heap->is_full_gc_in_progress(), "only for full GC");
315
316 switch (_state) {
317 case _empty_uncommitted:
318 do_commit();
319 set_state(_empty_committed);
320 return;
321 default:
322 report_illegal_transition("commit bypass");
323 }
324 }
325
326 void ShenandoahHeapRegion::clear_live_data() {
327 OrderAccess::release_store_fence<size_t>(&_live_data, 0);
328 }
329
330 void ShenandoahHeapRegion::reset_alloc_metadata() {
331 _tlab_allocs = 0;
332 _gclab_allocs = 0;
333 _shared_allocs = 0;
334 _seqnum_first_alloc_mutator = 0;
335 _seqnum_last_alloc_mutator = 0;
336 _seqnum_first_alloc_gc = 0;
337 _seqnum_last_alloc_gc = 0;
338 }
339
661 }
662
663 void ShenandoahHeapRegion::do_commit() {
664 if (!os::commit_memory((char *) _reserved.start(), _reserved.byte_size(), false)) {
665 report_java_out_of_memory("Unable to commit region");
666 }
667 if (!_heap->commit_bitmap_slice(this)) {
668 report_java_out_of_memory("Unable to commit bitmaps for region");
669 }
670 _heap->increase_committed(ShenandoahHeapRegion::region_size_bytes());
671 }
672
673 void ShenandoahHeapRegion::do_uncommit() {
674 if (!os::uncommit_memory((char *) _reserved.start(), _reserved.byte_size())) {
675 report_java_out_of_memory("Unable to uncommit region");
676 }
677 if (!_heap->uncommit_bitmap_slice(this)) {
678 report_java_out_of_memory("Unable to uncommit bitmaps for region");
679 }
680 _heap->decrease_committed(ShenandoahHeapRegion::region_size_bytes());
681 }
682
683 void ShenandoahHeapRegion::set_state(RegionState to) {
684 EventShenandoahHeapRegionStateChange evt;
685 if (evt.should_commit()){
686 evt.set_index(region_number());
687 evt.set_start((uintptr_t)bottom());
688 evt.set_used(used());
689 evt.set_from(_state);
690 evt.set_to(to);
691 evt.commit();
692 }
693 _state = to;
694 }
|