Path: blob/master/src/hotspot/share/utilities/events.cpp
64441 views
/*1* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "memory/allocation.inline.hpp"26#include "oops/instanceKlass.hpp"27#include "runtime/mutexLocker.hpp"28#include "runtime/osThread.hpp"29#include "runtime/thread.inline.hpp"30#include "runtime/threadCritical.hpp"31#include "runtime/timer.hpp"32#include "utilities/events.hpp"333435EventLog* Events::_logs = NULL;36StringEventLog* Events::_messages = NULL;37StringEventLog* Events::_vm_operations = NULL;38ExceptionsEventLog* Events::_exceptions = NULL;39StringEventLog* Events::_redefinitions = NULL;40UnloadingEventLog* Events::_class_unloading = NULL;41StringEventLog* Events::_deopt_messages = NULL;42StringEventLog* Events::_dll_messages = NULL;4344EventLog::EventLog() {45// This normally done during bootstrap when we're only single46// threaded but use a ThreadCritical to ensure inclusion in case47// some are created slightly late.48ThreadCritical tc;49_next = Events::_logs;50Events::_logs = this;51}5253// For each registered event logger, print out the current contents of54// the buffer.55void Events::print_all(outputStream* out, int max) {56EventLog* log = _logs;57while (log != NULL) {58log->print_log_on(out, max);59log = log->next();60}61}6263// Print a single event log specified by name.64void Events::print_one(outputStream* out, const char* log_name, int max) {65EventLog* log = _logs;66int num_printed = 0;67while (log != NULL) {68if (log->matches_name_or_handle(log_name)) {69log->print_log_on(out, max);70num_printed ++;71}72log = log->next();73}74// Write a short error note if no name matched.75if (num_printed == 0) {76out->print_cr("The name \"%s\" did not match any known event log. "77"Valid event log names are:", log_name);78EventLog* log = _logs;79while (log != NULL) {80log->print_names(out);81out->cr();82log = log->next();83}84}85}868788void Events::print() {89print_all(tty);90}9192void Events::init() {93if (LogEvents) {94_messages = new StringEventLog("Events", "events");95_vm_operations = new StringEventLog("VM Operations", "vmops");96_exceptions = new ExceptionsEventLog("Internal exceptions", "exc");97_redefinitions = new StringEventLog("Classes redefined", "redef");98_class_unloading = new UnloadingEventLog("Classes unloaded", "unload");99_deopt_messages = new StringEventLog("Deoptimization events", "deopt");100_dll_messages = new StringEventLog("Dll operation events", "dll");101}102}103104void eventlog_init() {105Events::init();106}107108///////////////////////////////////////////////////////////////////////////109// EventMark110111EventMarkBase::EventMarkBase(EventLogFunction log_function) :112_log_function(log_function),113_buffer() {}114115void EventMarkBase::log_start(const char* format, va_list argp) {116// Save a copy of begin message and log it.117_buffer.printv(format, argp);118_log_function(NULL, "%s", _buffer.buffer());119}120121void EventMarkBase::log_end() {122// Append " done" to the begin message and log it123_buffer.append(" done");124_log_function(NULL, "%s", _buffer.buffer());125}126127void UnloadingEventLog::log(Thread* thread, InstanceKlass* ik) {128if (!should_log()) return;129130double timestamp = fetch_timestamp();131// Unloading events are single threaded.132int index = compute_log_index();133_records[index].thread = thread;134_records[index].timestamp = timestamp;135stringStream st(_records[index].data.buffer(),136_records[index].data.size());137st.print("Unloading class " INTPTR_FORMAT " ", p2i(ik));138ik->name()->print_value_on(&st);139}140141void ExceptionsEventLog::log(Thread* thread, Handle h_exception, const char* message, const char* file, int line) {142if (!should_log()) return;143144double timestamp = fetch_timestamp();145MutexLocker ml(&_mutex, Mutex::_no_safepoint_check_flag);146int index = compute_log_index();147_records[index].thread = thread;148_records[index].timestamp = timestamp;149stringStream st(_records[index].data.buffer(),150_records[index].data.size());151st.print("Exception <");152h_exception->print_value_on(&st);153st.print("%s%s> (" INTPTR_FORMAT ") \n"154"thrown [%s, line %d]",155message ? ": " : "", message ? message : "",156p2i(h_exception()), file, line);157}158159160