1 /*
2 * Copyright (c) 2021, Red Hat, Inc. All rights reserved.
3 * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
56 shenandoah_assert_safepoint();
57 _epoch_id++;
58 }
59
60 ShenandoahStackWatermark::ShenandoahStackWatermark(JavaThread* jt) :
61 StackWatermark(jt, StackWatermarkKind::gc, _epoch_id),
62 _heap(ShenandoahHeap::heap()),
63 _stats(),
64 _keep_alive_cl(),
65 _evac_update_oop_cl(),
66 _nm_cl() {}
67
68 OopClosure* ShenandoahStackWatermark::closure_from_context(void* context) {
69 if (context != nullptr) {
70 assert(_heap->is_concurrent_weak_root_in_progress() ||
71 _heap->is_concurrent_mark_in_progress(),
72 "Only these two phases");
73 assert(Thread::current()->is_Worker_thread(), "Unexpected thread passing in context: " PTR_FORMAT, p2i(context));
74 return reinterpret_cast<OopClosure*>(context);
75 } else {
76 if (_heap->is_concurrent_mark_in_progress()) {
77 return &_keep_alive_cl;
78 } else if (_heap->is_concurrent_weak_root_in_progress()) {
79 assert(_heap->is_evacuation_in_progress(), "Nothing to evacuate");
80 return &_evac_update_oop_cl;
81 } else {
82 ShouldNotReachHere();
83 return nullptr;
84 }
85 }
86 }
87
88 void ShenandoahStackWatermark::start_processing_impl(void* context) {
89 NoSafepointVerifier nsv;
90 ShenandoahHeap* const heap = ShenandoahHeap::heap();
91
92 // Process the non-frame part of the thread
93 if (heap->is_concurrent_mark_in_progress()) {
94 // We need to reset all TLABs because they might be below the TAMS, and we need to mark
95 // the objects in them. Do not let mutators allocate any new objects in their current TLABs.
96 // It is also a good place to resize the TLAB sizes for future allocations.
97 retire_tlab();
98
99 _jt->oops_do_no_frames(closure_from_context(context), &_nm_cl);
100 } else if (heap->is_concurrent_weak_root_in_progress()) {
101 assert(heap->is_evacuation_in_progress(), "Should not be armed");
102 // Retire the TLABs, which will force threads to reacquire their TLABs.
103 // This is needed for two reasons. Strong one: new allocations would be with new freeset,
104 // which would be outside the collection set, so no cset writes would happen there.
105 // Weaker one: new allocations would happen past update watermark, and so less work would
106 // be needed for reference updates (would update the large filler instead).
107 retire_tlab();
108
109 _jt->oops_do_no_frames(closure_from_context(context), &_nm_cl);
110 } else {
111 ShouldNotReachHere();
112 }
113
114 // Publishes the processing start to concurrent threads
115 StackWatermark::start_processing_impl(context);
116 }
117
118 void ShenandoahStackWatermark::retire_tlab() {
119 // Retire TLAB
120 if (UseTLAB) {
121 _stats.reset();
122 _jt->tlab().retire(&_stats);
123 if (ResizeTLAB) {
124 _jt->tlab().resize();
125 }
126 }
127 }
128
|
1 /*
2 * Copyright (c) 2021, Red Hat, Inc. All rights reserved.
3 * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
4 * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
5 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 *
7 * This code is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 only, as
9 * published by the Free Software Foundation.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 *
57 shenandoah_assert_safepoint();
58 _epoch_id++;
59 }
60
61 ShenandoahStackWatermark::ShenandoahStackWatermark(JavaThread* jt) :
62 StackWatermark(jt, StackWatermarkKind::gc, _epoch_id),
63 _heap(ShenandoahHeap::heap()),
64 _stats(),
65 _keep_alive_cl(),
66 _evac_update_oop_cl(),
67 _nm_cl() {}
68
69 OopClosure* ShenandoahStackWatermark::closure_from_context(void* context) {
70 if (context != nullptr) {
71 assert(_heap->is_concurrent_weak_root_in_progress() ||
72 _heap->is_concurrent_mark_in_progress(),
73 "Only these two phases");
74 assert(Thread::current()->is_Worker_thread(), "Unexpected thread passing in context: " PTR_FORMAT, p2i(context));
75 return reinterpret_cast<OopClosure*>(context);
76 } else {
77 if (_heap->is_concurrent_weak_root_in_progress()) {
78 assert(_heap->is_evacuation_in_progress(), "Nothing to evacuate");
79 return &_evac_update_oop_cl;
80 } else if (_heap->is_concurrent_mark_in_progress()) {
81 return &_keep_alive_cl;
82 } else {
83 ShouldNotReachHere();
84 return nullptr;
85 }
86 }
87 }
88
89 void ShenandoahStackWatermark::start_processing_impl(void* context) {
90 NoSafepointVerifier nsv;
91 ShenandoahHeap* const heap = ShenandoahHeap::heap();
92
93 // Process the non-frame part of the thread
94 if (heap->is_concurrent_weak_root_in_progress()) {
95 assert(heap->is_evacuation_in_progress(), "Should not be armed");
96 // Retire the TLABs, which will force threads to reacquire their TLABs.
97 // This is needed for two reasons. Strong one: new allocations would be with new freeset,
98 // which would be outside the collection set, so no cset writes would happen there.
99 // Weaker one: new allocations would happen past update watermark, and so less work would
100 // be needed for reference updates (would update the large filler instead).
101 retire_tlab();
102
103 _jt->oops_do_no_frames(closure_from_context(context), &_nm_cl);
104 } else if (heap->is_concurrent_mark_in_progress()) {
105 // We need to reset all TLABs because they might be below the TAMS, and we need to mark
106 // the objects in them. Do not let mutators allocate any new objects in their current TLABs.
107 // It is also a good place to resize the TLAB sizes for future allocations.
108 retire_tlab();
109
110 _jt->oops_do_no_frames(closure_from_context(context), &_nm_cl);
111 } else {
112 ShouldNotReachHere();
113 }
114
115 // Publishes the processing start to concurrent threads
116 StackWatermark::start_processing_impl(context);
117 }
118
119 void ShenandoahStackWatermark::retire_tlab() {
120 // Retire TLAB
121 if (UseTLAB) {
122 _stats.reset();
123 _jt->tlab().retire(&_stats);
124 if (ResizeTLAB) {
125 _jt->tlab().resize();
126 }
127 }
128 }
129
|