1 /*
  2  * Copyright (c) 2000, 2023, 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 "compiler/compilerDefinitions.hpp"
 27 #include "gc/shared/gcConfig.hpp"
 28 #include "jvm.h"
 29 #include "jvmci/jvmci_globals.hpp"
 30 #include "logging/log.hpp"
 31 #include "runtime/arguments.hpp"
 32 #include "runtime/flags/jvmFlagAccess.hpp"
 33 #include "runtime/globals_extension.hpp"
 34 #include "utilities/defaultStream.hpp"
 35 #include "utilities/ostream.hpp"
 36 
 37 fileStream* JVMCIGlobals::_jni_config_file = nullptr;
 38 
 39 // Return true if jvmci flags are consistent.
 40 bool JVMCIGlobals::check_jvmci_flags_are_consistent() {
 41 
 42 #ifndef PRODUCT
 43 #define APPLY_JVMCI_FLAGS(params3, params4) \
 44   JVMCI_FLAGS(params4, params3, params4, params3, params4, IGNORE_RANGE, IGNORE_CONSTRAINT)
 45 #define JVMCI_DECLARE_CHECK4(type, name, value, ...) bool name##checked = false;
 46 #define JVMCI_DECLARE_CHECK3(type, name, ...)        bool name##checked = false;
 47 #define JVMCI_FLAG_CHECKED(name)                          name##checked = true;
 48   APPLY_JVMCI_FLAGS(JVMCI_DECLARE_CHECK3, JVMCI_DECLARE_CHECK4)
 49 #else
 50 #define JVMCI_FLAG_CHECKED(name)
 51 #endif
 52 
 53   // Checks that a given flag is not set if a given guard flag is false.
 54 #define CHECK_NOT_SET(FLAG, GUARD)                     \
 55   JVMCI_FLAG_CHECKED(FLAG)                             \
 56   if (!GUARD && !FLAG_IS_DEFAULT(FLAG)) {              \
 57     jio_fprintf(defaultStream::error_stream(),         \
 58         "Improperly specified VM option '%s': '%s' must be enabled\n", #FLAG, #GUARD); \
 59     return false;                                      \
 60   }
 61 
 62   if (EnableJVMCIProduct) {
 63     if (FLAG_IS_DEFAULT(EnableJVMCI)) {
 64       FLAG_SET_DEFAULT(EnableJVMCI, true);
 65     }
 66     if (EnableJVMCI && FLAG_IS_DEFAULT(UseJVMCICompiler)) {
 67       FLAG_SET_DEFAULT(UseJVMCICompiler, true);
 68     }
 69   }
 70 
 71   JVMCI_FLAG_CHECKED(UseJVMCICompiler)
 72   JVMCI_FLAG_CHECKED(EnableJVMCI)
 73   JVMCI_FLAG_CHECKED(EnableJVMCIProduct)
 74   JVMCI_FLAG_CHECKED(UseGraalJIT)
 75 
 76   CHECK_NOT_SET(BootstrapJVMCI,   UseJVMCICompiler)
 77   CHECK_NOT_SET(PrintBootstrap,   UseJVMCICompiler)
 78   CHECK_NOT_SET(JVMCIThreads,     UseJVMCICompiler)
 79   CHECK_NOT_SET(JVMCIHostThreads, UseJVMCICompiler)
 80 
 81   if (UseJVMCICompiler) {
 82     if (FLAG_IS_DEFAULT(UseJVMCINativeLibrary) && !UseJVMCINativeLibrary) {
 83       char path[JVM_MAXPATHLEN];
 84       if (os::dll_locate_lib(path, sizeof(path), Arguments::get_dll_dir(), JVMCI_SHARED_LIBRARY_NAME)) {
 85         // If a JVMCI native library is present,
 86         // we enable UseJVMCINativeLibrary by default.
 87         FLAG_SET_DEFAULT(UseJVMCINativeLibrary, true);
 88       }
 89     }
 90     if (!FLAG_IS_DEFAULT(EnableJVMCI) && !EnableJVMCI) {
 91       jio_fprintf(defaultStream::error_stream(),
 92           "Improperly specified VM option UseJVMCICompiler: EnableJVMCI cannot be disabled\n");
 93       return false;
 94     }
 95     FLAG_SET_DEFAULT(EnableJVMCI, true);
 96     if (BootstrapJVMCI && UseJVMCINativeLibrary) {
 97       jio_fprintf(defaultStream::error_stream(), "-XX:+BootstrapJVMCI is not compatible with -XX:+UseJVMCINativeLibrary\n");
 98       return false;
 99     }
100     if (BootstrapJVMCI && (TieredStopAtLevel < CompLevel_full_optimization)) {
101       jio_fprintf(defaultStream::error_stream(),
102           "-XX:+BootstrapJVMCI is not compatible with -XX:TieredStopAtLevel=%d\n", TieredStopAtLevel);
103       return false;
104     }
105   }
106 
107   if (!EnableJVMCI) {
108     // Switch off eager JVMCI initialization if JVMCI is disabled.
109     // Don't throw error if EagerJVMCI is set to allow testing.
110     if (EagerJVMCI) {
111       FLAG_SET_DEFAULT(EagerJVMCI, false);
112     }
113   }
114   JVMCI_FLAG_CHECKED(EagerJVMCI)
115 
116   CHECK_NOT_SET(JVMCIEventLogLevel,                  EnableJVMCI)
117   CHECK_NOT_SET(JVMCITraceLevel,                     EnableJVMCI)
118   CHECK_NOT_SET(JVMCICounterSize,                    EnableJVMCI)
119   CHECK_NOT_SET(JVMCICountersExcludeCompiler,        EnableJVMCI)
120   CHECK_NOT_SET(JVMCIUseFastLocking,                 EnableJVMCI)
121   CHECK_NOT_SET(JVMCINMethodSizeLimit,               EnableJVMCI)
122   CHECK_NOT_SET(JVMCIPrintProperties,                EnableJVMCI)
123   CHECK_NOT_SET(JVMCIThreadsPerNativeLibraryRuntime, EnableJVMCI)
124   CHECK_NOT_SET(JVMCICompilerIdleDelay,              EnableJVMCI)
125   CHECK_NOT_SET(UseJVMCINativeLibrary,               EnableJVMCI)
126   CHECK_NOT_SET(JVMCINativeLibraryThreadFraction,    EnableJVMCI)
127   CHECK_NOT_SET(JVMCILibPath,                        EnableJVMCI)
128   CHECK_NOT_SET(JVMCINativeLibraryErrorFile,         EnableJVMCI)
129   CHECK_NOT_SET(JVMCILibDumpJNIConfig,               EnableJVMCI)
130 
131 #ifndef COMPILER2
132   JVMCI_FLAG_CHECKED(MaxVectorSize)
133   JVMCI_FLAG_CHECKED(ReduceInitialCardMarks)
134   JVMCI_FLAG_CHECKED(UseMultiplyToLenIntrinsic)
135   JVMCI_FLAG_CHECKED(UseSquareToLenIntrinsic)
136   JVMCI_FLAG_CHECKED(UseMulAddIntrinsic)
137   JVMCI_FLAG_CHECKED(UseMontgomeryMultiplyIntrinsic)
138   JVMCI_FLAG_CHECKED(UseMontgomerySquareIntrinsic)
139 #endif // !COMPILER2
140 
141 #ifndef PRODUCT
142 #define JVMCI_CHECK4(type, name, value, ...) assert(name##checked, #name " flag not checked");
143 #define JVMCI_CHECK3(type, name, ...)        assert(name##checked, #name " flag not checked");
144   // Ensures that all JVMCI flags are checked by this method.
145   APPLY_JVMCI_FLAGS(JVMCI_CHECK3, JVMCI_CHECK4)
146 #undef APPLY_JVMCI_FLAGS
147 #undef JVMCI_DECLARE_CHECK3
148 #undef JVMCI_DECLARE_CHECK4
149 #undef JVMCI_CHECK3
150 #undef JVMCI_CHECK4
151 #undef JVMCI_FLAG_CHECKED
152 #endif // PRODUCT
153 #undef CHECK_NOT_SET
154 
155   if (JVMCILibDumpJNIConfig != nullptr) {
156     _jni_config_file = new(mtJVMCI) fileStream(JVMCILibDumpJNIConfig);
157     if (_jni_config_file == nullptr || !_jni_config_file->is_open()) {
158       jio_fprintf(defaultStream::error_stream(),
159           "Could not open file for dumping JVMCI shared library JNI config: %s\n", JVMCILibDumpJNIConfig);
160       return false;
161     }
162   }
163 
164   return true;
165 }
166 
167 // Convert JVMCI flags from experimental to product
168 bool JVMCIGlobals::enable_jvmci_product_mode(JVMFlagOrigin origin, bool use_graal_jit) {
169   const char *JVMCIFlags[] = {
170     "EnableJVMCI",
171     "EnableJVMCIProduct",
172     "UseJVMCICompiler",
173     "JVMCIThreadsPerNativeLibraryRuntime",
174     "JVMCICompilerIdleDelay",
175     "JVMCIPrintProperties",
176     "EagerJVMCI",
177     "JVMCIThreads",
178     "JVMCICounterSize",
179     "JVMCICountersExcludeCompiler",
180     "JVMCINMethodSizeLimit",
181     "JVMCIEventLogLevel",
182     "JVMCITraceLevel",
183     "JVMCILibPath",
184     "JVMCILibDumpJNIConfig",
185     "UseJVMCINativeLibrary",
186     "JVMCINativeLibraryThreadFraction",
187     "JVMCINativeLibraryErrorFile",
188     nullptr
189   };
190 
191   for (int i = 0; JVMCIFlags[i] != nullptr; i++) {
192     JVMFlag *jvmciFlag = (JVMFlag *)JVMFlag::find_declared_flag(JVMCIFlags[i]);
193     if (jvmciFlag == nullptr) {
194       return false;
195     }
196     jvmciFlag->clear_experimental();
197     jvmciFlag->set_product();
198   }
199 
200   bool value = true;
201   JVMFlag *jvmciEnableFlag = JVMFlag::find_flag("EnableJVMCIProduct");
202   if (JVMFlagAccess::set_bool(jvmciEnableFlag, &value, origin) != JVMFlag::SUCCESS) {
203     return false;
204   }
205   if (use_graal_jit) {
206     JVMFlag *useGraalJITFlag = JVMFlag::find_flag("UseGraalJIT");
207     if (JVMFlagAccess::set_bool(useGraalJITFlag, &value, origin) != JVMFlag::SUCCESS) {
208       return false;
209     }
210   }
211 
212   // Effect of EnableJVMCIProduct on changing defaults of EnableJVMCI
213   // and UseJVMCICompiler is deferred to check_jvmci_flags_are_consistent
214   // so that setting these flags explicitly (e.g. on the command line)
215   // takes precedence.
216 
217   return true;
218 }
219 
220 bool JVMCIGlobals::gc_supports_jvmci() {
221   return UseSerialGC || UseParallelGC || UseG1GC || (UseZGC && !ZGenerational);
222 }
223 
224 void JVMCIGlobals::check_jvmci_supported_gc() {
225   if (EnableJVMCI) {
226     // Check if selected GC is supported by JVMCI and Java compiler
227     if (!gc_supports_jvmci()) {
228       log_warning(gc, jvmci)("Setting EnableJVMCI to false as selected GC does not support JVMCI: %s", GCConfig::hs_err_name());
229       FLAG_SET_DEFAULT(EnableJVMCI, false);
230       FLAG_SET_DEFAULT(UseJVMCICompiler, false);
231     }
232   }
233 }