2661 out->cr();
2662 return;
2663 }
2664
2665 ts_total.update(); // record starting point
2666
2667 if (aggregate) {
2668 print_info(out);
2669 }
2670
2671 // We hold the CodeHeapStateAnalytics_lock all the time, from here until we leave this function.
2672 // That prevents another thread from destroying our view on the CodeHeap.
2673 // When we request individual parts of the analysis via the jcmd interface, it is possible
2674 // that in between another thread (another jcmd user or the vm running into CodeCache OOM)
2675 // updated the aggregated data. That's a tolerable tradeoff because we can't hold a lock
2676 // across user interaction.
2677 // Acquire this lock before acquiring the CodeCache_lock.
2678 // CodeHeapStateAnalytics_lock could be held by a concurrent thread for a long time,
2679 // leading to an unnecessarily long hold time of the CodeCache_lock.
2680 ts.update(); // record starting point
2681 MutexLockerEx mu1(CodeHeapStateAnalytics_lock, Mutex::_no_safepoint_check_flag);
2682 out->print_cr("\n__ CodeHeapStateAnalytics lock wait took %10.3f seconds _________\n", ts.seconds());
2683
2684 // If we serve an "allFun" call, it is beneficial to hold the CodeCache_lock
2685 // for the entire duration of aggregation and printing. That makes sure
2686 // we see a consistent picture and do not run into issues caused by
2687 // the CodeHeap being altered concurrently.
2688 Monitor* global_lock = allFun ? CodeCache_lock : NULL;
2689 Monitor* function_lock = allFun ? NULL : CodeCache_lock;
2690 ts_global.update(); // record starting point
2691 MutexLockerEx mu2(global_lock, Mutex::_no_safepoint_check_flag);
2692 if (global_lock != NULL) {
2693 out->print_cr("\n__ CodeCache (global) lock wait took %10.3f seconds _________\n", ts_global.seconds());
2694 ts_global.update(); // record starting point
2695 }
2696
2697 if (aggregate) {
2698 ts.update(); // record starting point
2699 MutexLockerEx mu3(function_lock, Mutex::_no_safepoint_check_flag);
2700 if (function_lock != NULL) {
2701 out->print_cr("\n__ CodeCache (function) lock wait took %10.3f seconds _________\n", ts.seconds());
2702 }
2703
2704 ts.update(); // record starting point
2705 CodeCache::aggregate(out, granularity);
2706 if (function_lock != NULL) {
2707 out->print_cr("\n__ CodeCache (function) lock hold took %10.3f seconds _________\n", ts.seconds());
2708 }
2709 }
2710
2711 if (usedSpace) CodeCache::print_usedSpace(out);
2712 if (freeSpace) CodeCache::print_freeSpace(out);
2713 if (methodCount) CodeCache::print_count(out);
2714 if (methodSpace) CodeCache::print_space(out);
2715 if (methodAge) CodeCache::print_age(out);
2716 if (methodNames) {
2717 // print_names() has shown to be sensitive to concurrent CodeHeap modifications.
2718 // Therefore, request the CodeCache_lock before calling...
2719 MutexLockerEx mu3(function_lock, Mutex::_no_safepoint_check_flag);
2720 CodeCache::print_names(out);
2721 }
2722 if (discard) CodeCache::discard(out);
2723
2724 if (global_lock != NULL) {
2725 out->print_cr("\n__ CodeCache (global) lock hold took %10.3f seconds _________\n", ts_global.seconds());
2726 }
2727 out->print_cr("\n__ CodeHeapStateAnalytics total duration %10.3f seconds _________\n", ts_total.seconds());
2728 }
|
2661 out->cr();
2662 return;
2663 }
2664
2665 ts_total.update(); // record starting point
2666
2667 if (aggregate) {
2668 print_info(out);
2669 }
2670
2671 // We hold the CodeHeapStateAnalytics_lock all the time, from here until we leave this function.
2672 // That prevents another thread from destroying our view on the CodeHeap.
2673 // When we request individual parts of the analysis via the jcmd interface, it is possible
2674 // that in between another thread (another jcmd user or the vm running into CodeCache OOM)
2675 // updated the aggregated data. That's a tolerable tradeoff because we can't hold a lock
2676 // across user interaction.
2677 // Acquire this lock before acquiring the CodeCache_lock.
2678 // CodeHeapStateAnalytics_lock could be held by a concurrent thread for a long time,
2679 // leading to an unnecessarily long hold time of the CodeCache_lock.
2680 ts.update(); // record starting point
2681 MutexLockerEx mu0(CodeHeapStateAnalytics_lock, Mutex::_no_safepoint_check_flag);
2682 out->print_cr("\n__ CodeHeapStateAnalytics lock wait took %10.3f seconds _________\n", ts.seconds());
2683
2684 // Unfortunately, it is not sufficient to only hold the CodeCache_lock.
2685 // When a new nmethod is created via ciEnv::register_method(), the
2686 // Compile_lock is taken first. After some initializations,
2687 // nmethod::new_nmethod() takes over, grabbing the CodeCache_lock
2688 // immediately (after finalizing the oop references). To lock out concurrent
2689 // modifiers, we have to grab both locks as well in the described sequence.
2690 //
2691 // If we serve an "allFun" call, it is beneficial to hold the CodeCache_lock
2692 // for the entire duration of aggregation and printing. That makes sure
2693 // we see a consistent picture and do not run into issues caused by
2694 // the CodeHeap being altered concurrently.
2695 Monitor* global_lock_1 = allFun ? Compile_lock : NULL;
2696 Monitor* global_lock_2 = allFun ? CodeCache_lock : NULL;
2697 Monitor* function_lock_1 = allFun ? NULL : Compile_lock;
2698 Monitor* function_lock_2 = allFun ? NULL : CodeCache_lock;
2699 ts_global.update(); // record starting point
2700 MutexLockerEx mu1(global_lock_1);
2701 MutexLockerEx mu2(global_lock_2, Mutex::_no_safepoint_check_flag);
2702 if (global_lock_1 != NULL) {
2703 out->print_cr("\n__ Compile & CodeCache (global) lock wait took %10.3f seconds _________\n", ts_global.seconds());
2704 ts_global.update(); // record starting point
2705 }
2706
2707 if (aggregate) {
2708 ts.update(); // record starting point
2709 MutexLockerEx mu11(function_lock_1, Mutex::_no_safepoint_check_flag);
2710 MutexLockerEx mu22(function_lock_2, Mutex::_no_safepoint_check_flag);
2711 if (function_lock_1 != NULL) {
2712 out->print_cr("\n__ Compile & CodeCache (function) lock wait took %10.3f seconds _________\n", ts.seconds());
2713 }
2714
2715 ts.update(); // record starting point
2716 CodeCache::aggregate(out, granularity);
2717 if (function_lock_1 != NULL) {
2718 out->print_cr("\n__ Compile & CodeCache (function) lock hold took %10.3f seconds _________\n", ts.seconds());
2719 }
2720 }
2721
2722 if (usedSpace) CodeCache::print_usedSpace(out);
2723 if (freeSpace) CodeCache::print_freeSpace(out);
2724 if (methodCount) CodeCache::print_count(out);
2725 if (methodSpace) CodeCache::print_space(out);
2726 if (methodAge) CodeCache::print_age(out);
2727 if (methodNames) {
2728 // print_names() has shown to be sensitive to concurrent CodeHeap modifications.
2729 // Therefore, request the CodeCache_lock before calling...
2730 MutexLockerEx mu11(function_lock_1, Mutex::_no_safepoint_check_flag);
2731 MutexLockerEx mu22(function_lock_2, Mutex::_no_safepoint_check_flag);
2732 CodeCache::print_names(out);
2733 }
2734 if (discard) CodeCache::discard(out);
2735
2736 if (global_lock_1 != NULL) {
2737 out->print_cr("\n__ Compile & CodeCache (global) lock hold took %10.3f seconds _________\n", ts_global.seconds());
2738 }
2739 out->print_cr("\n__ CodeHeapStateAnalytics total duration %10.3f seconds _________\n", ts_total.seconds());
2740 }
|