duke@435: /* hseigel@5891: * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * trims@1907: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA trims@1907: * or visit www.oracle.com if you need additional information or have any trims@1907: * questions. duke@435: * duke@435: */ duke@435: stefank@2314: #include "precompiled.hpp" stefank@2314: #include "classfile/classLoader.hpp" stefank@2314: #include "services/attachListener.hpp" stefank@2314: #include "services/management.hpp" stefank@2314: #include "services/runtimeService.hpp" stefank@2314: #include "utilities/dtrace.hpp" stefank@2314: #include "utilities/exceptions.hpp" jprovino@4542: #include "utilities/macros.hpp" duke@435: dcubed@3202: #ifndef USDT2 duke@435: HS_DTRACE_PROBE_DECL(hs_private, safepoint__begin); duke@435: HS_DTRACE_PROBE_DECL(hs_private, safepoint__end); dcubed@3202: #endif /* !USDT2 */ duke@435: jprovino@4165: #if INCLUDE_MANAGEMENT duke@435: TimeStamp RuntimeService::_app_timer; duke@435: TimeStamp RuntimeService::_safepoint_timer; duke@435: PerfCounter* RuntimeService::_sync_time_ticks = NULL; duke@435: PerfCounter* RuntimeService::_total_safepoints = NULL; duke@435: PerfCounter* RuntimeService::_safepoint_time_ticks = NULL; duke@435: PerfCounter* RuntimeService::_application_time_ticks = NULL; duke@435: PerfCounter* RuntimeService::_thread_interrupt_signaled_count = NULL; duke@435: PerfCounter* RuntimeService::_interrupted_before_count = NULL; duke@435: PerfCounter* RuntimeService::_interrupted_during_count = NULL; duke@435: duke@435: void RuntimeService::init() { duke@435: // Make sure the VM version is initialized duke@435: Abstract_VM_Version::initialize(); duke@435: duke@435: if (UsePerfData) { duke@435: EXCEPTION_MARK; duke@435: duke@435: _sync_time_ticks = duke@435: PerfDataManager::create_counter(SUN_RT, "safepointSyncTime", duke@435: PerfData::U_Ticks, CHECK); duke@435: duke@435: _total_safepoints = duke@435: PerfDataManager::create_counter(SUN_RT, "safepoints", duke@435: PerfData::U_Events, CHECK); duke@435: duke@435: _safepoint_time_ticks = duke@435: PerfDataManager::create_counter(SUN_RT, "safepointTime", duke@435: PerfData::U_Ticks, CHECK); duke@435: duke@435: _application_time_ticks = duke@435: PerfDataManager::create_counter(SUN_RT, "applicationTime", duke@435: PerfData::U_Ticks, CHECK); duke@435: duke@435: duke@435: // create performance counters for jvm_version and its capabilities duke@435: PerfDataManager::create_constant(SUN_RT, "jvmVersion", PerfData::U_None, duke@435: (jlong) Abstract_VM_Version::jvm_version(), CHECK); duke@435: duke@435: // I/O interruption related counters duke@435: duke@435: // thread signaling via os::interrupt() duke@435: duke@435: _thread_interrupt_signaled_count = duke@435: PerfDataManager::create_counter(SUN_RT, duke@435: "threadInterruptSignaled", PerfData::U_Events, CHECK); duke@435: duke@435: // OS_INTRPT via "check before" in _INTERRUPTIBLE duke@435: duke@435: _interrupted_before_count = duke@435: PerfDataManager::create_counter(SUN_RT, "interruptedBeforeIO", duke@435: PerfData::U_Events, CHECK); duke@435: duke@435: // OS_INTRPT via "check during" in _INTERRUPTIBLE duke@435: duke@435: _interrupted_during_count = duke@435: PerfDataManager::create_counter(SUN_RT, "interruptedDuringIO", duke@435: PerfData::U_Events, CHECK); duke@435: duke@435: // The capabilities counter is a binary representation of the VM capabilities in string. duke@435: // This string respresentation simplifies the implementation of the client side duke@435: // to parse the value. duke@435: char capabilities[65]; duke@435: size_t len = sizeof(capabilities); duke@435: memset((void*) capabilities, '0', len); duke@435: capabilities[len-1] = '\0'; duke@435: capabilities[0] = AttachListener::is_attach_supported() ? '1' : '0'; jprovino@4165: #if INCLUDE_SERVICES duke@435: capabilities[1] = '1'; jprovino@4165: #endif // INCLUDE_SERVICES duke@435: PerfDataManager::create_string_constant(SUN_RT, "jvmCapabilities", duke@435: capabilities, CHECK); duke@435: } duke@435: } duke@435: duke@435: void RuntimeService::record_safepoint_begin() { dcubed@3202: #ifndef USDT2 duke@435: HS_DTRACE_PROBE(hs_private, safepoint__begin); dcubed@3202: #else /* USDT2 */ dcubed@3202: HS_PRIVATE_SAFEPOINT_BEGIN(); dcubed@3202: #endif /* USDT2 */ johnc@1695: johnc@1695: // Print the time interval in which the app was executing hseigel@5891: if (PrintGCApplicationConcurrentTime && _app_timer.is_updated()) { brutisso@4934: gclog_or_tty->date_stamp(PrintGCDateStamps); brutisso@4934: gclog_or_tty->stamp(PrintGCTimeStamps); johnc@1695: gclog_or_tty->print_cr("Application time: %3.7f seconds", johnc@1695: last_application_time_sec()); johnc@1695: } johnc@1695: duke@435: // update the time stamp to begin recording safepoint time duke@435: _safepoint_timer.update(); duke@435: if (UsePerfData) { duke@435: _total_safepoints->inc(); duke@435: if (_app_timer.is_updated()) { duke@435: _application_time_ticks->inc(_app_timer.ticks_since_update()); duke@435: } duke@435: } duke@435: } duke@435: duke@435: void RuntimeService::record_safepoint_synchronized() { duke@435: if (UsePerfData) { duke@435: _sync_time_ticks->inc(_safepoint_timer.ticks_since_update()); duke@435: } duke@435: } duke@435: duke@435: void RuntimeService::record_safepoint_end() { dcubed@3202: #ifndef USDT2 duke@435: HS_DTRACE_PROBE(hs_private, safepoint__end); dcubed@3202: #else /* USDT2 */ dcubed@3202: HS_PRIVATE_SAFEPOINT_END(); dcubed@3202: #endif /* USDT2 */ johnc@1695: johnc@1695: // Print the time interval for which the app was stopped johnc@1695: // during the current safepoint operation. johnc@1695: if (PrintGCApplicationStoppedTime) { brutisso@4934: gclog_or_tty->date_stamp(PrintGCDateStamps); brutisso@4934: gclog_or_tty->stamp(PrintGCTimeStamps); johnc@1695: gclog_or_tty->print_cr("Total time for which application threads " johnc@1695: "were stopped: %3.7f seconds", johnc@1695: last_safepoint_time_sec()); johnc@1695: } johnc@1695: duke@435: // update the time stamp to begin recording app time duke@435: _app_timer.update(); duke@435: if (UsePerfData) { duke@435: _safepoint_time_ticks->inc(_safepoint_timer.ticks_since_update()); duke@435: } duke@435: } duke@435: duke@435: void RuntimeService::record_application_start() { duke@435: // update the time stamp to begin recording app time duke@435: _app_timer.update(); duke@435: } duke@435: duke@435: // Don't need to record application end because we currently duke@435: // exit at a safepoint and record_safepoint_begin() handles updating duke@435: // the application time counter at VM exit. duke@435: duke@435: jlong RuntimeService::safepoint_sync_time_ms() { duke@435: return UsePerfData ? duke@435: Management::ticks_to_ms(_sync_time_ticks->get_value()) : -1; duke@435: } duke@435: duke@435: jlong RuntimeService::safepoint_count() { duke@435: return UsePerfData ? duke@435: _total_safepoints->get_value() : -1; duke@435: } duke@435: jlong RuntimeService::safepoint_time_ms() { duke@435: return UsePerfData ? duke@435: Management::ticks_to_ms(_safepoint_time_ticks->get_value()) : -1; duke@435: } duke@435: duke@435: jlong RuntimeService::application_time_ms() { duke@435: return UsePerfData ? duke@435: Management::ticks_to_ms(_application_time_ticks->get_value()) : -1; duke@435: } duke@435: duke@435: void RuntimeService::record_interrupted_before_count() { duke@435: if (UsePerfData) { duke@435: _interrupted_before_count->inc(); duke@435: } duke@435: } duke@435: duke@435: void RuntimeService::record_interrupted_during_count() { duke@435: if (UsePerfData) { duke@435: _interrupted_during_count->inc(); duke@435: } duke@435: } duke@435: duke@435: void RuntimeService::record_thread_interrupt_signaled_count() { duke@435: if (UsePerfData) { duke@435: _thread_interrupt_signaled_count->inc(); duke@435: } duke@435: } jprovino@4165: jprovino@4165: #endif // INCLUDE_MANAGEMENT