60 #include "runtime/synchronizer.hpp" |
61 #include "runtime/synchronizer.hpp" |
61 #include "runtime/thread.inline.hpp" |
62 #include "runtime/thread.inline.hpp" |
62 #include "runtime/threadSMR.hpp" |
63 #include "runtime/threadSMR.hpp" |
63 #include "runtime/timerTrace.hpp" |
64 #include "runtime/timerTrace.hpp" |
64 #include "services/runtimeService.hpp" |
65 #include "services/runtimeService.hpp" |
65 #include "trace/tracing.hpp" |
|
66 #include "trace/traceMacros.hpp" |
|
67 #include "utilities/events.hpp" |
66 #include "utilities/events.hpp" |
68 #include "utilities/macros.hpp" |
67 #include "utilities/macros.hpp" |
69 #ifdef COMPILER1 |
68 #ifdef COMPILER1 |
70 #include "c1/c1_globals.hpp" |
69 #include "c1/c1_globals.hpp" |
71 #endif |
70 #endif |
|
71 |
|
72 template <typename E> |
|
73 static void set_current_safepoint_id(E* event, int adjustment = 0) { |
|
74 assert(event != NULL, "invariant"); |
|
75 event->set_safepointId(SafepointSynchronize::safepoint_counter() + adjustment); |
|
76 } |
|
77 |
|
78 static void post_safepoint_begin_event(EventSafepointBegin* event, |
|
79 int thread_count, |
|
80 int critical_thread_count) { |
|
81 assert(event != NULL, "invariant"); |
|
82 assert(event->should_commit(), "invariant"); |
|
83 set_current_safepoint_id(event); |
|
84 event->set_totalThreadCount(thread_count); |
|
85 event->set_jniCriticalThreadCount(critical_thread_count); |
|
86 event->commit(); |
|
87 } |
|
88 |
|
89 static void post_safepoint_cleanup_event(EventSafepointCleanup* event) { |
|
90 assert(event != NULL, "invariant"); |
|
91 assert(event->should_commit(), "invariant"); |
|
92 set_current_safepoint_id(event); |
|
93 event->commit(); |
|
94 } |
|
95 |
|
96 static void post_safepoint_synchronize_event(EventSafepointStateSynchronization* event, |
|
97 int initial_number_of_threads, |
|
98 int threads_waiting_to_block, |
|
99 unsigned int iterations) { |
|
100 assert(event != NULL, "invariant"); |
|
101 if (event->should_commit()) { |
|
102 // Group this event together with the ones committed after the counter is increased |
|
103 set_current_safepoint_id(event, 1); |
|
104 event->set_initialThreadCount(initial_number_of_threads); |
|
105 event->set_runningThreadCount(threads_waiting_to_block); |
|
106 event->set_iterations(iterations); |
|
107 event->commit(); |
|
108 } |
|
109 } |
|
110 |
|
111 static void post_safepoint_wait_blocked_event(EventSafepointWaitBlocked* event, |
|
112 int initial_threads_waiting_to_block) { |
|
113 assert(event != NULL, "invariant"); |
|
114 assert(event->should_commit(), "invariant"); |
|
115 set_current_safepoint_id(event); |
|
116 event->set_runningThreadCount(initial_threads_waiting_to_block); |
|
117 event->commit(); |
|
118 } |
|
119 |
|
120 static void post_safepoint_cleanup_task_event(EventSafepointCleanupTask* event, |
|
121 const char* name) { |
|
122 assert(event != NULL, "invariant"); |
|
123 if (event->should_commit()) { |
|
124 set_current_safepoint_id(event); |
|
125 event->set_name(name); |
|
126 event->commit(); |
|
127 } |
|
128 } |
|
129 |
|
130 static void post_safepoint_end_event(EventSafepointEnd* event) { |
|
131 assert(event != NULL, "invariant"); |
|
132 if (event->should_commit()) { |
|
133 // Group this event together with the ones committed before the counter increased |
|
134 set_current_safepoint_id(event, -1); |
|
135 event->commit(); |
|
136 } |
|
137 } |
72 |
138 |
73 // -------------------------------------------------------------------------------------------------- |
139 // -------------------------------------------------------------------------------------------------- |
74 // Implementation of Safepoint begin/end |
140 // Implementation of Safepoint begin/end |
75 |
141 |
76 SafepointSynchronize::SynchronizeState volatile SafepointSynchronize::_state = SafepointSynchronize::_not_synchronized; |
142 SafepointSynchronize::SynchronizeState volatile SafepointSynchronize::_state = SafepointSynchronize::_not_synchronized; |
419 // Call stuff that needs to be run when a safepoint is just about to be completed |
476 // Call stuff that needs to be run when a safepoint is just about to be completed |
420 { |
477 { |
421 EventSafepointCleanup cleanup_event; |
478 EventSafepointCleanup cleanup_event; |
422 do_cleanup_tasks(); |
479 do_cleanup_tasks(); |
423 if (cleanup_event.should_commit()) { |
480 if (cleanup_event.should_commit()) { |
424 cleanup_event.set_safepointId(safepoint_counter()); |
481 post_safepoint_cleanup_event(&cleanup_event); |
425 cleanup_event.commit(); |
|
426 } |
482 } |
427 } |
483 } |
428 |
484 |
429 if (PrintSafepointStatistics) { |
485 if (PrintSafepointStatistics) { |
430 // Record how much time spend on the above cleanup tasks |
486 // Record how much time spend on the above cleanup tasks |
431 update_statistics_on_cleanup_end(os::javaTimeNanos()); |
487 update_statistics_on_cleanup_end(os::javaTimeNanos()); |
432 } |
488 } |
|
489 |
433 if (begin_event.should_commit()) { |
490 if (begin_event.should_commit()) { |
434 begin_event.set_safepointId(safepoint_counter()); |
491 post_safepoint_begin_event(&begin_event, nof_threads, _current_jni_active_count); |
435 begin_event.set_totalThreadCount(nof_threads); |
|
436 begin_event.set_jniCriticalThreadCount(_current_jni_active_count); |
|
437 begin_event.commit(); |
|
438 } |
492 } |
439 } |
493 } |
440 |
494 |
441 // Wake up all threads, so they are ready to resume execution after the safepoint |
495 // Wake up all threads, so they are ready to resume execution after the safepoint |
442 // operation has been carried out |
496 // operation has been carried out |
443 void SafepointSynchronize::end() { |
497 void SafepointSynchronize::end() { |
444 EventSafepointEnd event; |
|
445 int safepoint_id = safepoint_counter(); // Keep the odd counter as "id" |
|
446 |
|
447 assert(Threads_lock->owned_by_self(), "must hold Threads_lock"); |
498 assert(Threads_lock->owned_by_self(), "must hold Threads_lock"); |
448 assert((_safepoint_counter & 0x1) == 1, "must be odd"); |
499 assert((_safepoint_counter & 0x1) == 1, "must be odd"); |
|
500 EventSafepointEnd event; |
449 _safepoint_counter ++; |
501 _safepoint_counter ++; |
450 // memory fence isn't required here since an odd _safepoint_counter |
502 // memory fence isn't required here since an odd _safepoint_counter |
451 // value can do no harm and a fence is issued below anyway. |
503 // value can do no harm and a fence is issued below anyway. |
452 |
504 |
453 DEBUG_ONLY(Thread* myThread = Thread::current();) |
505 DEBUG_ONLY(Thread* myThread = Thread::current();) |
539 |
591 |
540 Universe::heap()->safepoint_synchronize_end(); |
592 Universe::heap()->safepoint_synchronize_end(); |
541 // record this time so VMThread can keep track how much time has elapsed |
593 // record this time so VMThread can keep track how much time has elapsed |
542 // since last safepoint. |
594 // since last safepoint. |
543 _end_of_last_safepoint = os::javaTimeMillis(); |
595 _end_of_last_safepoint = os::javaTimeMillis(); |
544 |
|
545 if (event.should_commit()) { |
596 if (event.should_commit()) { |
546 event.set_safepointId(safepoint_id); |
597 post_safepoint_end_event(&event); |
547 event.commit(); |
|
548 } |
598 } |
549 } |
599 } |
550 |
600 |
551 bool SafepointSynchronize::is_cleanup_needed() { |
601 bool SafepointSynchronize::is_cleanup_needed() { |
552 // Need a safepoint if there are many monitors to deflate. |
602 // Need a safepoint if there are many monitors to deflate. |
553 if (ObjectSynchronizer::is_cleanup_needed()) return true; |
603 if (ObjectSynchronizer::is_cleanup_needed()) return true; |
554 // Need a safepoint if some inline cache buffers is non-empty |
604 // Need a safepoint if some inline cache buffers is non-empty |
555 if (!InlineCacheBuffer::is_empty()) return true; |
605 if (!InlineCacheBuffer::is_empty()) return true; |
556 return false; |
606 return false; |
557 } |
|
558 |
|
559 static void event_safepoint_cleanup_task_commit(EventSafepointCleanupTask& event, const char* name) { |
|
560 if (event.should_commit()) { |
|
561 event.set_safepointId(SafepointSynchronize::safepoint_counter()); |
|
562 event.set_name(name); |
|
563 event.commit(); |
|
564 } |
|
565 } |
607 } |
566 |
608 |
567 class ParallelSPCleanupThreadClosure : public ThreadClosure { |
609 class ParallelSPCleanupThreadClosure : public ThreadClosure { |
568 private: |
610 private: |
569 CodeBlobClosure* _nmethod_cl; |
611 CodeBlobClosure* _nmethod_cl; |
605 if (!_subtasks.is_task_claimed(SafepointSynchronize::SAFEPOINT_CLEANUP_DEFLATE_MONITORS)) { |
647 if (!_subtasks.is_task_claimed(SafepointSynchronize::SAFEPOINT_CLEANUP_DEFLATE_MONITORS)) { |
606 const char* name = "deflating idle monitors"; |
648 const char* name = "deflating idle monitors"; |
607 EventSafepointCleanupTask event; |
649 EventSafepointCleanupTask event; |
608 TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup)); |
650 TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup)); |
609 ObjectSynchronizer::deflate_idle_monitors(_counters); |
651 ObjectSynchronizer::deflate_idle_monitors(_counters); |
610 event_safepoint_cleanup_task_commit(event, name); |
652 if (event.should_commit()) { |
|
653 post_safepoint_cleanup_task_event(&event, name); |
|
654 } |
611 } |
655 } |
612 |
656 |
613 if (!_subtasks.is_task_claimed(SafepointSynchronize::SAFEPOINT_CLEANUP_UPDATE_INLINE_CACHES)) { |
657 if (!_subtasks.is_task_claimed(SafepointSynchronize::SAFEPOINT_CLEANUP_UPDATE_INLINE_CACHES)) { |
614 const char* name = "updating inline caches"; |
658 const char* name = "updating inline caches"; |
615 EventSafepointCleanupTask event; |
659 EventSafepointCleanupTask event; |
616 TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup)); |
660 TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup)); |
617 InlineCacheBuffer::update_inline_caches(); |
661 InlineCacheBuffer::update_inline_caches(); |
618 event_safepoint_cleanup_task_commit(event, name); |
662 if (event.should_commit()) { |
|
663 post_safepoint_cleanup_task_event(&event, name); |
|
664 } |
619 } |
665 } |
620 |
666 |
621 if (!_subtasks.is_task_claimed(SafepointSynchronize::SAFEPOINT_CLEANUP_COMPILATION_POLICY)) { |
667 if (!_subtasks.is_task_claimed(SafepointSynchronize::SAFEPOINT_CLEANUP_COMPILATION_POLICY)) { |
622 const char* name = "compilation policy safepoint handler"; |
668 const char* name = "compilation policy safepoint handler"; |
623 EventSafepointCleanupTask event; |
669 EventSafepointCleanupTask event; |
624 TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup)); |
670 TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup)); |
625 CompilationPolicy::policy()->do_safepoint_work(); |
671 CompilationPolicy::policy()->do_safepoint_work(); |
626 event_safepoint_cleanup_task_commit(event, name); |
672 if (event.should_commit()) { |
|
673 post_safepoint_cleanup_task_event(&event, name); |
|
674 } |
627 } |
675 } |
628 |
676 |
629 if (!_subtasks.is_task_claimed(SafepointSynchronize::SAFEPOINT_CLEANUP_SYMBOL_TABLE_REHASH)) { |
677 if (!_subtasks.is_task_claimed(SafepointSynchronize::SAFEPOINT_CLEANUP_SYMBOL_TABLE_REHASH)) { |
630 if (SymbolTable::needs_rehashing()) { |
678 if (SymbolTable::needs_rehashing()) { |
631 const char* name = "rehashing symbol table"; |
679 const char* name = "rehashing symbol table"; |
632 EventSafepointCleanupTask event; |
680 EventSafepointCleanupTask event; |
633 TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup)); |
681 TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup)); |
634 SymbolTable::rehash_table(); |
682 SymbolTable::rehash_table(); |
635 event_safepoint_cleanup_task_commit(event, name); |
683 if (event.should_commit()) { |
|
684 post_safepoint_cleanup_task_event(&event, name); |
|
685 } |
636 } |
686 } |
637 } |
687 } |
638 |
688 |
639 if (!_subtasks.is_task_claimed(SafepointSynchronize::SAFEPOINT_CLEANUP_STRING_TABLE_REHASH)) { |
689 if (!_subtasks.is_task_claimed(SafepointSynchronize::SAFEPOINT_CLEANUP_STRING_TABLE_REHASH)) { |
640 if (StringTable::needs_rehashing()) { |
690 if (StringTable::needs_rehashing()) { |
641 const char* name = "rehashing string table"; |
691 const char* name = "rehashing string table"; |
642 EventSafepointCleanupTask event; |
692 EventSafepointCleanupTask event; |
643 TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup)); |
693 TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup)); |
644 StringTable::rehash_table(); |
694 StringTable::rehash_table(); |
645 event_safepoint_cleanup_task_commit(event, name); |
695 if (event.should_commit()) { |
|
696 post_safepoint_cleanup_task_event(&event, name); |
|
697 } |
646 } |
698 } |
647 } |
699 } |
648 |
700 |
649 if (!_subtasks.is_task_claimed(SafepointSynchronize::SAFEPOINT_CLEANUP_CLD_PURGE)) { |
701 if (!_subtasks.is_task_claimed(SafepointSynchronize::SAFEPOINT_CLEANUP_CLD_PURGE)) { |
650 // CMS delays purging the CLDG until the beginning of the next safepoint and to |
702 // CMS delays purging the CLDG until the beginning of the next safepoint and to |
651 // make sure concurrent sweep is done |
703 // make sure concurrent sweep is done |
652 const char* name = "purging class loader data graph"; |
704 const char* name = "purging class loader data graph"; |
653 EventSafepointCleanupTask event; |
705 EventSafepointCleanupTask event; |
654 TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup)); |
706 TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup)); |
655 ClassLoaderDataGraph::purge_if_needed(); |
707 ClassLoaderDataGraph::purge_if_needed(); |
656 event_safepoint_cleanup_task_commit(event, name); |
708 if (event.should_commit()) { |
|
709 post_safepoint_cleanup_task_event(&event, name); |
|
710 } |
657 } |
711 } |
658 |
712 |
659 if (!_subtasks.is_task_claimed(SafepointSynchronize::SAFEPOINT_CLEANUP_SYSTEM_DICTIONARY_RESIZE)) { |
713 if (!_subtasks.is_task_claimed(SafepointSynchronize::SAFEPOINT_CLEANUP_SYSTEM_DICTIONARY_RESIZE)) { |
660 const char* name = "resizing system dictionaries"; |
714 const char* name = "resizing system dictionaries"; |
661 EventSafepointCleanupTask event; |
715 EventSafepointCleanupTask event; |
662 TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup)); |
716 TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup)); |
663 ClassLoaderDataGraph::resize_if_needed(); |
717 ClassLoaderDataGraph::resize_if_needed(); |
664 event_safepoint_cleanup_task_commit(event, name); |
718 if (event.should_commit()) { |
|
719 post_safepoint_cleanup_task_event(&event, name); |
|
720 } |
665 } |
721 } |
666 _subtasks.all_tasks_completed(_num_workers); |
722 _subtasks.all_tasks_completed(_num_workers); |
667 } |
723 } |
668 }; |
724 }; |
669 |
725 |