1 /*
2  * Copyright (c) 2018, 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 package sun.hotspot.code;
25 
26 import java.lang.reflect.Executable;
27 import sun.hotspot.WhiteBox;
28 
29 /**
30  * API to obtain information about enabled JIT compilers
31  * retrieved from the VM with the WhiteBox API.
32  */
33 public class Compiler {
34 
35     private static final WhiteBox WB = WhiteBox.getWhiteBox();
36 
37     /**
38      * Check if C2 or JVMCI were included in the VM build
39      *
40      * @return true if either C2 or JVMCI were included in the VM build.
41      */
isC2OrJVMCIIncludedInVmBuild()42     public static boolean isC2OrJVMCIIncludedInVmBuild() {
43         return WB.isC2OrJVMCIIncludedInVmBuild();
44     }
45 
46     /**
47      * Check if Graal is used as JIT compiler.
48      *
49      * Graal is enabled if following conditions are true:
50      * - we are not in Interpreter mode
51      * - UseJVMCICompiler flag is true
52      * - jvmci.Compiler variable is equal to 'graal'
53      * - TieredCompilation is not used or TieredStopAtLevel is greater than 3
54      * No need to check client mode because it set UseJVMCICompiler to false.
55      *
56      * @return true if Graal is used as JIT compiler.
57      */
isGraalEnabled()58     public static boolean isGraalEnabled() {
59         Boolean useCompiler = WB.getBooleanVMFlag("UseCompiler");
60         if (useCompiler == null || !useCompiler) {
61             return false;
62         }
63         Boolean useJvmciComp = WB.getBooleanVMFlag("UseJVMCICompiler");
64         if (useJvmciComp == null || !useJvmciComp) {
65             return false;
66         }
67 
68         Boolean tieredCompilation = WB.getBooleanVMFlag("TieredCompilation");
69         Long compLevel = WB.getIntxVMFlag("TieredStopAtLevel");
70         // if TieredCompilation is enabled and compilation level is <= 3 then no Graal is used
71         if (tieredCompilation != null && tieredCompilation &&
72             compLevel != null && compLevel <= 3) {
73             return false;
74         }
75         return true;
76     }
77 
78     /**
79      * Check if C2 is used as JIT compiler.
80      *
81      * C2 is enabled if following conditions are true:
82      * - we are not in Interpreter mode
83      * - we are in Server compilation mode
84      * - TieredCompilation is not used or TieredStopAtLevel is greater than 3
85      * - Graal is not used
86      *
87      * @return true if C2 is used as JIT compiler.
88      */
isC2Enabled()89     public static boolean isC2Enabled() {
90         Boolean useCompiler = WB.getBooleanVMFlag("UseCompiler");
91         if (useCompiler == null || !useCompiler) {
92             return false;
93         }
94         Boolean serverMode = WB.getBooleanVMFlag("ProfileInterpreter");
95         if (serverMode == null || !serverMode) {
96             return false;
97         }
98 
99         Boolean tieredCompilation = WB.getBooleanVMFlag("TieredCompilation");
100         Long compLevel = WB.getIntxVMFlag("TieredStopAtLevel");
101         // if TieredCompilation is enabled and compilation level is <= 3 then no Graal is used
102         if (tieredCompilation != null && tieredCompilation &&
103             compLevel != null && compLevel <= 3) {
104             return false;
105         }
106 
107         if (isGraalEnabled()) {
108             return false;
109         }
110 
111         return true;
112     }
113 
114     /*
115      * Check if C1 is used as JIT compiler.
116      *
117      * C1 is enabled if following conditions are true:
118      * - we are not in Interpreter mode
119      * - we are not in Server compilation mode
120      * - TieredCompilation is used in Server mode
121      *
122      * @return true if C1 is used as JIT compiler.
123      */
isC1Enabled()124     public static boolean isC1Enabled() {
125         Boolean useCompiler = WB.getBooleanVMFlag("UseCompiler");
126         if (useCompiler == null || !useCompiler) {
127             return false;
128         }
129         Boolean serverMode = WB.getBooleanVMFlag("ProfileInterpreter");
130         if (serverMode == null || !serverMode) {
131             return true; // Client mode
132         }
133 
134         Boolean tieredCompilation = WB.getBooleanVMFlag("TieredCompilation");
135         // C1 is not used in server mode if TieredCompilation is off.
136         if (tieredCompilation != null && !tieredCompilation) {
137             return false;
138         }
139         return true;
140     }
141 
142     /*
143      * Determine if the compiler corresponding to the compilation level 'compLevel'
144      * provides an intrinsic for 'class'.'method'.
145      */
isIntrinsicAvailable(int compLevel, String klass, String method, Class<?>... parameterTypes)146     public static boolean isIntrinsicAvailable(int compLevel, String klass, String method, Class<?>... parameterTypes) {
147         Executable intrinsicMethod;
148         try {
149             intrinsicMethod = Class.forName(klass).getDeclaredMethod(method, parameterTypes);
150         } catch (NoSuchMethodException e) {
151             throw new RuntimeException("Test bug, '" + method + "' method unavailable. " + e);
152         } catch (ClassNotFoundException e) {
153             throw new RuntimeException("Test bug, '" + klass + "' class unavailable. " + e);
154         }
155         return WB.isIntrinsicAvailable(intrinsicMethod, compLevel);
156     }
157 }
158