< 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 >