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