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