comparison src/share/vm/jvmci/jvmciOptions.cpp @ 21562:47bebae7454f

Merge.
author Doug Simon <doug.simon@oracle.com>
date Thu, 28 May 2015 21:58:33 +0200
parents src/share/vm/graal/graalOptions.cpp@cecb4e39521c
children b72a5d25ad43
comparison
equal deleted inserted replaced
21561:ce2113326bc8 21562:47bebae7454f
1 /*
2 * Copyright (c) 2015, 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 #include "precompiled.hpp"
25 #include "jvmci/jvmciOptions.hpp"
26 #include "jvmci/jvmciRuntime.hpp"
27 #include "runtime/arguments.hpp"
28 #include "utilities/hashtable.inline.hpp"
29
30 class OptionsParseClosure : public ParseClosure {
31 OptionsTable* _table;
32 public:
33 OptionsParseClosure(OptionsTable* table) : _table(table) {}
34 void do_line(char* line) {
35 char* idx = strchr(line, '\t');
36 if (idx == NULL) {
37 warn_and_abort("invalid format: could not find first tab");
38 return;
39 }
40 *idx = '\0';
41 char* name = line;
42 line = idx + 1;
43 idx = strchr(line, '\t');
44 if (idx == NULL) {
45 warn_and_abort("invalid format: could not find second tab");
46 return;
47 }
48 *idx = '\0';
49 if (strlen(line) != 1) {
50 warn_and_abort("invalid format: type should be 1 char long");
51 return;
52 }
53 char typeChar = *line;
54 line = idx + 1;
55 idx = strchr(line, '\t');
56 if (idx == NULL) {
57 warn_and_abort("invalid format: could not find third tab");
58 return;
59 }
60 *idx = '\0';
61 char* help = line;
62 line = idx + 1;
63 idx = strchr(line, '\t');
64 if (idx == NULL) {
65 warn_and_abort("invalid format: could not find fourth tab");
66 return;
67 }
68 *idx = '\0';
69 char* declaringClass = line;
70 line = idx + 1;
71 char* fieldClass = line;
72 OptionType type;
73 switch(typeChar) {
74 case 's':
75 type = _string;
76 break;
77 case 'i':
78 type = _int;
79 break;
80 case 'j':
81 type = _long;
82 break;
83 case 'f':
84 type = _float;
85 break;
86 case 'd':
87 type = _double;
88 break;
89 case 'z':
90 type = _boolean;
91 break;
92 default:
93 warn_and_abort("unkown type");
94 return;
95 }
96 char* name2 = NEW_C_HEAP_ARRAY(char, (strlen(name) + 1 + strlen(help) + 1 + strlen(declaringClass) + 1 + strlen(fieldClass) + 1), mtCompiler);
97 char* help2 = name2 + strlen(name) + 1;
98 char* declaringClass2 = help2 + strlen(help) + 1;
99 char* fieldClass2 = declaringClass2 + strlen(declaringClass) + 1;
100 strcpy(name2, name);
101 strcpy(help2, help);
102 strcpy(declaringClass2, declaringClass);
103 strcpy(fieldClass2, fieldClass);
104 OptionDesc desc = {name2, help2, type, declaringClass2, fieldClass2};
105 if (!_table->add(desc)) {
106 warn_and_abort("duplicate option");
107 return;
108 }
109 }
110 };
111
112 class FreeNamesClosure : public ValueClosure<OptionDesc> {
113 void do_value(OptionDesc* desc) {
114 FREE_C_HEAP_ARRAY(char, desc->name, mtCompiler);
115 }
116 };
117
118 OptionsTable::~OptionsTable() {
119 FreeNamesClosure closure;
120 for_each(&closure);
121 }
122
123 OptionsTable* OptionsTable::load_options() {
124 OptionsTable* table = new OptionsTable();
125 // Add PrintFlags option manually
126 OptionDesc printFlagsDesc;
127 printFlagsDesc.name = PRINT_FLAGS_ARG;
128 printFlagsDesc.type = _boolean;
129 printFlagsDesc.help = PRINT_FLAGS_HELP;
130 printFlagsDesc.declaringClass = NULL;
131 printFlagsDesc.fieldClass = NULL;
132 table->add(printFlagsDesc);
133
134 char optionsDir[JVM_MAXPATHLEN];
135 const char* fileSep = os::file_separator();
136 jio_snprintf(optionsDir, sizeof(optionsDir), "%s%slib%sjvmci%soptions",
137 Arguments::get_java_home(), fileSep, fileSep, fileSep);
138 DIR* dir = os::opendir(optionsDir);
139 if (dir != NULL) {
140 struct dirent *entry;
141 char *dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(optionsDir), mtInternal);
142 OptionsParseClosure closure(table);
143 while ((entry = os::readdir(dir, (dirent *) dbuf)) != NULL && !closure.is_aborted()) {
144 const char* name = entry->d_name;
145 char optionFilePath[JVM_MAXPATHLEN];
146 jio_snprintf(optionFilePath, sizeof(optionFilePath), "%s%s%s",optionsDir, fileSep, name);
147 JVMCIRuntime::parse_lines(optionFilePath, &closure, false);
148 }
149 FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
150 os::closedir(dir);
151 if (closure.is_aborted()) {
152 delete table;
153 return NULL;
154 }
155 return table;
156 }
157 // TODO(gd) should this be silent?
158 warning("Could not open jvmci options directory (%s)",optionsDir);
159 return table;
160 }
161
162 OptionDesc* OptionsTable::get(const char* name, size_t arglen) {
163 char nameOnly[256];
164 guarantee(arglen < 256, "Max supported option name len is 256");
165 strncpy(nameOnly, name, arglen);
166 nameOnly[arglen] = '\0';
167 return JVMCIHashtable<const char*, OptionDesc>::get(nameOnly);
168 }
169
170 // Compute string similarity based on Dice's coefficient
171 static float str_similar(const char* str1, const char* str2) {
172 size_t len1 = strlen(str1);
173 size_t len2 = strlen(str2);
174
175 if (len1 == 0 || len2 == 0) {
176 return 0;
177 }
178
179 int hits = 0;
180 for (size_t i = 0; i < len1 - 1; ++i) {
181 for (size_t j = 0; j < len2 -1; ++j) {
182 if ((str1[i] == str2[j]) && (str1[i+1] == str2[j+1])) {
183 ++hits;
184 break;
185 }
186 }
187 }
188
189 size_t total = len1 + len2;
190 return 2.0f * (float) hits / (float) total;
191 }
192
193 float VMOptionsFuzzyMatchSimilarity = 0.7f;
194
195 class FuzzyMatchClosure : public ValueClosure<OptionDesc> {
196 OptionDesc* _match;
197 float _max_score;
198 const char* _name;
199 public:
200 FuzzyMatchClosure(const char* name) : _name(name), _match(NULL), _max_score(-1) {}
201 void do_value(OptionDesc* value) {
202 float score = str_similar(value->name, _name);
203 if (score > VMOptionsFuzzyMatchSimilarity && score > _max_score) {
204 _max_score = score;
205 _match = value;
206 }
207 }
208 OptionDesc* get_match() {
209 return _match;
210 }
211 };
212
213 OptionDesc * OptionsTable::fuzzy_match(const char* name, size_t length) {
214 FuzzyMatchClosure closure(name);
215 for_each(&closure);
216 return closure.get_match();
217 }
218
219 class FreeStringsClosure : public ValueClosure<OptionValue> {
220 void do_value(OptionValue* value) {
221 if (value->desc.type == _string) {
222 FREE_C_HEAP_ARRAY(char, value->string_value, mtCompiler);
223 }
224 }
225 };
226
227 OptionsValueTable::~OptionsValueTable() {
228 FreeStringsClosure closure;
229 for_each(&closure);
230 delete _table;
231 }
232
233
234
235 OptionValue* OptionsValueTable::get(const char* name, size_t arglen) {
236 char nameOnly[256];
237 guarantee(arglen < 256, "Max supported option name len is 256");
238 strncpy(nameOnly, name, arglen);
239 nameOnly[arglen] = '\0';
240 return JVMCIHashtable<const char*, OptionValue>::get(nameOnly);
241 }