Path: blob/master/src/hotspot/share/jfr/periodic/jfrModuleEvent.cpp
41152 views
/*1* Copyright (c) 2015, 2018, 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 "classfile/classLoaderData.inline.hpp"26#include "classfile/classLoaderDataGraph.hpp"27#include "classfile/moduleEntry.hpp"28#include "classfile/packageEntry.hpp"29#include "jfr/jfrEvents.hpp"30#include "jfr/periodic/jfrModuleEvent.hpp"31#include "jfr/utilities/jfrTime.hpp"32#include "runtime/mutexLocker.hpp"3334// we want all periodic module events to have the same timestamp35static JfrTicks invocation_time;3637typedef void (*EventFunc)(const void* iterated_address, const ModuleEntry* module);38class ModuleEventCallbackClosure : public ModuleClosure {39protected:40const EventFunc _event_func;41ModuleEventCallbackClosure(EventFunc ef) : _event_func(ef) {}42};4344class ModuleDependencyClosure : public ModuleEventCallbackClosure {45private:46const ModuleEntry* const _module;47public:48ModuleDependencyClosure(const ModuleEntry* module, EventFunc ef) : ModuleEventCallbackClosure(ef), _module(module) {}49void do_module(ModuleEntry* entry);50};5152class ModuleExportClosure : public ModuleEventCallbackClosure {53private:54const PackageEntry* const _package;55public:56ModuleExportClosure(const PackageEntry* pkg, EventFunc ef) : ModuleEventCallbackClosure(ef), _package(pkg) {}57void do_module(ModuleEntry* entry);58};5960static void write_module_dependency_event(const void* from_module, const ModuleEntry* to_module) {61EventModuleRequire event(UNTIMED);62event.set_endtime(invocation_time);63event.set_source((const ModuleEntry* const)from_module);64event.set_requiredModule(to_module);65event.commit();66}6768static void write_module_export_event(const void* package, const ModuleEntry* qualified_export) {69EventModuleExport event(UNTIMED);70event.set_endtime(invocation_time);71event.set_exportedPackage((const PackageEntry*)package);72event.set_targetModule(qualified_export);73event.commit();74}7576void ModuleDependencyClosure::do_module(ModuleEntry* to_module) {77assert_locked_or_safepoint(Module_lock);78assert(to_module != NULL, "invariant");79assert(_module != NULL, "invariant");80assert(_event_func != NULL, "invariant");81_event_func(_module, to_module);82}8384void ModuleExportClosure::do_module(ModuleEntry* qualified_export) {85assert_locked_or_safepoint(Module_lock);86assert(qualified_export != NULL, "invariant");87assert(_package != NULL, "invariant");88assert(_event_func != NULL, "invariant");89_event_func(_package, qualified_export);90}9192static void module_dependency_event_callback(ModuleEntry* module) {93assert_locked_or_safepoint(Module_lock);94assert(module != NULL, "invariant");95if (module->has_reads_list()) {96// create an individual event for each directed edge97ModuleDependencyClosure directed_edges(module, &write_module_dependency_event);98module->module_reads_do(&directed_edges);99}100}101102static void module_export_event_callback(PackageEntry* package) {103assert_locked_or_safepoint(Module_lock);104assert(package != NULL, "invariant");105if (package->is_exported()) {106if (package->has_qual_exports_list()) {107// package is qualifiedly exported to a set of modules,108// create an event for each module in the qualified exported list109ModuleExportClosure qexports(package, &write_module_export_event);110package->package_exports_do(&qexports);111return;112}113114assert(!package->is_qual_exported() || package->is_exported_allUnnamed(), "invariant");115// no qualified exports116// only create a single event with NULL117// for the qualified_exports module118write_module_export_event(package, NULL);119}120}121122void JfrModuleEvent::generate_module_dependency_events() {123invocation_time = JfrTicks::now();124MutexLocker cld_lock(ClassLoaderDataGraph_lock);125MutexLocker module_lock(Module_lock);126ClassLoaderDataGraph::modules_do(&module_dependency_event_callback);127}128129void JfrModuleEvent::generate_module_export_events() {130invocation_time = JfrTicks::now();131MutexLocker cld_lock(ClassLoaderDataGraph_lock);132MutexLocker module_lock(Module_lock);133ClassLoaderDataGraph::packages_do(&module_export_event_callback);134}135136137