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