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 }