Path: blob/master/src/hotspot/share/compiler/compilerEvent.cpp
40930 views
/*1* Copyright (c) 2020, 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*/23#include "precompiled.hpp"24#include "ci/ciMethod.hpp"25#include "compiler/compilerEvent.hpp"26#include "jfr/jfr.hpp"27#include "jfr/jfrEvents.hpp"28#include "jfr/metadata/jfrSerializer.hpp"29#include "runtime/semaphore.inline.hpp"30#include "utilities/growableArray.hpp"3132// Synchronizes access to phases_names.33class PhaseTypeGuard : public StackObj {34private:35static Semaphore _mutex_semaphore;36bool _enabled;37public:38PhaseTypeGuard(bool enabled=true) {39if (enabled) {40_mutex_semaphore.wait();41_enabled = true;42} else {43_enabled = false;44}45}46~PhaseTypeGuard() {47if (_enabled) {48_mutex_semaphore.signal();49}50}51};5253Semaphore PhaseTypeGuard::_mutex_semaphore(1);5455// Table for mapping compiler phases names to int identifiers.56static GrowableArray<const char*>* phase_names = NULL;5758class CompilerPhaseTypeConstant : public JfrSerializer {59public:60void serialize(JfrCheckpointWriter& writer) {61PhaseTypeGuard guard;62assert(phase_names != NULL, "invariant");63assert(phase_names->is_nonempty(), "invariant");64const u4 nof_entries = phase_names->length();65writer.write_count(nof_entries);66for (u4 i = 0; i < nof_entries; i++) {67writer.write_key(i);68writer.write(phase_names->at(i));69}70}71};7273static int lookup_phase(const char* phase_name) {74for (int i = 0; i < phase_names->length(); i++) {75const char* name = phase_names->at(i);76if (strcmp(name, phase_name) == 0) {77return i;78}79}80return -1;81}8283int CompilerEvent::PhaseEvent::get_phase_id(const char* phase_name, bool may_exist, bool use_strdup, bool sync) {84int index;85bool register_jfr_serializer = false;86{87PhaseTypeGuard guard(sync);88if (phase_names == NULL) {89phase_names = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<const char*>(100, mtCompiler);90register_jfr_serializer = true;91} else if (may_exist) {92index = lookup_phase(phase_name);93if (index != -1) {94return index;95}96} else {97assert((index = lookup_phase(phase_name)) == -1, "phase name \"%s\" already registered: %d", phase_name, index);98}99100index = phase_names->length();101phase_names->append(use_strdup ? strdup(phase_name) : phase_name);102}103if (register_jfr_serializer) {104JfrSerializer::register_serializer(TYPE_COMPILERPHASETYPE, false, new CompilerPhaseTypeConstant());105} else if (Jfr::is_recording()) {106// serialize new phase.107JfrCheckpointWriter writer;108writer.write_type(TYPE_COMPILERPHASETYPE);109writer.write_count(1);110writer.write_key(index);111writer.write(phase_name);112}113return index;114}115116void CompilerEvent::CompilationEvent::post(EventCompilation& event, int compile_id, CompilerType compiler_type, Method* method, int compile_level, bool success, bool is_osr, int code_size, int inlined_bytecodes) {117event.set_compileId(compile_id);118event.set_compiler(compiler_type);119event.set_method(method);120event.set_compileLevel((short)compile_level);121event.set_succeded(success);122event.set_isOsr(is_osr);123event.set_codeSize(code_size);124event.set_inlinedBytes(inlined_bytecodes);125event.commit();126}127128void CompilerEvent::CompilationFailureEvent::post(EventCompilationFailure& event, int compile_id, const char* reason) {129event.set_compileId(compile_id);130event.set_failureMessage(reason);131event.commit();132}133134void CompilerEvent::PhaseEvent::post(EventCompilerPhase& event, const Ticks& start_time, int phase, int compile_id, int level) {135event.set_starttime(start_time);136event.set_phase((u1) phase);137event.set_compileId(compile_id);138event.set_phaseLevel((short)level);139event.commit();140}141142void CompilerEvent::InlineEvent::post(EventCompilerInlining& event, int compile_id, Method* caller, const JfrStructCalleeMethod& callee, bool success, const char* msg, int bci) {143event.set_compileId(compile_id);144event.set_caller(caller);145event.set_callee(callee);146event.set_succeeded(success);147event.set_message(msg);148event.set_bci(bci);149event.commit();150}151152void CompilerEvent::InlineEvent::post(EventCompilerInlining& event, int compile_id, Method* caller, Method* callee, bool success, const char* msg, int bci) {153JfrStructCalleeMethod callee_struct;154callee_struct.set_type(callee->klass_name()->as_utf8());155callee_struct.set_name(callee->name()->as_utf8());156callee_struct.set_descriptor(callee->signature()->as_utf8());157post(event, compile_id, caller, callee_struct, success, msg, bci);158}159160void CompilerEvent::InlineEvent::post(EventCompilerInlining& event, int compile_id, Method* caller, ciMethod* callee, bool success, const char* msg, int bci) {161JfrStructCalleeMethod callee_struct;162callee_struct.set_type(callee->holder()->name()->as_utf8());163callee_struct.set_name(callee->name()->as_utf8());164callee_struct.set_descriptor(callee->signature()->as_symbol()->as_utf8());165post(event, compile_id, caller, callee_struct, success, msg, bci);166}167168169