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 #include "precompiled.hpp"
26 #include "code/codeCache.hpp"
27 #include "code/compiledIC.hpp"
28 #include "code/icBuffer.hpp"
29 #include "code/nmethod.hpp"
30 #include "compiler/compileBroker.hpp"
31 #include "jfr/jfrEvents.hpp"
32 #include "logging/log.hpp"
33 #include "logging/logStream.hpp"
34 #include "memory/allocation.inline.hpp"
35 #include "memory/resourceArea.hpp"
36 #include "oops/method.hpp"
37 #include "runtime/atomic.hpp"
38 #include "runtime/compilationPolicy.hpp"
39 #include "runtime/interfaceSupport.inline.hpp"
40 #include "runtime/mutexLocker.hpp"
41 #include "runtime/orderAccess.hpp"
42 #include "runtime/os.hpp"
43 #include "runtime/sweeper.hpp"
44 #include "runtime/thread.inline.hpp"
45 #include "runtime/vm_operations.hpp"
46 #include "runtime/vmThread.hpp"
47 #include "utilities/events.hpp"
48 #include "utilities/xmlstream.hpp"
49
50 #ifdef ASSERT
51
52 #define SWEEP(nm) record_sweep(nm, __LINE__)
53 // Sweeper logging code
54 class SweeperRecord {
55 public:
56 int traversal;
57 int compile_id;
58 long traversal_mark;
59 int state;
180 public:
181 virtual void do_code_blob(CodeBlob* cb) {
182 assert(cb->is_nmethod(), "CodeBlob should be nmethod");
183 nmethod* nm = (nmethod*)cb;
184 nm->set_hotness_counter(NMethodSweeper::hotness_counter_reset_val());
185 }
186 };
187 static SetHotnessClosure set_hotness_closure;
188
189
190 int NMethodSweeper::hotness_counter_reset_val() {
191 if (_hotness_counter_reset_val == 0) {
192 _hotness_counter_reset_val = (ReservedCodeCacheSize < M) ? 1 : (ReservedCodeCacheSize / M) * 2;
193 }
194 return _hotness_counter_reset_val;
195 }
196 bool NMethodSweeper::wait_for_stack_scanning() {
197 return _current.end();
198 }
199
200 /**
201 * Scans the stacks of all Java threads and marks activations of not-entrant methods.
202 * No need to synchronize access, since 'mark_active_nmethods' is always executed at a
203 * safepoint.
204 */
205 void NMethodSweeper::mark_active_nmethods() {
206 CodeBlobClosure* cl = prepare_mark_active_nmethods();
207 if (cl != NULL) {
208 Threads::nmethods_do(cl);
209 }
210 }
211
212 CodeBlobClosure* NMethodSweeper::prepare_mark_active_nmethods() {
213 assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint");
214 // If we do not want to reclaim not-entrant or zombie methods there is no need
215 // to scan stacks
216 if (!MethodFlushing) {
217 return NULL;
218 }
219
220 // Increase time so that we can estimate when to invoke the sweeper again.
221 _time_counter++;
222
223 // Check for restart
224 if (_current.method() != NULL) {
225 if (_current.method()->is_nmethod()) {
226 assert(CodeCache::find_blob_unsafe(_current.method()) == _current.method(), "Sweeper nmethod cached state invalid");
227 } else if (_current.method()->is_aot()) {
228 assert(CodeCache::find_blob_unsafe(_current.method()->code_begin()) == _current.method(), "Sweeper AOT method cached state invalid");
229 } else {
230 ShouldNotReachHere();
231 }
232 }
233
241
242 if (PrintMethodFlushing) {
243 tty->print_cr("### Sweep: stack traversal %ld", _traversals);
244 }
245 return &mark_activation_closure;
246
247 } else {
248 // Only set hotness counter
249 return &set_hotness_closure;
250 }
251
252 }
253
254 /**
255 * This function triggers a VM operation that does stack scanning of active
256 * methods. Stack scanning is mandatory for the sweeper to make progress.
257 */
258 void NMethodSweeper::do_stack_scanning() {
259 assert(!CodeCache_lock->owned_by_self(), "just checking");
260 if (wait_for_stack_scanning()) {
261 VM_MarkActiveNMethods op;
262 VMThread::execute(&op);
263 _should_sweep = true;
264 }
265 }
266
267 void NMethodSweeper::sweeper_loop() {
268 bool timeout;
269 while (true) {
270 {
271 ThreadBlockInVM tbivm(JavaThread::current());
272 MutexLockerEx waiter(CodeCache_lock, Mutex::_no_safepoint_check_flag);
273 const long wait_time = 60*60*24 * 1000;
274 timeout = CodeCache_lock->wait(Mutex::_no_safepoint_check_flag, wait_time);
275 }
276 if (!timeout) {
277 possibly_sweep();
278 }
279 }
280 }
281
282 /**
|
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 #include "precompiled.hpp"
26 #include "code/codeCache.hpp"
27 #include "code/compiledIC.hpp"
28 #include "code/icBuffer.hpp"
29 #include "code/nmethod.hpp"
30 #include "compiler/compileBroker.hpp"
31 #include "gc/shared/collectedHeap.hpp"
32 #include "gc/shared/workgroup.hpp"
33 #include "jfr/jfrEvents.hpp"
34 #include "logging/log.hpp"
35 #include "logging/logStream.hpp"
36 #include "memory/allocation.inline.hpp"
37 #include "memory/resourceArea.hpp"
38 #include "memory/universe.hpp"
39 #include "oops/method.hpp"
40 #include "runtime/atomic.hpp"
41 #include "runtime/compilationPolicy.hpp"
42 #include "runtime/interfaceSupport.inline.hpp"
43 #include "runtime/handshake.hpp"
44 #include "runtime/mutexLocker.hpp"
45 #include "runtime/orderAccess.hpp"
46 #include "runtime/os.hpp"
47 #include "runtime/sweeper.hpp"
48 #include "runtime/thread.inline.hpp"
49 #include "runtime/vm_operations.hpp"
50 #include "runtime/vmThread.hpp"
51 #include "utilities/events.hpp"
52 #include "utilities/xmlstream.hpp"
53
54 #ifdef ASSERT
55
56 #define SWEEP(nm) record_sweep(nm, __LINE__)
57 // Sweeper logging code
58 class SweeperRecord {
59 public:
60 int traversal;
61 int compile_id;
62 long traversal_mark;
63 int state;
184 public:
185 virtual void do_code_blob(CodeBlob* cb) {
186 assert(cb->is_nmethod(), "CodeBlob should be nmethod");
187 nmethod* nm = (nmethod*)cb;
188 nm->set_hotness_counter(NMethodSweeper::hotness_counter_reset_val());
189 }
190 };
191 static SetHotnessClosure set_hotness_closure;
192
193
194 int NMethodSweeper::hotness_counter_reset_val() {
195 if (_hotness_counter_reset_val == 0) {
196 _hotness_counter_reset_val = (ReservedCodeCacheSize < M) ? 1 : (ReservedCodeCacheSize / M) * 2;
197 }
198 return _hotness_counter_reset_val;
199 }
200 bool NMethodSweeper::wait_for_stack_scanning() {
201 return _current.end();
202 }
203
204 class ThreadToCodeBlobClosure : public ThreadClosure {
205 private:
206 CodeBlobClosure* _cl;
207 public:
208 ThreadToCodeBlobClosure(CodeBlobClosure* cl) : _cl(cl) {}
209 void do_thread(Thread* thread) {
210 if (thread->is_Java_thread() &&
211 ! thread->is_Code_cache_sweeper_thread()) {
212 JavaThread* jt = (JavaThread*) thread;
213 jt->nmethods_do(_cl);
214 }
215 }
216 };
217
218 class NMethodMarkingTask : public AbstractGangTask {
219 private:
220 ThreadToCodeBlobClosure* _cl;
221 public:
222 NMethodMarkingTask(ThreadToCodeBlobClosure* cl) :
223 AbstractGangTask("Parallel NMethod Marking"),
224 _cl(cl) {}
225 void work(uint worker_id) {
226 Threads::possibly_parallel_threads_do(true, _cl);
227 }
228 };
229
230 /**
231 * Scans the stacks of all Java threads and marks activations of not-entrant methods.
232 * No need to synchronize access, since 'mark_active_nmethods' is always executed at a
233 * safepoint.
234 */
235 void NMethodSweeper::mark_active_nmethods() {
236 CodeBlobClosure* cl = prepare_mark_active_nmethods();
237 if (cl != NULL) {
238 WorkGang* workers = Universe::heap()->get_safepoint_workers();
239 if (workers != NULL) {
240 ThreadToCodeBlobClosure tcl(cl);
241 NMethodMarkingTask task(&tcl);
242 workers->run_task(&task);
243 } else {
244 Threads::nmethods_do(cl);
245 }
246 }
247 }
248
249 CodeBlobClosure* NMethodSweeper::prepare_mark_active_nmethods() {
250 assert(SafepointSynchronize::is_at_safepoint() ||
251 Thread::current()->is_Code_cache_sweeper_thread(), "must be executed at a safepoint");
252 // If we do not want to reclaim not-entrant or zombie methods there is no need
253 // to scan stacks
254 if (!MethodFlushing) {
255 return NULL;
256 }
257
258 // Increase time so that we can estimate when to invoke the sweeper again.
259 _time_counter++;
260
261 // Check for restart
262 if (_current.method() != NULL) {
263 if (_current.method()->is_nmethod()) {
264 assert(CodeCache::find_blob_unsafe(_current.method()) == _current.method(), "Sweeper nmethod cached state invalid");
265 } else if (_current.method()->is_aot()) {
266 assert(CodeCache::find_blob_unsafe(_current.method()->code_begin()) == _current.method(), "Sweeper AOT method cached state invalid");
267 } else {
268 ShouldNotReachHere();
269 }
270 }
271
279
280 if (PrintMethodFlushing) {
281 tty->print_cr("### Sweep: stack traversal %ld", _traversals);
282 }
283 return &mark_activation_closure;
284
285 } else {
286 // Only set hotness counter
287 return &set_hotness_closure;
288 }
289
290 }
291
292 /**
293 * This function triggers a VM operation that does stack scanning of active
294 * methods. Stack scanning is mandatory for the sweeper to make progress.
295 */
296 void NMethodSweeper::do_stack_scanning() {
297 assert(!CodeCache_lock->owned_by_self(), "just checking");
298 if (wait_for_stack_scanning()) {
299 if (ThreadLocalHandshakes) {
300 CodeBlobClosure* code_cl = prepare_mark_active_nmethods();
301 if (code_cl != NULL) {
302 ThreadToCodeBlobClosure tcl(code_cl);
303 Handshake::execute(&tcl);
304 }
305 } else {
306 VM_MarkActiveNMethods op;
307 VMThread::execute(&op);
308 }
309 _should_sweep = true;
310 }
311 }
312
313 void NMethodSweeper::sweeper_loop() {
314 bool timeout;
315 while (true) {
316 {
317 ThreadBlockInVM tbivm(JavaThread::current());
318 MutexLockerEx waiter(CodeCache_lock, Mutex::_no_safepoint_check_flag);
319 const long wait_time = 60*60*24 * 1000;
320 timeout = CodeCache_lock->wait(Mutex::_no_safepoint_check_flag, wait_time);
321 }
322 if (!timeout) {
323 possibly_sweep();
324 }
325 }
326 }
327
328 /**
|