1 /*
2 * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
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 #include "precompiled.hpp"
26 #include "compiler/compileBroker.hpp"
27 #include "gc/shared/collectedHeap.hpp"
28 #include "memory/resourceArea.hpp"
29 #include "oops/method.hpp"
30 #include "oops/oop.inline.hpp"
31 #include "oops/verifyOopClosure.hpp"
32 #include "runtime/interfaceSupport.hpp"
33 #include "runtime/mutexLocker.hpp"
34 #include "runtime/os.hpp"
35 #include "runtime/safepoint.hpp"
36 #include "runtime/thread.inline.hpp"
37 #include "runtime/vmThread.hpp"
38 #include "runtime/vm_operations.hpp"
39 #include "services/runtimeService.hpp"
40 #include "trace/tracing.hpp"
41 #include "utilities/dtrace.hpp"
42 #include "utilities/events.hpp"
43 #include "utilities/xmlstream.hpp"
44
45 // Dummy VM operation to act as first element in our circular double-linked list
46 class VM_Dummy: public VM_Operation {
47 VMOp_Type type() const { return VMOp_Dummy; }
48 void doit() {};
49 };
50
51 VMOperationQueue::VMOperationQueue() {
52 // The queue is a circular doubled-linked list, which always contains
53 // one element (i.e., one element means empty).
54 for(int i = 0; i < nof_priorities; i++) {
55 _queue_length[i] = 0;
56 _queue_counter = 0;
57 _queue[i] = new VM_Dummy();
58 _queue[i]->set_next(_queue[i]);
59 _queue[i]->set_prev(_queue[i]);
60 }
61 _drain_list = NULL;
62 }
63
319 _should_terminate = true;
320 VMOperationQueue_lock->notify();
321 }
322
323 // Note: VM thread leaves at Safepoint. We are not stopped by Safepoint
324 // because this thread has been removed from the threads list. But anything
325 // that could get blocked by Safepoint should not be used after this point,
326 // otherwise we will hang, since there is no one can end the safepoint.
327
328 // Wait until VM thread is terminated
329 // Note: it should be OK to use Terminator_lock here. But this is called
330 // at a very delicate time (VM shutdown) and we are operating in non- VM
331 // thread at Safepoint. It's safer to not share lock with other threads.
332 { MutexLockerEx ml(_terminate_lock, Mutex::_no_safepoint_check_flag);
333 while(!VMThread::is_terminated()) {
334 _terminate_lock->wait(Mutex::_no_safepoint_check_flag);
335 }
336 }
337 }
338
339 void VMThread::evaluate_operation(VM_Operation* op) {
340 ResourceMark rm;
341
342 {
343 PerfTraceTime vm_op_timer(perf_accumulated_vm_operation_time());
344 HOTSPOT_VMOPS_BEGIN(
345 (char *) op->name(), strlen(op->name()),
346 op->evaluation_mode());
347
348 EventExecuteVMOperation event;
349
350 op->evaluate();
351
352 if (event.should_commit()) {
353 const bool is_concurrent = op->evaluate_concurrently();
354 const bool evaluate_at_safepoint = op->evaluate_at_safepoint();
355 event.set_operation(op->type());
356 event.set_safepoint(evaluate_at_safepoint);
357 event.set_blocking(!is_concurrent);
358 // Only write caller thread information for non-concurrent vm operations.
359 // For concurrent vm operations, the thread id is set to 0 indicating thread is unknown.
360 // This is because the caller thread could have exited already.
361 event.set_caller(is_concurrent ? 0 : THREAD_TRACE_ID(op->calling_thread()));
362 event.set_safepointId(evaluate_at_safepoint ? SafepointSynchronize::safepoint_counter() : 0);
363 event.commit();
364 }
365
366 HOTSPOT_VMOPS_END(
367 (char *) op->name(), strlen(op->name()),
368 op->evaluation_mode());
369 }
370
371 // Last access of info in _cur_vm_operation!
372 bool c_heap_allocated = op->is_cheap_allocated();
373
374 // Mark as completed
375 if (!op->evaluate_concurrently()) {
376 op->calling_thread()->increment_vm_operation_completed_count();
377 }
378 // It is unsafe to access the _cur_vm_operation after the 'increment_vm_operation_completed_count' call,
379 // since if it is stack allocated the calling thread might have deallocated
380 if (c_heap_allocated) {
381 delete _cur_vm_operation;
382 }
383 }
384
|
1 /*
2 * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
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 #include "precompiled.hpp"
26 #include "compiler/compileBroker.hpp"
27 #include "gc/shared/collectedHeap.hpp"
28 #include "memory/resourceArea.hpp"
29 #include "oops/method.hpp"
30 #include "oops/oop.inline.hpp"
31 #include "oops/verifyOopClosure.hpp"
32 #include "runtime/interfaceSupport.hpp"
33 #include "runtime/mutexLocker.hpp"
34 #include "runtime/os.hpp"
35 #include "runtime/safepoint.hpp"
36 #include "runtime/thread.inline.hpp"
37 #include "runtime/vmThread.hpp"
38 #include "runtime/vm_operations.hpp"
39 #include "services/runtimeService.hpp"
40 #include "utilities/dtrace.hpp"
41 #include "utilities/events.hpp"
42 #include "utilities/macros.hpp"
43 #include "utilities/xmlstream.hpp"
44 #if INCLUDE_TRACE
45 #include "trace/tracing.hpp"
46 #endif
47
48 // Dummy VM operation to act as first element in our circular double-linked list
49 class VM_Dummy: public VM_Operation {
50 VMOp_Type type() const { return VMOp_Dummy; }
51 void doit() {};
52 };
53
54 VMOperationQueue::VMOperationQueue() {
55 // The queue is a circular doubled-linked list, which always contains
56 // one element (i.e., one element means empty).
57 for(int i = 0; i < nof_priorities; i++) {
58 _queue_length[i] = 0;
59 _queue_counter = 0;
60 _queue[i] = new VM_Dummy();
61 _queue[i]->set_next(_queue[i]);
62 _queue[i]->set_prev(_queue[i]);
63 }
64 _drain_list = NULL;
65 }
66
322 _should_terminate = true;
323 VMOperationQueue_lock->notify();
324 }
325
326 // Note: VM thread leaves at Safepoint. We are not stopped by Safepoint
327 // because this thread has been removed from the threads list. But anything
328 // that could get blocked by Safepoint should not be used after this point,
329 // otherwise we will hang, since there is no one can end the safepoint.
330
331 // Wait until VM thread is terminated
332 // Note: it should be OK to use Terminator_lock here. But this is called
333 // at a very delicate time (VM shutdown) and we are operating in non- VM
334 // thread at Safepoint. It's safer to not share lock with other threads.
335 { MutexLockerEx ml(_terminate_lock, Mutex::_no_safepoint_check_flag);
336 while(!VMThread::is_terminated()) {
337 _terminate_lock->wait(Mutex::_no_safepoint_check_flag);
338 }
339 }
340 }
341
342 #if INCLUDE_TRACE
343 static void post_vm_operation_event(EventExecuteVMOperation* event,
344 VM_Operation* op) {
345 assert(event != NULL, "invariant");
346 assert(op != NULL, "invariant");
347 if (event->should_commit()) {
348 const bool is_concurrent = op->evaluate_concurrently();
349 const bool evaluate_at_safepoint = op->evaluate_at_safepoint();
350 event->set_operation(op->type());
351 event->set_safepoint(evaluate_at_safepoint);
352 event->set_blocking(!is_concurrent);
353 // Only write caller thread information for non-concurrent vm operations.
354 // For concurrent vm operations, the thread id is set to 0 indicating thread is unknown.
355 // This is because the caller thread could have exited already.
356 event->set_caller(is_concurrent ? 0 : THREAD_TRACE_ID(op->calling_thread()));
357 event->set_safepointId(evaluate_at_safepoint ? SafepointSynchronize::safepoint_counter() : 0);
358 event->commit();
359 }
360 }
361 #endif // INCLUDE_TRACE
362
363 void VMThread::evaluate_operation(VM_Operation* op) {
364 ResourceMark rm;
365
366 {
367 PerfTraceTime vm_op_timer(perf_accumulated_vm_operation_time());
368 HOTSPOT_VMOPS_BEGIN(
369 (char *) op->name(), strlen(op->name()),
370 op->evaluation_mode());
371 TRACE_ONLY(EventExecuteVMOperation event;)
372
373 op->evaluate();
374
375 TRACE_ONLY(post_vm_operation_event(&event, op);)
376
377 HOTSPOT_VMOPS_END(
378 (char *) op->name(), strlen(op->name()),
379 op->evaluation_mode());
380 }
381
382 // Last access of info in _cur_vm_operation!
383 bool c_heap_allocated = op->is_cheap_allocated();
384
385 // Mark as completed
386 if (!op->evaluate_concurrently()) {
387 op->calling_thread()->increment_vm_operation_completed_count();
388 }
389 // It is unsafe to access the _cur_vm_operation after the 'increment_vm_operation_completed_count' call,
390 // since if it is stack allocated the calling thread might have deallocated
391 if (c_heap_allocated) {
392 delete _cur_vm_operation;
393 }
394 }
395
|