1 /*
   2  * Copyright (c) 2000, 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 #include "precompiled.hpp"
  26 #include "jvm.h"
  27 #include "jvmci/jvmci_globals.hpp"
  28 #include "gc/shared/gcConfig.hpp"
  29 #include "memory/resourceArea.hpp"
  30 #include "runtime/flags/jvmFlag.inline.hpp"
  31 #include "utilities/defaultStream.hpp"
  32 #include "utilities/ostream.hpp"
  33 #include "utilities/resourceHash.hpp"
  34 
  35 fileStream* JVMCIGlobals::_jni_config_file = NULL;
  36 
  37 #ifndef PRODUCT
  38 typedef ResourceHashtable<
  39   void*,
  40   bool,
  41   primitive_hash<void*>,
  42   primitive_equals<void*>,
  43   139, // prime number
  44   ResourceObj::C_HEAP // It's too early in VM bootstrap, cannot use resource allocation yet
  45   > JVMCIFlagCheckingTable;
  46 
  47 static void set_checked(JVMCIFlagCheckingTable* table, void* flag) {
  48   table->put(flag, true);
  49 }
  50 static bool has_checked(JVMCIFlagCheckingTable* table, void* flag) {
  51   return table->get(flag) != NULL;
  52 }
  53 #endif // PRODUCT
  54 
  55 // Return true if jvmci flags are consistent.
  56 bool JVMCIGlobals::check_jvmci_flags_are_consistent() {
  57 
  58 #ifndef PRODUCT
  59   JVMCIFlagCheckingTable table;
  60 #define JVMCI_FLAG_CHECKED(name) set_checked(&table, (void*)&name);
  61 #else
  62 #define JVMCI_FLAG_CHECKED(name)
  63 #endif
  64 
  65   // Checks that a given flag is not set if a given guard flag is false.
  66 #define CHECK_NOT_SET(FLAG, GUARD)                     \
  67   JVMCI_FLAG_CHECKED(FLAG)                             \
  68   if (!GUARD && !FLAG_IS_DEFAULT(FLAG)) {              \
  69     jio_fprintf(defaultStream::error_stream(),         \
  70         "Improperly specified VM option '%s': '%s' must be enabled\n", #FLAG, #GUARD); \
  71     return false;                                      \
  72   }
  73 
  74   if (EnableJVMCIProduct) {
  75     if (FLAG_IS_DEFAULT(EnableJVMCI)) {
  76       FLAG_SET_DEFAULT(EnableJVMCI, true);
  77     }
  78     if (EnableJVMCI && FLAG_IS_DEFAULT(UseJVMCICompiler)) {
  79       FLAG_SET_DEFAULT(UseJVMCICompiler, true);
  80     }
  81   }
  82 
  83   JVMCI_FLAG_CHECKED(UseJVMCICompiler)
  84   JVMCI_FLAG_CHECKED(EnableJVMCI)
  85   JVMCI_FLAG_CHECKED(EnableJVMCIProduct)
  86 
  87   CHECK_NOT_SET(BootstrapJVMCI,   UseJVMCICompiler)
  88   CHECK_NOT_SET(PrintBootstrap,   UseJVMCICompiler)
  89   CHECK_NOT_SET(JVMCIThreads,     UseJVMCICompiler)
  90   CHECK_NOT_SET(JVMCIHostThreads, UseJVMCICompiler)
  91 
  92   if (UseJVMCICompiler) {
  93     if (FLAG_IS_DEFAULT(UseJVMCINativeLibrary) && !UseJVMCINativeLibrary) {
  94       char path[JVM_MAXPATHLEN];
  95       if (os::dll_locate_lib(path, sizeof(path), Arguments::get_dll_dir(), JVMCI_SHARED_LIBRARY_NAME)) {
  96         // If a JVMCI native library is present,
  97         // we enable UseJVMCINativeLibrary by default.
  98         FLAG_SET_DEFAULT(UseJVMCINativeLibrary, true);
  99       }
 100     }
 101     if (!FLAG_IS_DEFAULT(EnableJVMCI) && !EnableJVMCI) {
 102       jio_fprintf(defaultStream::error_stream(),
 103           "Improperly specified VM option UseJVMCICompiler: EnableJVMCI cannot be disabled\n");
 104       return false;
 105     }
 106     FLAG_SET_DEFAULT(EnableJVMCI, true);
 107     if (BootstrapJVMCI && UseJVMCINativeLibrary) {
 108       jio_fprintf(defaultStream::error_stream(), "-XX:+BootstrapJVMCI is not compatible with -XX:+UseJVMCINativeLibrary\n");
 109       return false;
 110     }
 111     if (BootstrapJVMCI && (TieredStopAtLevel < CompLevel_full_optimization)) {
 112       jio_fprintf(defaultStream::error_stream(),
 113           "-XX:+BootstrapJVMCI is not compatible with -XX:TieredStopAtLevel=%d\n", TieredStopAtLevel);
 114       return false;
 115     }
 116   }
 117 
 118   if (!EnableJVMCI) {
 119     // Switch off eager JVMCI initialization if JVMCI is disabled.
 120     // Don't throw error if EagerJVMCI is set to allow testing.
 121     if (EagerJVMCI) {
 122       FLAG_SET_DEFAULT(EagerJVMCI, false);
 123     }
 124   }
 125   JVMCI_FLAG_CHECKED(EagerJVMCI)
 126 
 127   CHECK_NOT_SET(JVMCITraceLevel,              EnableJVMCI)
 128   CHECK_NOT_SET(JVMCICounterSize,             EnableJVMCI)
 129   CHECK_NOT_SET(JVMCICountersExcludeCompiler, EnableJVMCI)
 130   CHECK_NOT_SET(JVMCIUseFastLocking,          EnableJVMCI)
 131   CHECK_NOT_SET(JVMCINMethodSizeLimit,        EnableJVMCI)
 132   CHECK_NOT_SET(JVMCIPrintProperties,         EnableJVMCI)
 133   CHECK_NOT_SET(UseJVMCINativeLibrary,        EnableJVMCI)
 134   CHECK_NOT_SET(JVMCILibPath,                 EnableJVMCI)
 135   CHECK_NOT_SET(JVMCILibDumpJNIConfig,        EnableJVMCI)
 136 
 137 #ifndef COMPILER2
 138   JVMCI_FLAG_CHECKED(MaxVectorSize)
 139   JVMCI_FLAG_CHECKED(ReduceInitialCardMarks)
 140   JVMCI_FLAG_CHECKED(UseMultiplyToLenIntrinsic)
 141   JVMCI_FLAG_CHECKED(UseSquareToLenIntrinsic)
 142   JVMCI_FLAG_CHECKED(UseMulAddIntrinsic)
 143   JVMCI_FLAG_CHECKED(UseMontgomeryMultiplyIntrinsic)
 144   JVMCI_FLAG_CHECKED(UseMontgomerySquareIntrinsic)
 145 #endif // !COMPILER2
 146 
 147 #ifndef PRODUCT
 148   // Ensures that all JVMCI flags are checked by this method.
 149   JVMFlag* flag;
 150   JVMFLAG_FOR_EACH(flag) {
 151     if (flag->attr() & JVMFlag::JVMCI) {
 152       assert(has_checked(&table, flag->value_addr()), "%s flag not checked", flag->name());
 153     }
 154   }
 155 #endif // PRODUCT
 156 
 157   if (JVMCILibDumpJNIConfig != NULL) {
 158     _jni_config_file = new(ResourceObj::C_HEAP, mtJVMCI) fileStream(JVMCILibDumpJNIConfig);
 159     if (_jni_config_file == NULL || !_jni_config_file->is_open()) {
 160       jio_fprintf(defaultStream::error_stream(),
 161           "Could not open file for dumping JVMCI shared library JNI config: %s\n", JVMCILibDumpJNIConfig);
 162       return false;
 163     }
 164   }
 165 
 166   return true;
 167 }
 168 
 169 // Convert JVMCI flags from experimental to product
 170 bool JVMCIGlobals::enable_jvmci_product_mode(JVMFlag::Flags origin) {
 171   const char *JVMCIFlags[] = {
 172     "EnableJVMCI",
 173     "EnableJVMCIProduct",
 174     "UseJVMCICompiler",
 175     "JVMCIPrintProperties",
 176     "EagerJVMCI",
 177     "JVMCIThreads",
 178     "JVMCICounterSize",
 179     "JVMCICountersExcludeCompiler",
 180     "JVMCINMethodSizeLimit",
 181     "JVMCILibPath",
 182     "JVMCILibDumpJNIConfig",
 183     "UseJVMCINativeLibrary",
 184     NULL
 185   };
 186 
 187   for (int i = 0; JVMCIFlags[i] != NULL; i++) {
 188     JVMFlag *jvmciFlag = (JVMFlag *)JVMFlag::find_declared_flag(JVMCIFlags[i]);
 189     if (jvmciFlag == NULL) {
 190       return false;
 191     }
 192     jvmciFlag->clear_experimental();
 193     jvmciFlag->set_product();
 194   }
 195 
 196   bool value = true;
 197   JVMFlag *jvmciEnableFlag = JVMFlag::find_flag("EnableJVMCIProduct");
 198   if (JVMFlag::boolAtPut(jvmciEnableFlag, value, origin) != JVMFlag::SUCCESS) {
 199     return false;
 200   }
 201 
 202   // Effect of EnableJVMCIProduct on changing defaults of EnableJVMCI
 203   // and UseJVMCICompiler is deferred to check_jvmci_flags_are_consistent
 204   // so that setting these flags explicitly (e.g. on the command line)
 205   // takes precedence.
 206 
 207   return true;
 208 }
 209 
 210 void JVMCIGlobals::check_jvmci_supported_gc() {
 211   if (EnableJVMCI) {
 212     // Check if selected GC is supported by JVMCI and Java compiler
 213     if (!(UseSerialGC || UseParallelGC || UseG1GC)) {
 214       vm_exit_during_initialization("JVMCI Compiler does not support selected GC", GCConfig::hs_err_name());
 215       FLAG_SET_DEFAULT(EnableJVMCI, false);
 216       FLAG_SET_DEFAULT(UseJVMCICompiler, false);
 217     }
 218   }
 219 }
 220 
 221 // -- Define all JVM flags that have been declared in share/jvmci/jvmci_globals.hpp
 222 
 223 // Add JVMFlag::JVMCI to the JVMFlag::attr() for all flags defined in this file
 224 #ifdef FLAG_COMMON_ATTRS
 225 #undef FLAG_COMMON_ATTRS
 226 #endif
 227 #define FLAG_COMMON_ATTRS JVMFlag::JVMCI
 228 
 229 #include "jvmci_globals.hpp"
 230 #include "runtime/flags/jvmFlag.inline.hpp"
 231 DEFN_PRODUCT_FLAG(EnableJVMCI);
 232 DEFN_PRODUCT_FLAG(EnableJVMCIProduct);
 233 DEFN_PRODUCT_FLAG(UseJVMCICompiler);
 234 DEFN_PRODUCT_FLAG(JVMCIPrintProperties);
 235 DEFN_PRODUCT_FLAG(BootstrapJVMCI);
 236 DEFN_PRODUCT_FLAG(EagerJVMCI);
 237 DEFN_PRODUCT_FLAG(PrintBootstrap);
 238 DEFN_PRODUCT_FLAG(JVMCIThreads); DEFN_PRODUCT_RANGE(JVMCIThreads);
 239 DEFN_PRODUCT_FLAG(JVMCIHostThreads); DEFN_PRODUCT_RANGE(JVMCIHostThreads);
 240 NOT_COMPILER2(DEFN_PRODUCT_FLAG(MaxVectorSize);)
 241 
 242 NOT_COMPILER2(DEFN_PRODUCT_FLAG(ReduceInitialCardMarks);)
 243 
 244 DEFN_PRODUCT_FLAG(JVMCITraceLevel); DEFN_PRODUCT_RANGE(JVMCITraceLevel);
 245 DEFN_PRODUCT_FLAG(JVMCICounterSize); DEFN_PRODUCT_RANGE(JVMCICounterSize);
 246 DEFN_PRODUCT_FLAG(JVMCICountersExcludeCompiler);
 247 DEFN_DEVELOP_FLAG(JVMCIUseFastLocking);
 248 DEFN_PRODUCT_FLAG(JVMCINMethodSizeLimit); DEFN_PRODUCT_RANGE(JVMCINMethodSizeLimit);
 249 DEFN_PRODUCT_FLAG(JVMCILibPath);
 250 DEFN_PRODUCT_FLAG(JVMCILibDumpJNIConfig);
 251 DEFN_PRODUCT_FLAG(UseJVMCINativeLibrary);
 252 NOT_COMPILER2(DEFN_PRODUCT_FLAG(UseMultiplyToLenIntrinsic);)
 253 
 254 NOT_COMPILER2(DEFN_PRODUCT_FLAG(UseSquareToLenIntrinsic);)
 255 
 256 NOT_COMPILER2(DEFN_PRODUCT_FLAG(UseMulAddIntrinsic);)
 257 
 258 NOT_COMPILER2(DEFN_PRODUCT_FLAG(UseMontgomeryMultiplyIntrinsic);)