| 1 | /* |
| 2 | * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. |
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| 4 | * |
| 5 | * This code is free software; you can redistribute it and/or modify it |
| 6 | * under the terms of the GNU General Public License version 2 only, as |
| 7 | * published by the Free Software Foundation. |
| 8 | * |
| 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
| 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| 12 | * version 2 for more details (a copy is included in the LICENSE file that |
| 13 | * accompanied this code). |
| 14 | * |
| 15 | * You should have received a copy of the GNU General Public License version |
| 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
| 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| 18 | * |
| 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| 20 | * or visit www.oracle.com if you need additional information or have any |
| 21 | * questions. |
| 22 | * |
| 23 | */ |
| 24 | |
| 25 | #include "precompiled.hpp" |
| 26 | #include "classfile/classLoaderData.inline.hpp" |
| 27 | #include "classfile/classLoaderDataGraph.hpp" |
| 28 | #include "classfile/moduleEntry.hpp" |
| 29 | #include "classfile/packageEntry.hpp" |
| 30 | #include "jfr/jfrEvents.hpp" |
| 31 | #include "jfr/periodic/jfrModuleEvent.hpp" |
| 32 | #include "jfr/utilities/jfrTime.hpp" |
| 33 | #include "runtime/mutexLocker.hpp" |
| 34 | |
| 35 | // we want all periodic module events to have the same timestamp |
| 36 | static JfrTicks invocation_time; |
| 37 | |
| 38 | typedef void (*EventFunc)(const void* iterated_address, const ModuleEntry* module); |
| 39 | class ModuleEventCallbackClosure : public ModuleClosure { |
| 40 | protected: |
| 41 | const EventFunc _event_func; |
| 42 | ModuleEventCallbackClosure(EventFunc ef) : _event_func(ef) {} |
| 43 | }; |
| 44 | |
| 45 | class ModuleDependencyClosure : public ModuleEventCallbackClosure { |
| 46 | private: |
| 47 | const ModuleEntry* const _module; |
| 48 | public: |
| 49 | ModuleDependencyClosure(const ModuleEntry* module, EventFunc ef) : ModuleEventCallbackClosure(ef), _module(module) {} |
| 50 | void do_module(ModuleEntry* entry); |
| 51 | }; |
| 52 | |
| 53 | class ModuleExportClosure : public ModuleEventCallbackClosure { |
| 54 | private: |
| 55 | const PackageEntry* const _package; |
| 56 | public: |
| 57 | ModuleExportClosure(const PackageEntry* pkg, EventFunc ef) : ModuleEventCallbackClosure(ef), _package(pkg) {} |
| 58 | void do_module(ModuleEntry* entry); |
| 59 | }; |
| 60 | |
| 61 | static void write_module_dependency_event(const void* from_module, const ModuleEntry* to_module) { |
| 62 | EventModuleRequire event(UNTIMED); |
| 63 | event.set_endtime(invocation_time); |
| 64 | event.set_source((const ModuleEntry* const)from_module); |
| 65 | event.set_requiredModule(to_module); |
| 66 | event.commit(); |
| 67 | } |
| 68 | |
| 69 | static void write_module_export_event(const void* package, const ModuleEntry* qualified_export) { |
| 70 | EventModuleExport event(UNTIMED); |
| 71 | event.set_endtime(invocation_time); |
| 72 | event.set_exportedPackage((const PackageEntry*)package); |
| 73 | event.set_targetModule(qualified_export); |
| 74 | event.commit(); |
| 75 | } |
| 76 | |
| 77 | void ModuleDependencyClosure::do_module(ModuleEntry* to_module) { |
| 78 | assert_locked_or_safepoint(Module_lock); |
| 79 | assert(to_module != NULL, "invariant" ); |
| 80 | assert(_module != NULL, "invariant" ); |
| 81 | assert(_event_func != NULL, "invariant" ); |
| 82 | _event_func(_module, to_module); |
| 83 | } |
| 84 | |
| 85 | void ModuleExportClosure::do_module(ModuleEntry* qualified_export) { |
| 86 | assert_locked_or_safepoint(Module_lock); |
| 87 | assert(qualified_export != NULL, "invariant" ); |
| 88 | assert(_package != NULL, "invariant" ); |
| 89 | assert(_event_func != NULL, "invariant" ); |
| 90 | _event_func(_package, qualified_export); |
| 91 | } |
| 92 | |
| 93 | static void module_dependency_event_callback(ModuleEntry* module) { |
| 94 | assert_locked_or_safepoint(Module_lock); |
| 95 | assert(module != NULL, "invariant" ); |
| 96 | if (module->has_reads_list()) { |
| 97 | // create an individual event for each directed edge |
| 98 | ModuleDependencyClosure directed_edges(module, &write_module_dependency_event); |
| 99 | module->module_reads_do(&directed_edges); |
| 100 | } |
| 101 | } |
| 102 | |
| 103 | static void module_export_event_callback(PackageEntry* package) { |
| 104 | assert_locked_or_safepoint(Module_lock); |
| 105 | assert(package != NULL, "invariant" ); |
| 106 | if (package->is_exported()) { |
| 107 | if (package->has_qual_exports_list()) { |
| 108 | // package is qualifiedly exported to a set of modules, |
| 109 | // create an event for each module in the qualified exported list |
| 110 | ModuleExportClosure qexports(package, &write_module_export_event); |
| 111 | package->package_exports_do(&qexports); |
| 112 | return; |
| 113 | } |
| 114 | |
| 115 | assert(!package->is_qual_exported() || package->is_exported_allUnnamed(), "invariant" ); |
| 116 | // no qualified exports |
| 117 | // only create a single event with NULL |
| 118 | // for the qualified_exports module |
| 119 | write_module_export_event(package, NULL); |
| 120 | } |
| 121 | } |
| 122 | |
| 123 | void JfrModuleEvent::generate_module_dependency_events() { |
| 124 | invocation_time = JfrTicks::now(); |
| 125 | MutexLocker cld_lock(ClassLoaderDataGraph_lock); |
| 126 | MutexLocker module_lock(Module_lock); |
| 127 | ClassLoaderDataGraph::modules_do(&module_dependency_event_callback); |
| 128 | } |
| 129 | |
| 130 | void JfrModuleEvent::generate_module_export_events() { |
| 131 | invocation_time = JfrTicks::now(); |
| 132 | MutexLocker cld_lock(ClassLoaderDataGraph_lock); |
| 133 | MutexLocker module_lock(Module_lock); |
| 134 | ClassLoaderDataGraph::packages_do(&module_export_event_callback); |
| 135 | } |
| 136 | |