diff src/share/vm/graal/graalOptions.cpp @ 21519:cecb4e39521c

Use files in lib/graal/options to define Graal options (-G:...) instead of generating code for them
author Gilles Duboscq <gilles.m.duboscq@oracle.com>
date Wed, 27 May 2015 17:40:26 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/graal/graalOptions.cpp	Wed May 27 17:40:26 2015 +0200
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "precompiled.hpp"
+#include "graal/graalOptions.hpp"
+#include "graal/graalRuntime.hpp"
+#include "runtime/arguments.hpp"
+#include "utilities/hashtable.inline.hpp"
+
+class OptionsParseClosure : public ParseClosure {
+  OptionsTable* _table;
+public:
+  OptionsParseClosure(OptionsTable* table) : _table(table) {}
+  void do_line(char* line) {
+    char* idx = strchr(line, '\t');
+    if (idx == NULL) {
+      warn_and_abort("invalid format: could not find first tab");
+      return;
+    }
+    *idx = '\0';
+    char* name = line;
+    line = idx + 1;
+    idx = strchr(line, '\t');
+    if (idx == NULL) {
+      warn_and_abort("invalid format: could not find second tab");
+      return;
+    }
+    *idx = '\0';
+    if (strlen(line) != 1) {
+      warn_and_abort("invalid format: type should be 1 char long");
+      return;
+    }
+    char typeChar = *line;
+    line = idx + 1;
+    idx = strchr(line, '\t');
+    if (idx == NULL) {
+      warn_and_abort("invalid format: could not find third tab");
+      return;
+    }
+    *idx = '\0';
+    char* help = line;
+    line = idx + 1;
+    idx = strchr(line, '\t');
+    if (idx == NULL) {
+      warn_and_abort("invalid format: could not find fourth tab");
+      return;
+    }
+    *idx = '\0';
+    char* declaringClass = line;
+    line = idx + 1;
+    char* fieldClass = line;
+    OptionType type;
+    switch(typeChar) {
+      case 's':
+        type = _string;
+        break;
+      case 'i':
+        type = _int;
+        break;
+      case 'j':
+        type = _long;
+        break;
+      case 'f':
+        type = _float;
+        break;
+      case 'd':
+        type = _double;
+        break;
+      case 'z':
+        type = _boolean;
+        break;
+      default:
+        warn_and_abort("unkown type");
+        return;
+    }
+    char* name2 = NEW_C_HEAP_ARRAY(char, (strlen(name) + 1 + strlen(help) + 1 + strlen(declaringClass) + 1 + strlen(fieldClass) + 1), mtCompiler);
+    char* help2 = name2 + strlen(name) + 1;
+    char* declaringClass2 = help2 + strlen(help) + 1;
+    char* fieldClass2 = declaringClass2 + strlen(declaringClass) + 1;
+    strcpy(name2, name);
+    strcpy(help2, help);
+    strcpy(declaringClass2, declaringClass);
+    strcpy(fieldClass2, fieldClass);
+    OptionDesc desc = {name2, help2, type, declaringClass2, fieldClass2};
+    if (!_table->add(desc)) {
+      warn_and_abort("duplicate option");
+      return;
+    }
+  }
+};
+
+class FreeNamesClosure : public ValueClosure<OptionDesc> {
+  void do_value(OptionDesc* desc) {
+    FREE_C_HEAP_ARRAY(char, desc->name, mtCompiler);
+  }
+};
+
+OptionsTable::~OptionsTable() {
+  FreeNamesClosure closure;
+  for_each(&closure);
+}
+
+OptionsTable* OptionsTable::load_options() {
+  OptionsTable* table = new OptionsTable();
+  // Add PrintFlags option manually
+  OptionDesc printFlagsDesc;
+  printFlagsDesc.name = PRINT_FLAGS_ARG;
+  printFlagsDesc.type = _boolean;
+  printFlagsDesc.help = PRINT_FLAGS_HELP;
+  printFlagsDesc.declaringClass = NULL;
+  printFlagsDesc.fieldClass = NULL;
+  table->add(printFlagsDesc);
+
+  char optionsDir[JVM_MAXPATHLEN];
+  const char* fileSep = os::file_separator();
+  jio_snprintf(optionsDir, sizeof(optionsDir), "%s%slib%sgraal%soptions",
+               Arguments::get_java_home(), fileSep, fileSep, fileSep);
+  DIR* dir = os::opendir(optionsDir);
+  if (dir != NULL) {
+    struct dirent *entry;
+    char *dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(optionsDir), mtInternal);
+    OptionsParseClosure closure(table);
+    while ((entry = os::readdir(dir, (dirent *) dbuf)) != NULL && !closure.is_aborted()) {
+      const char* name = entry->d_name;
+      char optionFilePath[JVM_MAXPATHLEN];
+      jio_snprintf(optionFilePath, sizeof(optionFilePath), "%s%s%s",optionsDir, fileSep, name);
+      GraalRuntime::parse_lines(optionFilePath, &closure, false);
+    }
+    FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
+    os::closedir(dir);
+    if (closure.is_aborted()) {
+      delete table;
+      return NULL;
+    }
+    return table;
+  }
+  // TODO(gd) should this be silent?
+  warning("Could not open graal options directory (%s)",optionsDir);
+  return table;
+}
+
+OptionDesc* OptionsTable::get(const char* name, size_t arglen) {
+  char nameOnly[256];
+  guarantee(arglen < 256, "Max supported option name len is 256");
+  strncpy(nameOnly, name, arglen);
+  nameOnly[arglen] = '\0';
+  return GraalHashtable<const char*, OptionDesc>::get(nameOnly);
+}
+
+// Compute string similarity based on Dice's coefficient
+static float str_similar(const char* str1, const char* str2) {
+  size_t len1 = strlen(str1);
+  size_t len2 = strlen(str2);
+
+  if (len1 == 0 || len2 == 0) {
+    return 0;
+  }
+
+  int hits = 0;
+  for (size_t i = 0; i < len1 - 1; ++i) {
+    for (size_t j = 0; j < len2 -1; ++j) {
+      if ((str1[i] == str2[j]) && (str1[i+1] == str2[j+1])) {
+        ++hits;
+        break;
+      }
+    }
+  }
+
+  size_t total = len1 + len2;
+  return 2.0f * (float) hits / (float) total;
+}
+
+float VMOptionsFuzzyMatchSimilarity = 0.7f;
+
+class FuzzyMatchClosure : public ValueClosure<OptionDesc> {
+  OptionDesc* _match;
+  float _max_score;
+  const char* _name;
+public:
+  FuzzyMatchClosure(const char* name) : _name(name), _match(NULL), _max_score(-1) {}
+  void do_value(OptionDesc* value) {
+    float score = str_similar(value->name, _name);
+    if (score > VMOptionsFuzzyMatchSimilarity && score > _max_score) {
+      _max_score = score;
+      _match = value;
+    }
+  }
+  OptionDesc* get_match() {
+    return _match;
+  }
+};
+
+OptionDesc * OptionsTable::fuzzy_match(const char* name, size_t length) {
+  FuzzyMatchClosure closure(name);
+  for_each(&closure);
+  return closure.get_match();
+}
+
+class FreeStringsClosure : public ValueClosure<OptionValue> {
+  void do_value(OptionValue* value) {
+    if (value->desc.type == _string) {
+      FREE_C_HEAP_ARRAY(char, value->string_value, mtCompiler);
+    }
+  }
+};
+
+OptionsValueTable::~OptionsValueTable() {
+  FreeStringsClosure closure;
+  for_each(&closure);
+  delete _table;
+}
+
+
+
+OptionValue* OptionsValueTable::get(const char* name, size_t arglen) {
+  char nameOnly[256];
+  guarantee(arglen < 256, "Max supported option name len is 256");
+  strncpy(nameOnly, name, arglen);
+  nameOnly[arglen] = '\0';
+  return GraalHashtable<const char*, OptionValue>::get(nameOnly);
+}