< prev index next >
src/hotspot/share/compiler/compileBroker.cpp
Print this page
rev 54097 : 8216314: SIGILL in CodeHeapState::print_names()
Reviewed-by: thartmann, kvn
*** 1,7 ****
/*
! * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
--- 1,7 ----
/*
! * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*** 2742,2751 ****
--- 2742,2752 ----
// That's a tradeoff which keeps together important blocks of output.
// At the same time, continuous tty_lock hold time is kept in check,
// preventing concurrently printing threads from stalling a long time.
void CompileBroker::print_heapinfo(outputStream* out, const char* function, size_t granularity) {
TimeStamp ts_total;
+ TimeStamp ts_global;
TimeStamp ts;
bool allFun = !strcmp(function, "all");
bool aggregate = !strcmp(function, "aggregate") || !strcmp(function, "analyze") || allFun;
bool usedSpace = !strcmp(function, "UsedSpace") || allFun;
*** 2771,2818 ****
if (aggregate) {
print_info(out);
}
// We hold the CodeHeapStateAnalytics_lock all the time, from here until we leave this function.
! // That helps us getting a consistent view on the CodeHeap, at least for the "all" function.
// When we request individual parts of the analysis via the jcmd interface, it is possible
// that in between another thread (another jcmd user or the vm running into CodeCache OOM)
// updated the aggregated data. That's a tolerable tradeoff because we can't hold a lock
// across user interaction.
ts.update(); // record starting point
MutexLockerEx mu1(CodeHeapStateAnalytics_lock, Mutex::_no_safepoint_check_flag);
! out->cr();
! out->print_cr("__ CodeHeapStateAnalytics lock wait took %10.3f seconds _________", ts.seconds());
! out->cr();
if (aggregate) {
- // It is sufficient to hold the CodeCache_lock only for the aggregate step.
- // All other functions operate on aggregated data - except MethodNames, but that should be safe.
- // The separate CodeHeapStateAnalytics_lock protects the printing functions against
- // concurrent aggregate steps. Acquire this lock before acquiring the CodeCache_lock.
- // CodeHeapStateAnalytics_lock could be held by a concurrent thread for a long time,
- // leading to an unnecessarily long hold time of the CodeCache_lock.
ts.update(); // record starting point
! MutexLockerEx mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag);
! out->cr();
! out->print_cr("__ CodeCache lock wait took %10.3f seconds _________", ts.seconds());
! out->cr();
ts.update(); // record starting point
CodeCache::aggregate(out, granularity);
! out->cr();
! out->print_cr("__ CodeCache lock hold took %10.3f seconds _________", ts.seconds());
! out->cr();
}
if (usedSpace) CodeCache::print_usedSpace(out);
if (freeSpace) CodeCache::print_freeSpace(out);
if (methodCount) CodeCache::print_count(out);
if (methodSpace) CodeCache::print_space(out);
if (methodAge) CodeCache::print_age(out);
! if (methodNames) CodeCache::print_names(out);
if (discard) CodeCache::discard(out);
! out->cr();
! out->print_cr("__ CodeHeapStateAnalytics total duration %10.3f seconds _________", ts_total.seconds());
! out->cr();
}
--- 2772,2833 ----
if (aggregate) {
print_info(out);
}
// We hold the CodeHeapStateAnalytics_lock all the time, from here until we leave this function.
! // That prevents another thread from destroying our view on the CodeHeap.
// When we request individual parts of the analysis via the jcmd interface, it is possible
// that in between another thread (another jcmd user or the vm running into CodeCache OOM)
// updated the aggregated data. That's a tolerable tradeoff because we can't hold a lock
// across user interaction.
+ // Acquire this lock before acquiring the CodeCache_lock.
+ // CodeHeapStateAnalytics_lock could be held by a concurrent thread for a long time,
+ // leading to an unnecessarily long hold time of the CodeCache_lock.
ts.update(); // record starting point
MutexLockerEx mu1(CodeHeapStateAnalytics_lock, Mutex::_no_safepoint_check_flag);
! out->print_cr("\n__ CodeHeapStateAnalytics lock wait took %10.3f seconds _________\n", ts.seconds());
!
! // If we serve an "allFun" call, it is beneficial to hold the CodeCache_lock
! // for the entire duration of aggregation and printing. That makes sure
! // we see a consistent picture and do not run into issues caused by
! // the CodeHeap being altered concurrently.
! Monitor* global_lock = allFun ? CodeCache_lock : NULL;
! Monitor* function_lock = allFun ? NULL : CodeCache_lock;
! ts_global.update(); // record starting point
! MutexLockerEx mu2(global_lock, Mutex::_no_safepoint_check_flag);
! if (global_lock != NULL) {
! out->print_cr("\n__ CodeCache (global) lock wait took %10.3f seconds _________\n", ts_global.seconds());
! ts_global.update(); // record starting point
! }
if (aggregate) {
ts.update(); // record starting point
! MutexLockerEx mu3(function_lock, Mutex::_no_safepoint_check_flag);
! if (function_lock != NULL) {
! out->print_cr("\n__ CodeCache (function) lock wait took %10.3f seconds _________\n", ts.seconds());
! }
ts.update(); // record starting point
CodeCache::aggregate(out, granularity);
! if (function_lock != NULL) {
! out->print_cr("\n__ CodeCache (function) lock hold took %10.3f seconds _________\n", ts.seconds());
! }
}
if (usedSpace) CodeCache::print_usedSpace(out);
if (freeSpace) CodeCache::print_freeSpace(out);
if (methodCount) CodeCache::print_count(out);
if (methodSpace) CodeCache::print_space(out);
if (methodAge) CodeCache::print_age(out);
! if (methodNames) {
! // print_names() has shown to be sensitive to concurrent CodeHeap modifications.
! // Therefore, request the CodeCache_lock before calling...
! MutexLockerEx mu3(function_lock, Mutex::_no_safepoint_check_flag);
! CodeCache::print_names(out);
! }
if (discard) CodeCache::discard(out);
! if (global_lock != NULL) {
! out->print_cr("\n__ CodeCache (global) lock hold took %10.3f seconds _________\n", ts_global.seconds());
! }
! out->print_cr("\n__ CodeHeapStateAnalytics total duration %10.3f seconds _________\n", ts_total.seconds());
}
< prev index next >