Mercurial > hg > graal-compiler
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); +}