diff src/share/vm/jvmci/jvmciRuntime.cpp @ 22398:4f6caa445b92

moved JVMCI option parsing back into Java
author Doug Simon <doug.simon@oracle.com>
date Tue, 04 Aug 2015 00:47:34 +0200
parents 0e095e2c24e2
children 31e0737e2fce
line wrap: on
line diff
--- a/src/share/vm/jvmci/jvmciRuntime.cpp	Mon Aug 03 15:19:14 2015 +0200
+++ b/src/share/vm/jvmci/jvmciRuntime.cpp	Tue Aug 04 00:47:34 2015 +0200
@@ -44,6 +44,7 @@
 
 jobject JVMCIRuntime::_HotSpotJVMCIRuntime_instance = NULL;
 bool JVMCIRuntime::_HotSpotJVMCIRuntime_initialized = false;
+const char* JVMCIRuntime::_options = NULL;
 bool JVMCIRuntime::_shutdown_called = false;
 
 void JVMCIRuntime::initialize_natives(JNIEnv *env, jclass c2vmClass) {
@@ -622,7 +623,7 @@
   return value;
 JRT_END
 
-// private static void JVMCIClassLoaderFactory.init()
+// private static void JVMCIClassLoaderFactory.init(ClassLoader loader)
 JVM_ENTRY(void, JVM_InitJVMCIClassLoader(JNIEnv *env, jclass c, jobject loader_handle))
   SystemDictionary::init_jvmci_loader(JNIHandles::resolve(loader_handle));
   SystemDictionary::WKID scan = SystemDictionary::FIRST_JVMCI_WKID;
@@ -643,30 +644,43 @@
   return JNIHandles::make_local(THREAD, JVMCIRuntime::get_service_impls(serviceKlass, THREAD)());
 JVM_END
 
-Handle JVMCIRuntime::callInitializer(const char* className, const char* methodName, const char* returnType) {
+Handle JVMCIRuntime::callInitializer(const char* className, const char* methodName, const char* signature, JavaCallArguments* args) {
   guarantee(!_HotSpotJVMCIRuntime_initialized, "cannot reinitialize HotSpotJVMCIRuntime");
   Thread* THREAD = Thread::current();
 
   TempNewSymbol name = SymbolTable::new_symbol(className, CHECK_ABORT_(Handle()));
   KlassHandle klass = load_required_class(name);
   TempNewSymbol runtime = SymbolTable::new_symbol(methodName, CHECK_ABORT_(Handle()));
-  TempNewSymbol sig = SymbolTable::new_symbol(returnType, CHECK_ABORT_(Handle()));
+  TempNewSymbol sig = SymbolTable::new_symbol(signature, CHECK_ABORT_(Handle()));
   JavaValue result(T_OBJECT);
-  JavaCalls::call_static(&result, klass, runtime, sig, CHECK_ABORT_(Handle()));
+  if (args == NULL) {
+    JavaCalls::call_static(&result, klass, runtime, sig, CHECK_ABORT_(Handle()));
+  } else {
+    JavaCalls::call_static(&result, klass, runtime, sig, args, CHECK_ABORT_(Handle()));
+  }
   return Handle((oop)result.get_jobject());
 }
 
 void JVMCIRuntime::initialize_HotSpotJVMCIRuntime() {
   if (JNIHandles::resolve(_HotSpotJVMCIRuntime_instance) == NULL) {
+    Thread* THREAD = Thread::current();
 #ifdef ASSERT
     // This should only be called in the context of the JVMCI class being initialized
-    Thread* THREAD = Thread::current();
     TempNewSymbol name = SymbolTable::new_symbol("jdk/internal/jvmci/runtime/JVMCI", CHECK_ABORT);
     instanceKlassHandle klass = InstanceKlass::cast(load_required_class(name));
     assert(klass->is_being_initialized() && klass->is_reentrant_initialization(THREAD),
            "HotSpotJVMCIRuntime initialization should only be triggered through JVMCI initialization");
 #endif
 
+    if (_options != NULL) {
+      JavaCallArguments args;
+      oop options = java_lang_String::create_oop_from_str(_options, CHECK_ABORT);
+      args.push_oop(options);
+      callInitializer("jdk/internal/jvmci/options/OptionsParser",
+                      "parseOptionsFromVM",
+                      "(Ljava/lang/String;)Ljava/lang/Boolean;", &args);
+    }
+
     Handle result = callInitializer("jdk/internal/jvmci/hotspot/HotSpotJVMCIRuntime", "runtime",
                                     "()Ljdk/internal/jvmci/hotspot/HotSpotJVMCIRuntime;");
     _HotSpotJVMCIRuntime_initialized = true;
@@ -782,159 +796,6 @@
   }
 }
 
-OptionValuesTable* JVMCIRuntime::parse_arguments() {
-  OptionDescsTable* table = OptionDescsTable::load_options();
-  if (table == NULL) {
-    return NULL;
-  }
-
-  OptionValuesTable* options = new OptionValuesTable(table);
-
-  // Process option overrides from jvmci.options first
-  parse_jvmci_options_file(options);
-
-  // Now process options on the command line
-  int numOptions = Arguments::num_jvmci_args();
-  for (int i = 0; i < numOptions; i++) {
-    char* arg = Arguments::jvmci_args_array()[i];
-    if (!parse_argument(options, arg)) {
-      delete options;
-      return NULL;
-    }
-  }
-  return options;
-}
-
-void not_found(OptionDescsTable* table, const char* argname, size_t namelen) {
-  jio_fprintf(defaultStream::error_stream(),"Unrecognized VM option '%.*s'\n", namelen, argname);
-  OptionDesc* fuzzy_matched = table->fuzzy_match(argname, strlen(argname));
-  if (fuzzy_matched != NULL) {
-    jio_fprintf(defaultStream::error_stream(),
-                "Did you mean '%s%s%s'?\n",
-                (fuzzy_matched->type == _boolean) ? "(+/-)" : "",
-                fuzzy_matched->name,
-                (fuzzy_matched->type == _boolean) ? "" : "=<value>");
-  }
-}
-
-bool JVMCIRuntime::parse_argument(OptionValuesTable* options, const char* arg) {
-  OptionDescsTable* table = options->options_table();
-  char first = arg[0];
-  const char* name;
-  size_t name_len;
-  if (first == '+' || first == '-') {
-    name = arg + 1;
-    OptionDesc* optionDesc = table->get(name);
-    if (optionDesc == NULL) {
-      not_found(table, name, strlen(name));
-      return false;
-    }
-    if (optionDesc->type != _boolean) {
-      jio_fprintf(defaultStream::error_stream(), "Unexpected +/- setting in VM option '%s'\n", name);
-      return false;
-    }
-    OptionValue value;
-    value.desc = *optionDesc;
-    value.boolean_value = first == '+';
-    options->put(value);
-    return true;
-  } else {
-    const char* sep = strchr(arg, '=');
-    name = arg;
-    const char* value = NULL;
-    if (sep != NULL) {
-      name_len = sep - name;
-      value = sep + 1;
-    } else {
-      name_len = strlen(name);
-    }
-    OptionDesc* optionDesc = table->get(name, name_len);
-    if (optionDesc == NULL) {
-      not_found(table, name, name_len);
-      return false;
-    }
-    if (optionDesc->type == _boolean) {
-      jio_fprintf(defaultStream::error_stream(), "Missing +/- setting for VM option '%s'\n", name);
-      return false;
-    }
-    if (value == NULL) {
-      jio_fprintf(defaultStream::error_stream(), "Must use '-G:%.*s=<value>' format for %.*s option", name_len, name, name_len, name);
-      return false;
-    }
-    OptionValue optionValue;
-    optionValue.desc = *optionDesc;
-    char* check;
-    errno = 0;
-    switch(optionDesc->type) {
-      case _int: {
-        long int int_value = ::strtol(value, &check, 10);
-        if (*check != '\0' || errno == ERANGE || int_value > max_jint || int_value < min_jint) {
-          jio_fprintf(defaultStream::error_stream(), "Expected int value for VM option '%s'\n", name);
-          return false;
-        }
-        optionValue.int_value = int_value;
-        break;
-      }
-      case _long: {
-        long long int long_value = ::strtoll(value, &check, 10);
-        if (*check != '\0' || errno == ERANGE || long_value > max_jlong || long_value < min_jlong) {
-          jio_fprintf(defaultStream::error_stream(), "Expected long value for VM option '%s'\n", name);
-          return false;
-        }
-        optionValue.long_value = long_value;
-        break;
-      }
-      case _float: {
-        optionValue.float_value = (float)::strtod(value, &check); //strtof not available in Windows SDK yet
-        if (*check != '\0' || errno == ERANGE) {
-          jio_fprintf(defaultStream::error_stream(), "Expected float value for VM option '%s'\n", name);
-          return false;
-        }
-        break;
-      }
-      case _double: {
-        optionValue.double_value = ::strtod(value, &check);
-        if (*check != '\0' || errno == ERANGE) {
-          jio_fprintf(defaultStream::error_stream(), "Expected double value for VM option '%s'\n", name);
-          return false;
-        }
-        break;
-      }
-      case _string: {
-        char* copy = NEW_C_HEAP_ARRAY(char, strlen(value) + 1, mtCompiler);
-        strcpy(copy, value);
-        optionValue.string_value = copy;
-        break;
-      }
-      default:
-        ShouldNotReachHere();
-    }
-    options->put(optionValue);
-    return true;
-  }
-}
-
-class JVMCIOptionParseClosure : public ParseClosure {
-  OptionValuesTable* _options;
-public:
-  JVMCIOptionParseClosure(OptionValuesTable* options) : _options(options) {}
-  void do_line(char* line) {
-    if (!JVMCIRuntime::parse_argument(_options, line)) {
-      warn("There was an error parsing an argument. Skipping it.");
-    }
-  }
-};
-
-void JVMCIRuntime::parse_jvmci_options_file(OptionValuesTable* options) {
-  const char* home = Arguments::get_java_home();
-  size_t path_len = strlen(home) + strlen("/lib/jvmci.options") + 1;
-  char path[JVM_MAXPATHLEN];
-  char sep = os::file_separator()[0];
-  jio_snprintf(path, JVM_MAXPATHLEN, "%s%clib%cjvmci.options", home, sep, sep);
-  JVMCIOptionParseClosure closure(options);
-  parse_lines(path, &closure, false);
-}
-
 #define CHECK_WARN_ABORT_(message) THREAD); \
   if (HAS_PENDING_EXCEPTION) { \
     warning(message); \
@@ -945,149 +806,10 @@
   } \
   (void)(0
 
-class SetOptionClosure : public ValueClosure<OptionValue> {
-  Thread* _thread;
-public:
-  SetOptionClosure(TRAPS) : _thread(THREAD) {}
-  void do_value(OptionValue* optionValue) {
-    TRAPS = _thread;
-    const char* declaringClass = optionValue->desc.declaringClass;
-    if (declaringClass == NULL) {
-      // skip PrintFlags pseudo-option
-      return;
-    }
-    const char* fieldName = optionValue->desc.name;
-    const char* fieldClass = optionValue->desc.fieldClass;
-
-    size_t fieldSigLen = 2 + strlen(fieldClass);
-    char* fieldSig = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, fieldSigLen + 1);
-    jio_snprintf(fieldSig, fieldSigLen + 1, "L%s;", fieldClass);
-    for (size_t i = 0; i < fieldSigLen; ++i) {
-      if (fieldSig[i] == '.') {
-        fieldSig[i] = '/';
-      }
-    }
-    fieldSig[fieldSigLen] = '\0';
-    size_t declaringClassLen = strlen(declaringClass);
-    char* declaringClassBinary = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, declaringClassLen + 1);
-    for (size_t i = 0; i < declaringClassLen; ++i) {
-      if (declaringClass[i] == '.') {
-        declaringClassBinary[i] = '/';
-      } else {
-        declaringClassBinary[i] = declaringClass[i];
-      }
-    }
-    declaringClassBinary[declaringClassLen] = '\0';
-
-    TempNewSymbol name = SymbolTable::new_symbol(declaringClassBinary, CHECK_WARN_ABORT_("Declaring class could not be found"));
-    Klass* klass = JVMCIRuntime::resolve_or_null(name, CHECK_WARN_ABORT_("Declaring class could not be resolved"));
-
-    if (klass == NULL) {
-      warning("Declaring class for option %s could not be resolved", declaringClass);
-      abort();
-      return;
-    }
-
-    // The class has been loaded so the field and signature should already be in the symbol
-    // table.  If they're not there, the field doesn't exist.
-    TempNewSymbol fieldname = SymbolTable::probe(fieldName, (int)strlen(fieldName));
-    TempNewSymbol signame = SymbolTable::probe(fieldSig, (int)fieldSigLen);
-    if (fieldname == NULL || signame == NULL) {
-      warning("Symbols for field for option %s not found (in %s)", fieldName, declaringClass);
-      abort();
-      return;
-    }
-    // Make sure class is initialized before handing id's out to fields
-    klass->initialize(CHECK_WARN_ABORT_("Error while initializing declaring class for option"));
-
-    fieldDescriptor fd;
-    if (!InstanceKlass::cast(klass)->find_field(fieldname, signame, true, &fd)) {
-      warning("Field for option %s not found (in %s)", fieldName, declaringClass);
-      abort();
-      return;
-    }
-    oop value;
-    switch(optionValue->desc.type) {
-    case _boolean: {
-      jvalue jv;
-      jv.z = optionValue->boolean_value;
-      value = java_lang_boxing_object::create(T_BOOLEAN, &jv, THREAD);
-      break;
-    }
-    case _int: {
-      jvalue jv;
-      jv.i = optionValue->int_value;
-      value = java_lang_boxing_object::create(T_INT, &jv, THREAD);
-      break;
-    }
-    case _long: {
-      jvalue jv;
-      jv.j = optionValue->long_value;
-      value = java_lang_boxing_object::create(T_LONG, &jv, THREAD);
-      break;
-    }
-    case _float: {
-      jvalue jv;
-      jv.f = optionValue->float_value;
-      value = java_lang_boxing_object::create(T_FLOAT, &jv, THREAD);
-      break;
-    }
-    case _double: {
-      jvalue jv;
-      jv.d = optionValue->double_value;
-      value = java_lang_boxing_object::create(T_DOUBLE, &jv, THREAD);
-      break;
-    }
-    case _string:
-      value = java_lang_String::create_from_str(optionValue->string_value, THREAD)();
-      break;
-    default:
-      ShouldNotReachHere();
-    }
-
-    oop optionValueOop = klass->java_mirror()->obj_field(fd.offset());
-
-    if (optionValueOop == NULL) {
-      warning("Option field was null, can not set %s", fieldName);
-      abort();
-      return;
-    }
-
-    if (!InstanceKlass::cast(optionValueOop->klass())->find_field(vmSymbols::value_name(), vmSymbols::object_signature(), false, &fd)) {
-      warning("'Object value' field not found in option class %s, can not set option %s", fieldClass, fieldName);
-      abort();
-      return;
-    }
-
-    optionValueOop->obj_field_put(fd.offset(), value);
-  }
-};
-
-void JVMCIRuntime::set_options(OptionValuesTable* options, TRAPS) {
-  ensure_jvmci_class_loader_is_initialized();
-  {
-    ResourceMark rm;
-    SetOptionClosure closure(THREAD);
-    options->for_each(&closure);
-    if (closure.is_aborted()) {
-      vm_abort(false);
-    }
-  }
-  OptionValue* printFlags = options->get(PRINT_FLAGS_ARG);
-  if (printFlags != NULL && printFlags->boolean_value) {
-    print_flags_helper(CHECK_ABORT);
-  }
-}
-
-void JVMCIRuntime::print_flags_helper(TRAPS) {
-  // TODO(gd) write this in C++?
-  HandleMark hm(THREAD);
-  TempNewSymbol name = SymbolTable::new_symbol("jdk/internal/jvmci/hotspot/HotSpotOptions", CHECK_ABORT);
-  KlassHandle hotSpotOptionsClass = load_required_class(name);
-  TempNewSymbol setOption = SymbolTable::new_symbol("printFlags", CHECK);
-  JavaValue result(T_VOID);
-  JavaCallArguments args;
-  JavaCalls::call_static(&result, hotSpotOptionsClass, setOption, vmSymbols::void_method_signature(), &args, CHECK);
+void JVMCIRuntime::save_options(const char* options) {
+  assert(options != NULL, "npe");
+  assert(_options == NULL, "cannot reassign JVMCI options");
+  _options = options;
 }
 
 Handle JVMCIRuntime::create_Service(const char* name, TRAPS) {