Mercurial > hg > truffle
annotate src/share/vm/compiler/compilerOracle.cpp @ 6862:8a5ea0a9ccc4
7127708: G1: change task num types from int to uint in concurrent mark
Summary: Change the type of various task num fields, parameters etc to unsigned and rename them to be more consistent with the other collectors. Code changes were also reviewed by Vitaly Davidovich.
Reviewed-by: johnc
Contributed-by: Kaushik Srenevasan <kaushik@twitter.com>
author | johnc |
---|---|
date | Sat, 06 Oct 2012 01:17:44 -0700 |
parents | da91efe96a93 |
children | 218a94758fe7 |
rev | line source |
---|---|
0 | 1 /* |
6150
1e76463170b3
7110720: Issue with vm config file loadingIssue with vm config file loading
kamg
parents:
2426
diff
changeset
|
2 * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1155
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1155
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1155
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "compiler/compilerOracle.hpp" | |
27 #include "memory/allocation.inline.hpp" | |
28 #include "memory/oopFactory.hpp" | |
29 #include "memory/resourceArea.hpp" | |
30 #include "oops/klass.hpp" | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6204
diff
changeset
|
31 #include "oops/method.hpp" |
1972 | 32 #include "oops/oop.inline.hpp" |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
33 #include "oops/symbol.hpp" |
1972 | 34 #include "runtime/handles.inline.hpp" |
35 #include "runtime/jniHandles.hpp" | |
0 | 36 |
6197 | 37 class MethodMatcher : public CHeapObj<mtCompiler> { |
0 | 38 public: |
39 enum Mode { | |
40 Exact, | |
41 Prefix = 1, | |
42 Suffix = 2, | |
43 Substring = Prefix | Suffix, | |
44 Any, | |
45 Unknown = -1 | |
46 }; | |
47 | |
48 protected: | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
49 Symbol* _class_name; |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
50 Symbol* _method_name; |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
51 Symbol* _signature; |
0 | 52 Mode _class_mode; |
53 Mode _method_mode; | |
54 MethodMatcher* _next; | |
55 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
56 static bool match(Symbol* candidate, Symbol* match, Mode match_mode); |
0 | 57 |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
58 Symbol* class_name() const { return _class_name; } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
59 Symbol* method_name() const { return _method_name; } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
60 Symbol* signature() const { return _signature; } |
0 | 61 |
62 public: | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
63 MethodMatcher(Symbol* class_name, Mode class_mode, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
64 Symbol* method_name, Mode method_mode, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
65 Symbol* signature, MethodMatcher* next); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
66 MethodMatcher(Symbol* class_name, Symbol* method_name, MethodMatcher* next); |
0 | 67 |
68 // utility method | |
69 MethodMatcher* find(methodHandle method) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
70 Symbol* class_name = Klass::cast(method->method_holder())->name(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
71 Symbol* method_name = method->name(); |
0 | 72 for (MethodMatcher* current = this; current != NULL; current = current->_next) { |
73 if (match(class_name, current->class_name(), current->_class_mode) && | |
74 match(method_name, current->method_name(), current->_method_mode) && | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
75 (current->signature() == NULL || current->signature() == method->signature())) { |
0 | 76 return current; |
77 } | |
78 } | |
79 return NULL; | |
80 } | |
81 | |
82 bool match(methodHandle method) { | |
83 return find(method) != NULL; | |
84 } | |
85 | |
86 MethodMatcher* next() const { return _next; } | |
87 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
88 static void print_symbol(Symbol* h, Mode mode) { |
0 | 89 ResourceMark rm; |
90 | |
91 if (mode == Suffix || mode == Substring || mode == Any) { | |
92 tty->print("*"); | |
93 } | |
94 if (mode != Any) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
95 h->print_symbol_on(tty); |
0 | 96 } |
97 if (mode == Prefix || mode == Substring) { | |
98 tty->print("*"); | |
99 } | |
100 } | |
101 | |
102 void print_base() { | |
103 print_symbol(class_name(), _class_mode); | |
104 tty->print("."); | |
105 print_symbol(method_name(), _method_mode); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
106 if (signature() != NULL) { |
0 | 107 tty->print(" "); |
108 signature()->print_symbol_on(tty); | |
109 } | |
110 } | |
111 | |
112 virtual void print() { | |
113 print_base(); | |
114 tty->cr(); | |
115 } | |
116 }; | |
117 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
118 MethodMatcher::MethodMatcher(Symbol* class_name, Symbol* method_name, MethodMatcher* next) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
119 _class_name = class_name; |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
120 _method_name = method_name; |
0 | 121 _next = next; |
122 _class_mode = MethodMatcher::Exact; | |
123 _method_mode = MethodMatcher::Exact; | |
124 _signature = NULL; | |
125 } | |
126 | |
127 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
128 MethodMatcher::MethodMatcher(Symbol* class_name, Mode class_mode, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
129 Symbol* method_name, Mode method_mode, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
130 Symbol* signature, MethodMatcher* next): |
0 | 131 _class_mode(class_mode) |
132 , _method_mode(method_mode) | |
133 , _next(next) | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
134 , _class_name(class_name) |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
135 , _method_name(method_name) |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
136 , _signature(signature) { |
0 | 137 } |
138 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
139 bool MethodMatcher::match(Symbol* candidate, Symbol* match, Mode match_mode) { |
0 | 140 if (match_mode == Any) { |
141 return true; | |
142 } | |
143 | |
144 if (match_mode == Exact) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
145 return candidate == match; |
0 | 146 } |
147 | |
148 ResourceMark rm; | |
149 const char * candidate_string = candidate->as_C_string(); | |
150 const char * match_string = match->as_C_string(); | |
151 | |
152 switch (match_mode) { | |
153 case Prefix: | |
154 return strstr(candidate_string, match_string) == candidate_string; | |
155 | |
156 case Suffix: { | |
157 size_t clen = strlen(candidate_string); | |
158 size_t mlen = strlen(match_string); | |
159 return clen >= mlen && strcmp(candidate_string + clen - mlen, match_string) == 0; | |
160 } | |
161 | |
162 case Substring: | |
163 return strstr(candidate_string, match_string) != NULL; | |
164 | |
165 default: | |
166 return false; | |
167 } | |
168 } | |
169 | |
170 | |
171 class MethodOptionMatcher: public MethodMatcher { | |
172 const char * option; | |
173 public: | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
174 MethodOptionMatcher(Symbol* class_name, Mode class_mode, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
175 Symbol* method_name, Mode method_mode, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
176 Symbol* signature, const char * opt, MethodMatcher* next): |
0 | 177 MethodMatcher(class_name, class_mode, method_name, method_mode, signature, next) { |
178 option = opt; | |
179 } | |
180 | |
181 bool match(methodHandle method, const char* opt) { | |
182 MethodOptionMatcher* current = this; | |
183 while (current != NULL) { | |
184 current = (MethodOptionMatcher*)current->find(method); | |
185 if (current == NULL) { | |
186 return false; | |
187 } | |
188 if (strcmp(current->option, opt) == 0) { | |
189 return true; | |
190 } | |
191 current = current->next(); | |
192 } | |
193 return false; | |
194 } | |
195 | |
196 MethodOptionMatcher* next() { | |
197 return (MethodOptionMatcher*)_next; | |
198 } | |
199 | |
200 virtual void print() { | |
201 print_base(); | |
202 tty->print(" %s", option); | |
203 tty->cr(); | |
204 } | |
205 }; | |
206 | |
207 | |
208 | |
209 // this must parallel the command_names below | |
210 enum OracleCommand { | |
211 UnknownCommand = -1, | |
212 OracleFirstCommand = 0, | |
213 BreakCommand = OracleFirstCommand, | |
214 PrintCommand, | |
215 ExcludeCommand, | |
216 InlineCommand, | |
217 DontInlineCommand, | |
218 CompileOnlyCommand, | |
219 LogCommand, | |
220 OptionCommand, | |
221 QuietCommand, | |
222 HelpCommand, | |
223 OracleCommandCount | |
224 }; | |
225 | |
226 // this must parallel the enum OracleCommand | |
227 static const char * command_names[] = { | |
228 "break", | |
229 "print", | |
230 "exclude", | |
231 "inline", | |
232 "dontinline", | |
233 "compileonly", | |
234 "log", | |
235 "option", | |
236 "quiet", | |
237 "help" | |
238 }; | |
239 | |
240 static const char * command_name(OracleCommand command) { | |
241 if (command < OracleFirstCommand || command >= OracleCommandCount) { | |
242 return "unknown command"; | |
243 } | |
244 return command_names[command]; | |
245 } | |
246 | |
247 class MethodMatcher; | |
248 static MethodMatcher* lists[OracleCommandCount] = { 0, }; | |
249 | |
250 | |
251 static bool check_predicate(OracleCommand command, methodHandle method) { | |
252 return ((lists[command] != NULL) && | |
253 !method.is_null() && | |
254 lists[command]->match(method)); | |
255 } | |
256 | |
257 | |
258 static MethodMatcher* add_predicate(OracleCommand command, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
259 Symbol* class_name, MethodMatcher::Mode c_mode, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
260 Symbol* method_name, MethodMatcher::Mode m_mode, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
261 Symbol* signature) { |
0 | 262 assert(command != OptionCommand, "must use add_option_string"); |
263 if (command == LogCommand && !LogCompilation && lists[LogCommand] == NULL) | |
264 tty->print_cr("Warning: +LogCompilation must be enabled in order for individual methods to be logged."); | |
265 lists[command] = new MethodMatcher(class_name, c_mode, method_name, m_mode, signature, lists[command]); | |
266 return lists[command]; | |
267 } | |
268 | |
269 | |
270 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
271 static MethodMatcher* add_option_string(Symbol* class_name, MethodMatcher::Mode c_mode, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
272 Symbol* method_name, MethodMatcher::Mode m_mode, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
273 Symbol* signature, |
0 | 274 const char* option) { |
275 lists[OptionCommand] = new MethodOptionMatcher(class_name, c_mode, method_name, m_mode, | |
276 signature, option, lists[OptionCommand]); | |
277 return lists[OptionCommand]; | |
278 } | |
279 | |
280 | |
281 bool CompilerOracle::has_option_string(methodHandle method, const char* option) { | |
282 return lists[OptionCommand] != NULL && | |
283 ((MethodOptionMatcher*)lists[OptionCommand])->match(method, option); | |
284 } | |
285 | |
286 | |
287 bool CompilerOracle::should_exclude(methodHandle method, bool& quietly) { | |
288 quietly = true; | |
289 if (lists[ExcludeCommand] != NULL) { | |
290 if (lists[ExcludeCommand]->match(method)) { | |
291 quietly = _quiet; | |
292 return true; | |
293 } | |
294 } | |
295 | |
296 if (lists[CompileOnlyCommand] != NULL) { | |
297 return !lists[CompileOnlyCommand]->match(method); | |
298 } | |
299 return false; | |
300 } | |
301 | |
302 | |
303 bool CompilerOracle::should_inline(methodHandle method) { | |
304 return (check_predicate(InlineCommand, method)); | |
305 } | |
306 | |
307 | |
308 bool CompilerOracle::should_not_inline(methodHandle method) { | |
309 return (check_predicate(DontInlineCommand, method)); | |
310 } | |
311 | |
312 | |
313 bool CompilerOracle::should_print(methodHandle method) { | |
314 return (check_predicate(PrintCommand, method)); | |
315 } | |
316 | |
317 | |
318 bool CompilerOracle::should_log(methodHandle method) { | |
319 if (!LogCompilation) return false; | |
320 if (lists[LogCommand] == NULL) return true; // by default, log all | |
321 return (check_predicate(LogCommand, method)); | |
322 } | |
323 | |
324 | |
325 bool CompilerOracle::should_break_at(methodHandle method) { | |
326 return check_predicate(BreakCommand, method); | |
327 } | |
328 | |
329 | |
330 static OracleCommand parse_command_name(const char * line, int* bytes_read) { | |
331 assert(ARRAY_SIZE(command_names) == OracleCommandCount, | |
332 "command_names size mismatch"); | |
333 | |
334 *bytes_read = 0; | |
2077
781072b12368
6765546: Wrong sscanf used to parse CompilerOracle command >= 32 characters could lead to crash
never
parents:
1972
diff
changeset
|
335 char command[33]; |
0 | 336 int result = sscanf(line, "%32[a-z]%n", command, bytes_read); |
337 for (uint i = 0; i < ARRAY_SIZE(command_names); i++) { | |
338 if (strcmp(command, command_names[i]) == 0) { | |
339 return (OracleCommand)i; | |
340 } | |
341 } | |
342 return UnknownCommand; | |
343 } | |
344 | |
345 | |
346 static void usage() { | |
347 tty->print_cr(" CompileCommand and the CompilerOracle allows simple control over"); | |
348 tty->print_cr(" what's allowed to be compiled. The standard supported directives"); | |
349 tty->print_cr(" are exclude and compileonly. The exclude directive stops a method"); | |
350 tty->print_cr(" from being compiled and compileonly excludes all methods except for"); | |
351 tty->print_cr(" the ones mentioned by compileonly directives. The basic form of"); | |
352 tty->print_cr(" all commands is a command name followed by the name of the method"); | |
353 tty->print_cr(" in one of two forms: the standard class file format as in"); | |
354 tty->print_cr(" class/name.methodName or the PrintCompilation format"); | |
355 tty->print_cr(" class.name::methodName. The method name can optionally be followed"); | |
356 tty->print_cr(" by a space then the signature of the method in the class file"); | |
357 tty->print_cr(" format. Otherwise the directive applies to all methods with the"); | |
358 tty->print_cr(" same name and class regardless of signature. Leading and trailing"); | |
359 tty->print_cr(" *'s in the class and/or method name allows a small amount of"); | |
360 tty->print_cr(" wildcarding. "); | |
361 tty->cr(); | |
362 tty->print_cr(" Examples:"); | |
363 tty->cr(); | |
364 tty->print_cr(" exclude java/lang/StringBuffer.append"); | |
365 tty->print_cr(" compileonly java/lang/StringBuffer.toString ()Ljava/lang/String;"); | |
366 tty->print_cr(" exclude java/lang/String*.*"); | |
367 tty->print_cr(" exclude *.toString"); | |
368 } | |
369 | |
370 | |
371 // The characters allowed in a class or method name. All characters > 0x7f | |
372 // are allowed in order to handle obfuscated class files (e.g. Volano) | |
373 #define RANGEBASE "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789$_<>" \ | |
374 "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" \ | |
375 "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" \ | |
376 "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf" \ | |
377 "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" \ | |
378 "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" \ | |
379 "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf" \ | |
380 "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef" \ | |
381 "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff" | |
382 | |
383 #define RANGE0 "[*" RANGEBASE "]" | |
384 #define RANGEDOT "[*" RANGEBASE ".]" | |
385 #define RANGESLASH "[*" RANGEBASE "/]" | |
386 | |
387 | |
388 // Accept several syntaxes for these patterns | |
389 // original syntax | |
390 // cmd java.lang.String foo | |
391 // PrintCompilation syntax | |
392 // cmd java.lang.String::foo | |
393 // VM syntax | |
394 // cmd java/lang/String[. ]foo | |
395 // | |
396 | |
397 static const char* patterns[] = { | |
398 "%*[ \t]%255" RANGEDOT " " "%255" RANGE0 "%n", | |
399 "%*[ \t]%255" RANGEDOT "::" "%255" RANGE0 "%n", | |
400 "%*[ \t]%255" RANGESLASH "%*[ .]" "%255" RANGE0 "%n", | |
401 }; | |
402 | |
403 static MethodMatcher::Mode check_mode(char name[], const char*& error_msg) { | |
404 int match = MethodMatcher::Exact; | |
1155
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
405 while (name[0] == '*') { |
0 | 406 match |= MethodMatcher::Suffix; |
407 strcpy(name, name + 1); | |
408 } | |
409 | |
1155
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
410 if (strcmp(name, "*") == 0) return MethodMatcher::Any; |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
411 |
0 | 412 size_t len = strlen(name); |
1155
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
413 while (len > 0 && name[len - 1] == '*') { |
0 | 414 match |= MethodMatcher::Prefix; |
1155
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
415 name[--len] = '\0'; |
0 | 416 } |
417 | |
418 if (strstr(name, "*") != NULL) { | |
419 error_msg = " Embedded * not allowed"; | |
420 return MethodMatcher::Unknown; | |
421 } | |
422 return (MethodMatcher::Mode)match; | |
423 } | |
424 | |
425 static bool scan_line(const char * line, | |
426 char class_name[], MethodMatcher::Mode* c_mode, | |
427 char method_name[], MethodMatcher::Mode* m_mode, | |
428 int* bytes_read, const char*& error_msg) { | |
429 *bytes_read = 0; | |
430 error_msg = NULL; | |
431 for (uint i = 0; i < ARRAY_SIZE(patterns); i++) { | |
432 if (2 == sscanf(line, patterns[i], class_name, method_name, bytes_read)) { | |
433 *c_mode = check_mode(class_name, error_msg); | |
434 *m_mode = check_mode(method_name, error_msg); | |
435 return *c_mode != MethodMatcher::Unknown && *m_mode != MethodMatcher::Unknown; | |
436 } | |
437 } | |
438 return false; | |
439 } | |
440 | |
441 | |
442 | |
443 void CompilerOracle::parse_from_line(char* line) { | |
444 if (line[0] == '\0') return; | |
445 if (line[0] == '#') return; | |
446 | |
447 bool have_colon = (strstr(line, "::") != NULL); | |
448 for (char* lp = line; *lp != '\0'; lp++) { | |
449 // Allow '.' to separate the class name from the method name. | |
450 // This is the preferred spelling of methods: | |
451 // exclude java/lang/String.indexOf(I)I | |
452 // Allow ',' for spaces (eases command line quoting). | |
453 // exclude,java/lang/String.indexOf | |
454 // For backward compatibility, allow space as separator also. | |
455 // exclude java/lang/String indexOf | |
456 // exclude,java/lang/String,indexOf | |
457 // For easy cut-and-paste of method names, allow VM output format | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6204
diff
changeset
|
458 // as produced by Method::print_short_name: |
0 | 459 // exclude java.lang.String::indexOf |
460 // For simple implementation convenience here, convert them all to space. | |
461 if (have_colon) { | |
462 if (*lp == '.') *lp = '/'; // dots build the package prefix | |
463 if (*lp == ':') *lp = ' '; | |
464 } | |
465 if (*lp == ',' || *lp == '.') *lp = ' '; | |
466 } | |
467 | |
468 char* original_line = line; | |
469 int bytes_read; | |
470 OracleCommand command = parse_command_name(line, &bytes_read); | |
471 line += bytes_read; | |
472 | |
2077
781072b12368
6765546: Wrong sscanf used to parse CompilerOracle command >= 32 characters could lead to crash
never
parents:
1972
diff
changeset
|
473 if (command == UnknownCommand) { |
781072b12368
6765546: Wrong sscanf used to parse CompilerOracle command >= 32 characters could lead to crash
never
parents:
1972
diff
changeset
|
474 tty->print_cr("CompilerOracle: unrecognized line"); |
781072b12368
6765546: Wrong sscanf used to parse CompilerOracle command >= 32 characters could lead to crash
never
parents:
1972
diff
changeset
|
475 tty->print_cr(" \"%s\"", original_line); |
781072b12368
6765546: Wrong sscanf used to parse CompilerOracle command >= 32 characters could lead to crash
never
parents:
1972
diff
changeset
|
476 return; |
781072b12368
6765546: Wrong sscanf used to parse CompilerOracle command >= 32 characters could lead to crash
never
parents:
1972
diff
changeset
|
477 } |
781072b12368
6765546: Wrong sscanf used to parse CompilerOracle command >= 32 characters could lead to crash
never
parents:
1972
diff
changeset
|
478 |
0 | 479 if (command == QuietCommand) { |
480 _quiet = true; | |
481 return; | |
482 } | |
483 | |
484 if (command == HelpCommand) { | |
485 usage(); | |
486 return; | |
487 } | |
488 | |
489 MethodMatcher::Mode c_match = MethodMatcher::Exact; | |
490 MethodMatcher::Mode m_match = MethodMatcher::Exact; | |
491 char class_name[256]; | |
492 char method_name[256]; | |
493 char sig[1024]; | |
494 char errorbuf[1024]; | |
495 const char* error_msg = NULL; | |
496 MethodMatcher* match = NULL; | |
497 | |
498 if (scan_line(line, class_name, &c_match, method_name, &m_match, &bytes_read, error_msg)) { | |
499 EXCEPTION_MARK; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
500 Symbol* c_name = SymbolTable::new_symbol(class_name, CHECK); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
501 Symbol* m_name = SymbolTable::new_symbol(method_name, CHECK); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
502 Symbol* signature = NULL; |
0 | 503 |
504 line += bytes_read; | |
505 // there might be a signature following the method. | |
506 // signatures always begin with ( so match that by hand | |
2077
781072b12368
6765546: Wrong sscanf used to parse CompilerOracle command >= 32 characters could lead to crash
never
parents:
1972
diff
changeset
|
507 if (1 == sscanf(line, "%*[ \t](%254[[);/" RANGEBASE "]%n", sig + 1, &bytes_read)) { |
0 | 508 sig[0] = '('; |
509 line += bytes_read; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
510 signature = SymbolTable::new_symbol(sig, CHECK); |
0 | 511 } |
512 | |
513 if (command == OptionCommand) { | |
514 // Look for trailing options to support | |
515 // ciMethod::has_option("string") to control features in the | |
516 // compiler. Multiple options may follow the method name. | |
517 char option[256]; | |
518 while (sscanf(line, "%*[ \t]%255[a-zA-Z0-9]%n", option, &bytes_read) == 1) { | |
519 if (match != NULL && !_quiet) { | |
520 // Print out the last match added | |
521 tty->print("CompilerOracle: %s ", command_names[command]); | |
522 match->print(); | |
523 } | |
524 match = add_option_string(c_name, c_match, m_name, m_match, signature, strdup(option)); | |
525 line += bytes_read; | |
526 } | |
527 } else { | |
528 bytes_read = 0; | |
529 sscanf(line, "%*[ \t]%n", &bytes_read); | |
530 if (line[bytes_read] != '\0') { | |
531 jio_snprintf(errorbuf, sizeof(errorbuf), " Unrecognized text after command: %s", line); | |
532 error_msg = errorbuf; | |
533 } else { | |
534 match = add_predicate(command, c_name, c_match, m_name, m_match, signature); | |
535 } | |
536 } | |
537 } | |
538 | |
539 if (match != NULL) { | |
540 if (!_quiet) { | |
541 tty->print("CompilerOracle: %s ", command_names[command]); | |
542 match->print(); | |
543 } | |
544 } else { | |
545 tty->print_cr("CompilerOracle: unrecognized line"); | |
546 tty->print_cr(" \"%s\"", original_line); | |
547 if (error_msg != NULL) { | |
548 tty->print_cr(error_msg); | |
549 } | |
550 } | |
551 } | |
552 | |
6196
3759236eea14
7167142: Consider a warning when finding a .hotspotrc or .hotspot_compiler file that isn't used
kamg
parents:
6150
diff
changeset
|
553 static const char* default_cc_file = ".hotspot_compiler"; |
3759236eea14
7167142: Consider a warning when finding a .hotspotrc or .hotspot_compiler file that isn't used
kamg
parents:
6150
diff
changeset
|
554 |
0 | 555 static const char* cc_file() { |
6150
1e76463170b3
7110720: Issue with vm config file loadingIssue with vm config file loading
kamg
parents:
2426
diff
changeset
|
556 #ifdef ASSERT |
0 | 557 if (CompileCommandFile == NULL) |
6196
3759236eea14
7167142: Consider a warning when finding a .hotspotrc or .hotspot_compiler file that isn't used
kamg
parents:
6150
diff
changeset
|
558 return default_cc_file; |
6150
1e76463170b3
7110720: Issue with vm config file loadingIssue with vm config file loading
kamg
parents:
2426
diff
changeset
|
559 #endif |
0 | 560 return CompileCommandFile; |
561 } | |
6150
1e76463170b3
7110720: Issue with vm config file loadingIssue with vm config file loading
kamg
parents:
2426
diff
changeset
|
562 |
1e76463170b3
7110720: Issue with vm config file loadingIssue with vm config file loading
kamg
parents:
2426
diff
changeset
|
563 bool CompilerOracle::has_command_file() { |
1e76463170b3
7110720: Issue with vm config file loadingIssue with vm config file loading
kamg
parents:
2426
diff
changeset
|
564 return cc_file() != NULL; |
1e76463170b3
7110720: Issue with vm config file loadingIssue with vm config file loading
kamg
parents:
2426
diff
changeset
|
565 } |
1e76463170b3
7110720: Issue with vm config file loadingIssue with vm config file loading
kamg
parents:
2426
diff
changeset
|
566 |
0 | 567 bool CompilerOracle::_quiet = false; |
568 | |
569 void CompilerOracle::parse_from_file() { | |
6150
1e76463170b3
7110720: Issue with vm config file loadingIssue with vm config file loading
kamg
parents:
2426
diff
changeset
|
570 assert(has_command_file(), "command file must be specified"); |
0 | 571 FILE* stream = fopen(cc_file(), "rt"); |
572 if (stream == NULL) return; | |
573 | |
574 char token[1024]; | |
575 int pos = 0; | |
576 int c = getc(stream); | |
577 while(c != EOF) { | |
578 if (c == '\n') { | |
579 token[pos++] = '\0'; | |
580 parse_from_line(token); | |
581 pos = 0; | |
582 } else { | |
583 token[pos++] = c; | |
584 } | |
585 c = getc(stream); | |
586 } | |
587 token[pos++] = '\0'; | |
588 parse_from_line(token); | |
589 | |
590 fclose(stream); | |
591 } | |
592 | |
593 void CompilerOracle::parse_from_string(const char* str, void (*parse_line)(char*)) { | |
594 char token[1024]; | |
595 int pos = 0; | |
596 const char* sp = str; | |
597 int c = *sp++; | |
598 while (c != '\0') { | |
599 if (c == '\n') { | |
600 token[pos++] = '\0'; | |
601 parse_line(token); | |
602 pos = 0; | |
603 } else { | |
604 token[pos++] = c; | |
605 } | |
606 c = *sp++; | |
607 } | |
608 token[pos++] = '\0'; | |
609 parse_line(token); | |
610 } | |
611 | |
612 void CompilerOracle::append_comment_to_file(const char* message) { | |
6150
1e76463170b3
7110720: Issue with vm config file loadingIssue with vm config file loading
kamg
parents:
2426
diff
changeset
|
613 assert(has_command_file(), "command file must be specified"); |
0 | 614 fileStream stream(fopen(cc_file(), "at")); |
615 stream.print("# "); | |
616 for (int index = 0; message[index] != '\0'; index++) { | |
617 stream.put(message[index]); | |
618 if (message[index] == '\n') stream.print("# "); | |
619 } | |
620 stream.cr(); | |
621 } | |
622 | |
623 void CompilerOracle::append_exclude_to_file(methodHandle method) { | |
6150
1e76463170b3
7110720: Issue with vm config file loadingIssue with vm config file loading
kamg
parents:
2426
diff
changeset
|
624 assert(has_command_file(), "command file must be specified"); |
0 | 625 fileStream stream(fopen(cc_file(), "at")); |
626 stream.print("exclude "); | |
627 Klass::cast(method->method_holder())->name()->print_symbol_on(&stream); | |
628 stream.print("."); | |
629 method->name()->print_symbol_on(&stream); | |
630 method->signature()->print_symbol_on(&stream); | |
631 stream.cr(); | |
632 stream.cr(); | |
633 } | |
634 | |
635 | |
636 void compilerOracle_init() { | |
637 CompilerOracle::parse_from_string(CompileCommand, CompilerOracle::parse_from_line); | |
638 CompilerOracle::parse_from_string(CompileOnly, CompilerOracle::parse_compile_only); | |
6150
1e76463170b3
7110720: Issue with vm config file loadingIssue with vm config file loading
kamg
parents:
2426
diff
changeset
|
639 if (CompilerOracle::has_command_file()) { |
1e76463170b3
7110720: Issue with vm config file loadingIssue with vm config file loading
kamg
parents:
2426
diff
changeset
|
640 CompilerOracle::parse_from_file(); |
6196
3759236eea14
7167142: Consider a warning when finding a .hotspotrc or .hotspot_compiler file that isn't used
kamg
parents:
6150
diff
changeset
|
641 } else { |
3759236eea14
7167142: Consider a warning when finding a .hotspotrc or .hotspot_compiler file that isn't used
kamg
parents:
6150
diff
changeset
|
642 struct stat buf; |
3759236eea14
7167142: Consider a warning when finding a .hotspotrc or .hotspot_compiler file that isn't used
kamg
parents:
6150
diff
changeset
|
643 if (os::stat(default_cc_file, &buf) == 0) { |
3759236eea14
7167142: Consider a warning when finding a .hotspotrc or .hotspot_compiler file that isn't used
kamg
parents:
6150
diff
changeset
|
644 warning("%s file is present but has been ignored. " |
3759236eea14
7167142: Consider a warning when finding a .hotspotrc or .hotspot_compiler file that isn't used
kamg
parents:
6150
diff
changeset
|
645 "Run with -XX:CompileCommandFile=%s to load the file.", |
3759236eea14
7167142: Consider a warning when finding a .hotspotrc or .hotspot_compiler file that isn't used
kamg
parents:
6150
diff
changeset
|
646 default_cc_file, default_cc_file); |
3759236eea14
7167142: Consider a warning when finding a .hotspotrc or .hotspot_compiler file that isn't used
kamg
parents:
6150
diff
changeset
|
647 } |
6150
1e76463170b3
7110720: Issue with vm config file loadingIssue with vm config file loading
kamg
parents:
2426
diff
changeset
|
648 } |
1155
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
649 if (lists[PrintCommand] != NULL) { |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
650 if (PrintAssembly) { |
6196
3759236eea14
7167142: Consider a warning when finding a .hotspotrc or .hotspot_compiler file that isn't used
kamg
parents:
6150
diff
changeset
|
651 warning("CompileCommand and/or %s file contains 'print' commands, but PrintAssembly is also enabled", default_cc_file); |
1155
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
652 } else if (FLAG_IS_DEFAULT(DebugNonSafepoints)) { |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
653 warning("printing of assembly code is enabled; turning on DebugNonSafepoints to gain additional output"); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
654 DebugNonSafepoints = true; |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
655 } |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
656 } |
0 | 657 } |
658 | |
659 | |
660 void CompilerOracle::parse_compile_only(char * line) { | |
661 int i; | |
662 char name[1024]; | |
663 const char* className = NULL; | |
664 const char* methodName = NULL; | |
665 | |
666 bool have_colon = (strstr(line, "::") != NULL); | |
667 char method_sep = have_colon ? ':' : '.'; | |
668 | |
669 if (Verbose) { | |
670 tty->print_cr(line); | |
671 } | |
672 | |
673 ResourceMark rm; | |
674 while (*line != '\0') { | |
675 MethodMatcher::Mode c_match = MethodMatcher::Exact; | |
676 MethodMatcher::Mode m_match = MethodMatcher::Exact; | |
677 | |
678 for (i = 0; | |
679 i < 1024 && *line != '\0' && *line != method_sep && *line != ',' && !isspace(*line); | |
680 line++, i++) { | |
681 name[i] = *line; | |
682 if (name[i] == '.') name[i] = '/'; // package prefix uses '/' | |
683 } | |
684 | |
685 if (i > 0) { | |
686 char* newName = NEW_RESOURCE_ARRAY( char, i + 1); | |
687 if (newName == NULL) | |
688 return; | |
689 strncpy(newName, name, i); | |
690 newName[i] = '\0'; | |
691 | |
692 if (className == NULL) { | |
693 className = newName; | |
694 c_match = MethodMatcher::Prefix; | |
695 } else { | |
696 methodName = newName; | |
697 } | |
698 } | |
699 | |
700 if (*line == method_sep) { | |
701 if (className == NULL) { | |
702 className = ""; | |
703 c_match = MethodMatcher::Any; | |
704 } else { | |
705 // foo/bar.blah is an exact match on foo/bar, bar.blah is a suffix match on bar | |
706 if (strchr(className, '/') != NULL) { | |
707 c_match = MethodMatcher::Exact; | |
708 } else { | |
709 c_match = MethodMatcher::Suffix; | |
710 } | |
711 } | |
712 } else { | |
713 // got foo or foo/bar | |
714 if (className == NULL) { | |
715 ShouldNotReachHere(); | |
716 } else { | |
717 // got foo or foo/bar | |
718 if (strchr(className, '/') != NULL) { | |
719 c_match = MethodMatcher::Prefix; | |
720 } else if (className[0] == '\0') { | |
721 c_match = MethodMatcher::Any; | |
722 } else { | |
723 c_match = MethodMatcher::Substring; | |
724 } | |
725 } | |
726 } | |
727 | |
728 // each directive is terminated by , or NUL or . followed by NUL | |
729 if (*line == ',' || *line == '\0' || (line[0] == '.' && line[1] == '\0')) { | |
730 if (methodName == NULL) { | |
731 methodName = ""; | |
732 if (*line != method_sep) { | |
733 m_match = MethodMatcher::Any; | |
734 } | |
735 } | |
736 | |
737 EXCEPTION_MARK; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
738 Symbol* c_name = SymbolTable::new_symbol(className, CHECK); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
739 Symbol* m_name = SymbolTable::new_symbol(methodName, CHECK); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
740 Symbol* signature = NULL; |
0 | 741 |
742 add_predicate(CompileOnlyCommand, c_name, c_match, m_name, m_match, signature); | |
743 if (PrintVMOptions) { | |
744 tty->print("CompileOnly: compileonly "); | |
745 lists[CompileOnlyCommand]->print(); | |
746 } | |
747 | |
748 className = NULL; | |
749 methodName = NULL; | |
750 } | |
751 | |
752 line = *line == '\0' ? line : line + 1; | |
753 } | |
754 } |