Mercurial > hg > truffle
annotate src/share/vm/compiler/compilerOracle.cpp @ 1994:6cd6d394f280
7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed())
7002546: regression on SpecJbb2005 on 7b118 comparing to 7b117 on small heaps
Summary: Relaxed assertion checking related to incremental_collection_failed flag to allow for ExplicitGCInvokesConcurrent behaviour where we do not want a failing scavenge to bail to a stop-world collection. Parameterized incremental_collection_will_fail() so we can selectively use, or not use, as appropriate, the statistical prediction at specific use sites. This essentially reverts the scavenge bail-out logic to what it was prior to some recent changes that had inadvertently started using the statistical prediction which can be noisy in the presence of bursty loads. Added some associated verbose non-product debugging messages.
Reviewed-by: johnc, tonyp
author | ysr |
---|---|
date | Tue, 07 Dec 2010 21:55:53 -0800 |
parents | f95d63e2154a |
children | 781072b12368 |
rev | line source |
---|---|
0 | 1 /* |
1972 | 2 * Copyright (c) 1998, 2010, 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" | |
31 #include "oops/methodOop.hpp" | |
32 #include "oops/oop.inline.hpp" | |
33 #include "oops/symbolOop.hpp" | |
34 #include "runtime/handles.inline.hpp" | |
35 #include "runtime/jniHandles.hpp" | |
0 | 36 |
37 class MethodMatcher : public CHeapObj { | |
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: | |
49 jobject _class_name; | |
50 Mode _class_mode; | |
51 jobject _method_name; | |
52 Mode _method_mode; | |
53 jobject _signature; | |
54 MethodMatcher* _next; | |
55 | |
56 static bool match(symbolHandle candidate, symbolHandle match, Mode match_mode); | |
57 | |
58 symbolHandle class_name() const { return (symbolOop)JNIHandles::resolve_non_null(_class_name); } | |
59 symbolHandle method_name() const { return (symbolOop)JNIHandles::resolve_non_null(_method_name); } | |
60 symbolHandle signature() const { return (symbolOop)JNIHandles::resolve(_signature); } | |
61 | |
62 public: | |
63 MethodMatcher(symbolHandle class_name, Mode class_mode, | |
64 symbolHandle method_name, Mode method_mode, | |
65 symbolHandle signature, MethodMatcher* next); | |
66 MethodMatcher(symbolHandle class_name, symbolHandle method_name, MethodMatcher* next); | |
67 | |
68 // utility method | |
69 MethodMatcher* find(methodHandle method) { | |
70 symbolHandle class_name = Klass::cast(method->method_holder())->name(); | |
71 symbolHandle method_name = method->name(); | |
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) && | |
75 (current->signature().is_null() || current->signature()() == method->signature())) { | |
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 | |
88 static void print_symbol(symbolHandle h, Mode mode) { | |
89 ResourceMark rm; | |
90 | |
91 if (mode == Suffix || mode == Substring || mode == Any) { | |
92 tty->print("*"); | |
93 } | |
94 if (mode != Any) { | |
95 h()->print_symbol_on(tty); | |
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); | |
106 if (!signature().is_null()) { | |
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 | |
118 MethodMatcher::MethodMatcher(symbolHandle class_name, symbolHandle method_name, MethodMatcher* next) { | |
119 _class_name = JNIHandles::make_global(class_name); | |
120 _method_name = JNIHandles::make_global(method_name); | |
121 _next = next; | |
122 _class_mode = MethodMatcher::Exact; | |
123 _method_mode = MethodMatcher::Exact; | |
124 _signature = NULL; | |
125 } | |
126 | |
127 | |
128 MethodMatcher::MethodMatcher(symbolHandle class_name, Mode class_mode, | |
129 symbolHandle method_name, Mode method_mode, | |
130 symbolHandle signature, MethodMatcher* next): | |
131 _class_mode(class_mode) | |
132 , _method_mode(method_mode) | |
133 , _next(next) | |
134 , _class_name(JNIHandles::make_global(class_name())) | |
135 , _method_name(JNIHandles::make_global(method_name())) | |
136 , _signature(JNIHandles::make_global(signature())) { | |
137 } | |
138 | |
139 bool MethodMatcher::match(symbolHandle candidate, symbolHandle match, Mode match_mode) { | |
140 if (match_mode == Any) { | |
141 return true; | |
142 } | |
143 | |
144 if (match_mode == Exact) { | |
145 return candidate() == match(); | |
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: | |
174 MethodOptionMatcher(symbolHandle class_name, Mode class_mode, | |
175 symbolHandle method_name, Mode method_mode, | |
176 symbolHandle signature, const char * opt, MethodMatcher* next): | |
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, | |
259 symbolHandle class_name, MethodMatcher::Mode c_mode, | |
260 symbolHandle method_name, MethodMatcher::Mode m_mode, | |
261 symbolHandle signature) { | |
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 | |
271 static MethodMatcher* add_option_string(symbolHandle class_name, MethodMatcher::Mode c_mode, | |
272 symbolHandle method_name, MethodMatcher::Mode m_mode, | |
273 symbolHandle signature, | |
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; | |
335 char command[32]; | |
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 | |
458 // as produced by methodOopDesc::print_short_name: | |
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 | |
473 if (command == QuietCommand) { | |
474 _quiet = true; | |
475 return; | |
476 } | |
477 | |
478 if (command == HelpCommand) { | |
479 usage(); | |
480 return; | |
481 } | |
482 | |
483 MethodMatcher::Mode c_match = MethodMatcher::Exact; | |
484 MethodMatcher::Mode m_match = MethodMatcher::Exact; | |
485 char class_name[256]; | |
486 char method_name[256]; | |
487 char sig[1024]; | |
488 char errorbuf[1024]; | |
489 const char* error_msg = NULL; | |
490 MethodMatcher* match = NULL; | |
491 | |
492 if (scan_line(line, class_name, &c_match, method_name, &m_match, &bytes_read, error_msg)) { | |
493 EXCEPTION_MARK; | |
494 symbolHandle c_name = oopFactory::new_symbol_handle(class_name, CHECK); | |
495 symbolHandle m_name = oopFactory::new_symbol_handle(method_name, CHECK); | |
496 symbolHandle signature; | |
497 | |
498 line += bytes_read; | |
499 // there might be a signature following the method. | |
500 // signatures always begin with ( so match that by hand | |
501 if (1 == sscanf(line, "%*[ \t](%254[);/" RANGEBASE "]%n", sig + 1, &bytes_read)) { | |
502 sig[0] = '('; | |
503 line += bytes_read; | |
504 signature = oopFactory::new_symbol_handle(sig, CHECK); | |
505 } | |
506 | |
507 if (command == OptionCommand) { | |
508 // Look for trailing options to support | |
509 // ciMethod::has_option("string") to control features in the | |
510 // compiler. Multiple options may follow the method name. | |
511 char option[256]; | |
512 while (sscanf(line, "%*[ \t]%255[a-zA-Z0-9]%n", option, &bytes_read) == 1) { | |
513 if (match != NULL && !_quiet) { | |
514 // Print out the last match added | |
515 tty->print("CompilerOracle: %s ", command_names[command]); | |
516 match->print(); | |
517 } | |
518 match = add_option_string(c_name, c_match, m_name, m_match, signature, strdup(option)); | |
519 line += bytes_read; | |
520 } | |
521 } else { | |
522 bytes_read = 0; | |
523 sscanf(line, "%*[ \t]%n", &bytes_read); | |
524 if (line[bytes_read] != '\0') { | |
525 jio_snprintf(errorbuf, sizeof(errorbuf), " Unrecognized text after command: %s", line); | |
526 error_msg = errorbuf; | |
527 } else { | |
528 match = add_predicate(command, c_name, c_match, m_name, m_match, signature); | |
529 } | |
530 } | |
531 } | |
532 | |
533 if (match != NULL) { | |
534 if (!_quiet) { | |
535 tty->print("CompilerOracle: %s ", command_names[command]); | |
536 match->print(); | |
537 } | |
538 } else { | |
539 tty->print_cr("CompilerOracle: unrecognized line"); | |
540 tty->print_cr(" \"%s\"", original_line); | |
541 if (error_msg != NULL) { | |
542 tty->print_cr(error_msg); | |
543 } | |
544 } | |
545 } | |
546 | |
547 static const char* cc_file() { | |
548 if (CompileCommandFile == NULL) | |
549 return ".hotspot_compiler"; | |
550 return CompileCommandFile; | |
551 } | |
552 bool CompilerOracle::_quiet = false; | |
553 | |
554 void CompilerOracle::parse_from_file() { | |
555 FILE* stream = fopen(cc_file(), "rt"); | |
556 if (stream == NULL) return; | |
557 | |
558 char token[1024]; | |
559 int pos = 0; | |
560 int c = getc(stream); | |
561 while(c != EOF) { | |
562 if (c == '\n') { | |
563 token[pos++] = '\0'; | |
564 parse_from_line(token); | |
565 pos = 0; | |
566 } else { | |
567 token[pos++] = c; | |
568 } | |
569 c = getc(stream); | |
570 } | |
571 token[pos++] = '\0'; | |
572 parse_from_line(token); | |
573 | |
574 fclose(stream); | |
575 } | |
576 | |
577 void CompilerOracle::parse_from_string(const char* str, void (*parse_line)(char*)) { | |
578 char token[1024]; | |
579 int pos = 0; | |
580 const char* sp = str; | |
581 int c = *sp++; | |
582 while (c != '\0') { | |
583 if (c == '\n') { | |
584 token[pos++] = '\0'; | |
585 parse_line(token); | |
586 pos = 0; | |
587 } else { | |
588 token[pos++] = c; | |
589 } | |
590 c = *sp++; | |
591 } | |
592 token[pos++] = '\0'; | |
593 parse_line(token); | |
594 } | |
595 | |
596 void CompilerOracle::append_comment_to_file(const char* message) { | |
597 fileStream stream(fopen(cc_file(), "at")); | |
598 stream.print("# "); | |
599 for (int index = 0; message[index] != '\0'; index++) { | |
600 stream.put(message[index]); | |
601 if (message[index] == '\n') stream.print("# "); | |
602 } | |
603 stream.cr(); | |
604 } | |
605 | |
606 void CompilerOracle::append_exclude_to_file(methodHandle method) { | |
607 fileStream stream(fopen(cc_file(), "at")); | |
608 stream.print("exclude "); | |
609 Klass::cast(method->method_holder())->name()->print_symbol_on(&stream); | |
610 stream.print("."); | |
611 method->name()->print_symbol_on(&stream); | |
612 method->signature()->print_symbol_on(&stream); | |
613 stream.cr(); | |
614 stream.cr(); | |
615 } | |
616 | |
617 | |
618 void compilerOracle_init() { | |
619 CompilerOracle::parse_from_string(CompileCommand, CompilerOracle::parse_from_line); | |
620 CompilerOracle::parse_from_string(CompileOnly, CompilerOracle::parse_compile_only); | |
621 CompilerOracle::parse_from_file(); | |
1155
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
622 if (lists[PrintCommand] != NULL) { |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
623 if (PrintAssembly) { |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
624 warning("CompileCommand and/or .hotspot_compiler file contains 'print' commands, but PrintAssembly is also enabled"); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
625 } else if (FLAG_IS_DEFAULT(DebugNonSafepoints)) { |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
626 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
|
627 DebugNonSafepoints = true; |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
628 } |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
629 } |
0 | 630 } |
631 | |
632 | |
633 void CompilerOracle::parse_compile_only(char * line) { | |
634 int i; | |
635 char name[1024]; | |
636 const char* className = NULL; | |
637 const char* methodName = NULL; | |
638 | |
639 bool have_colon = (strstr(line, "::") != NULL); | |
640 char method_sep = have_colon ? ':' : '.'; | |
641 | |
642 if (Verbose) { | |
643 tty->print_cr(line); | |
644 } | |
645 | |
646 ResourceMark rm; | |
647 while (*line != '\0') { | |
648 MethodMatcher::Mode c_match = MethodMatcher::Exact; | |
649 MethodMatcher::Mode m_match = MethodMatcher::Exact; | |
650 | |
651 for (i = 0; | |
652 i < 1024 && *line != '\0' && *line != method_sep && *line != ',' && !isspace(*line); | |
653 line++, i++) { | |
654 name[i] = *line; | |
655 if (name[i] == '.') name[i] = '/'; // package prefix uses '/' | |
656 } | |
657 | |
658 if (i > 0) { | |
659 char* newName = NEW_RESOURCE_ARRAY( char, i + 1); | |
660 if (newName == NULL) | |
661 return; | |
662 strncpy(newName, name, i); | |
663 newName[i] = '\0'; | |
664 | |
665 if (className == NULL) { | |
666 className = newName; | |
667 c_match = MethodMatcher::Prefix; | |
668 } else { | |
669 methodName = newName; | |
670 } | |
671 } | |
672 | |
673 if (*line == method_sep) { | |
674 if (className == NULL) { | |
675 className = ""; | |
676 c_match = MethodMatcher::Any; | |
677 } else { | |
678 // foo/bar.blah is an exact match on foo/bar, bar.blah is a suffix match on bar | |
679 if (strchr(className, '/') != NULL) { | |
680 c_match = MethodMatcher::Exact; | |
681 } else { | |
682 c_match = MethodMatcher::Suffix; | |
683 } | |
684 } | |
685 } else { | |
686 // got foo or foo/bar | |
687 if (className == NULL) { | |
688 ShouldNotReachHere(); | |
689 } else { | |
690 // got foo or foo/bar | |
691 if (strchr(className, '/') != NULL) { | |
692 c_match = MethodMatcher::Prefix; | |
693 } else if (className[0] == '\0') { | |
694 c_match = MethodMatcher::Any; | |
695 } else { | |
696 c_match = MethodMatcher::Substring; | |
697 } | |
698 } | |
699 } | |
700 | |
701 // each directive is terminated by , or NUL or . followed by NUL | |
702 if (*line == ',' || *line == '\0' || (line[0] == '.' && line[1] == '\0')) { | |
703 if (methodName == NULL) { | |
704 methodName = ""; | |
705 if (*line != method_sep) { | |
706 m_match = MethodMatcher::Any; | |
707 } | |
708 } | |
709 | |
710 EXCEPTION_MARK; | |
711 symbolHandle c_name = oopFactory::new_symbol_handle(className, CHECK); | |
712 symbolHandle m_name = oopFactory::new_symbol_handle(methodName, CHECK); | |
713 symbolHandle signature; | |
714 | |
715 add_predicate(CompileOnlyCommand, c_name, c_match, m_name, m_match, signature); | |
716 if (PrintVMOptions) { | |
717 tty->print("CompileOnly: compileonly "); | |
718 lists[CompileOnlyCommand]->print(); | |
719 } | |
720 | |
721 className = NULL; | |
722 methodName = NULL; | |
723 } | |
724 | |
725 line = *line == '\0' ? line : line + 1; | |
726 } | |
727 } |