1 /*
2  * Copyright (c) 2020, 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 package jdk.vm.ci.hotspot;
26 
27 import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
28 
29 import java.util.Arrays;
30 import java.util.ArrayList;
31 import java.util.concurrent.ConcurrentHashMap;
32 
33 import jdk.vm.ci.meta.ResolvedJavaMethod;
34 
35 /**
36  * Helper methods for interacting with the Java Flight Recorder (JFR) to register events and notify it when events occur.
37  * The JFR events are defined in {see @code src/share/jfr/metadata/metadata.xml}.
38  */
39 public final class JFR {
40 
41     /**
42      * Provides access to current JFR time stamp.
43      */
44     public static final class Ticks {
45 
46         /**
47          * @return current JFR time stamp
48          */
now()49         public static long now() {
50             return compilerToVM().ticksNow();
51         }
52     }
53 
54     /**
55      * Helper methods for managing JFR CompilerPhase events.
56      * The events are defined in {see @code src/share/jfr/metadata/metadata.xml}.
57      */
58     public static final class CompilerPhaseEvent {
59 
60         private static final ConcurrentHashMap<String, Integer> phaseToId = new ConcurrentHashMap<>();
61 
getPhaseToId(String phaseName)62         private static int getPhaseToId(String phaseName) {
63             String[] phaseNames = { phaseName };
64             return phaseToId.computeIfAbsent(phaseName, k -> compilerToVM().registerCompilerPhases(phaseNames));
65         }
66 
67         /**
68          * Registers new compiler phases with JFR. This should be called during compiler initialization.
69          *
70          * @param phaseNames compiler phase names
71          */
registerPhases(String[] phaseNames)72         public static synchronized void registerPhases(String[] phaseNames) {
73             ArrayList<String> toProcess = new ArrayList<>(Arrays.asList(phaseNames));
74             toProcess.removeAll(phaseToId.keySet());
75             int pid = compilerToVM().registerCompilerPhases(toProcess.toArray(new String[toProcess.size()]));
76             for (String phase : toProcess) {
77                 phaseToId.put(phase, pid++);
78             }
79         }
80 
81         /**
82          * Commits a CompilerPhase event.
83          *
84          * @param startTime time captured at the start of compiler phase
85          * @param phaseName compiler phase name
86          * @param compileId current compilation unit id
87          * @param phaseLevel compiler phase nesting level
88          */
write(long startTime, String phaseName, int compileId, int phaseLevel)89         public static void write(long startTime, String phaseName, int compileId, int phaseLevel) {
90             compilerToVM().notifyCompilerPhaseEvent(startTime, getPhaseToId(phaseName), compileId, phaseLevel);
91         }
92     }
93 
94     /**
95      * Helper methods for managing JFR CompilerInlining events.
96      * The events are defined in {see @code src/share/jfr/metadata/metadata.xml}.
97      */
98     public static final class CompilerInliningEvent {
99 
100         /**
101          * Commits a CompilerInlining event.
102          *
103          * @param compileId current compilation unit id
104          * @param caller caller method
105          * @param callee callee method
106          * @param succeeded inlining succeeded or not
107          * @param message extra information on inlining
108          * @param bci invocation byte code index
109          */
write(int compileId, ResolvedJavaMethod caller, ResolvedJavaMethod callee, boolean succeeded, String message, int bci)110         public static void write(int compileId, ResolvedJavaMethod caller, ResolvedJavaMethod callee, boolean succeeded, String message, int bci) {
111             compilerToVM().notifyCompilerInliningEvent(compileId, (HotSpotResolvedJavaMethodImpl) caller, (HotSpotResolvedJavaMethodImpl) callee, succeeded, message, bci);
112         }
113     }
114 }
115 
116