Mercurial > hg > truffle
comparison src/share/vm/compiler/compilerOracle.cpp @ 20429:14b356bbca27
8055286: Extend CompileCommand=option to handle numeric parameters
Summary: Changed CompileCommand=option to handle "extended" parameters: Klass::method,type,flag,value. Types supported are bool, intx, and uintx.
Reviewed-by: kvn, roland
author | zmajo |
---|---|
date | Fri, 29 Aug 2014 15:32:16 +0200 |
parents | 78bbf4d43a14 |
children | 119875f0fc67 |
comparison
equal
deleted
inserted
replaced
20428:4d8781a35525 | 20429:14b356bbca27 |
---|---|
165 default: | 165 default: |
166 return false; | 166 return false; |
167 } | 167 } |
168 } | 168 } |
169 | 169 |
170 | 170 enum OptionType { |
171 class MethodOptionMatcher: public MethodMatcher { | 171 IntxType, |
172 const char * option; | 172 UintxType, |
173 public: | 173 BoolType, |
174 MethodOptionMatcher(Symbol* class_name, Mode class_mode, | 174 CcstrType, |
175 Symbol* method_name, Mode method_mode, | 175 CcstrListType, |
176 Symbol* signature, const char * opt, MethodMatcher* next): | 176 UnknownType |
177 MethodMatcher(class_name, class_mode, method_name, method_mode, signature, next) { | 177 }; |
178 option = opt; | 178 |
179 } | 179 /* Methods to map real type names to OptionType */ |
180 | 180 template<typename T> |
181 bool match(methodHandle method, const char* opt) { | 181 static OptionType get_type_for() { |
182 MethodOptionMatcher* current = this; | 182 return UnknownType; |
183 }; | |
184 | |
185 template<> OptionType get_type_for<intx>() { | |
186 return IntxType; | |
187 } | |
188 | |
189 template<> OptionType get_type_for<uintx>() { | |
190 return UintxType; | |
191 } | |
192 | |
193 template<> OptionType get_type_for<bool>() { | |
194 return BoolType; | |
195 } | |
196 | |
197 template <typename T> | |
198 class TypedMethodOptionMatcher : public MethodMatcher { | |
199 const char* _option; | |
200 OptionType _type; | |
201 const T _value; | |
202 | |
203 public: | |
204 TypedMethodOptionMatcher(Symbol* class_name, Mode class_mode, | |
205 Symbol* method_name, Mode method_mode, | |
206 Symbol* signature, const char* opt, | |
207 const T value, MethodMatcher* next) : | |
208 MethodMatcher(class_name, class_mode, method_name, method_mode, signature, next), | |
209 _type(get_type_for<T>()), _value(value) { | |
210 _option = strdup(opt); | |
211 } | |
212 | |
213 ~TypedMethodOptionMatcher() { | |
214 free((void*)_option); | |
215 } | |
216 | |
217 TypedMethodOptionMatcher* match(methodHandle method, const char* opt) { | |
218 TypedMethodOptionMatcher* current = this; | |
183 while (current != NULL) { | 219 while (current != NULL) { |
184 current = (MethodOptionMatcher*)current->find(method); | 220 current = (TypedMethodOptionMatcher*)current->find(method); |
185 if (current == NULL) { | 221 if (current == NULL) { |
186 return false; | 222 return NULL; |
187 } | 223 } |
188 if (strcmp(current->option, opt) == 0) { | 224 if (strcmp(current->_option, opt) == 0) { |
189 return true; | 225 return current; |
190 } | 226 } |
191 current = current->next(); | 227 current = current->next(); |
192 } | 228 } |
193 return false; | 229 return NULL; |
194 } | 230 } |
195 | 231 |
196 MethodOptionMatcher* next() { | 232 TypedMethodOptionMatcher* next() { |
197 return (MethodOptionMatcher*)_next; | 233 return (TypedMethodOptionMatcher*)_next; |
198 } | 234 } |
199 | 235 |
200 virtual void print() { | 236 OptionType get_type(void) { |
237 return _type; | |
238 }; | |
239 | |
240 T value() { return _value; } | |
241 | |
242 void print() { | |
243 ttyLocker ttyl; | |
201 print_base(); | 244 print_base(); |
202 tty->print(" %s", option); | 245 tty->print(" %s", _option); |
246 tty->print(" <unknown option type>"); | |
203 tty->cr(); | 247 tty->cr(); |
204 } | 248 } |
205 }; | 249 }; |
206 | 250 |
207 | 251 template<> |
252 void TypedMethodOptionMatcher<intx>::print() { | |
253 ttyLocker ttyl; | |
254 print_base(); | |
255 tty->print(" %s", _option); | |
256 tty->print(" " INTX_FORMAT, _value); | |
257 tty->cr(); | |
258 }; | |
259 | |
260 template<> | |
261 void TypedMethodOptionMatcher<uintx>::print() { | |
262 ttyLocker ttyl; | |
263 print_base(); | |
264 tty->print(" %s", _option); | |
265 tty->print(" " UINTX_FORMAT, _value); | |
266 tty->cr(); | |
267 }; | |
268 | |
269 template<> | |
270 void TypedMethodOptionMatcher<bool>::print() { | |
271 ttyLocker ttyl; | |
272 print_base(); | |
273 tty->print(" %s", _option); | |
274 tty->print(" %s", _value ? "true" : "false"); | |
275 tty->cr(); | |
276 }; | |
208 | 277 |
209 // this must parallel the command_names below | 278 // this must parallel the command_names below |
210 enum OracleCommand { | 279 enum OracleCommand { |
211 UnknownCommand = -1, | 280 UnknownCommand = -1, |
212 OracleFirstCommand = 0, | 281 OracleFirstCommand = 0, |
257 tty->print_cr("Warning: +LogCompilation must be enabled in order for individual methods to be logged."); | 326 tty->print_cr("Warning: +LogCompilation must be enabled in order for individual methods to be logged."); |
258 lists[command] = new MethodMatcher(class_name, c_mode, method_name, m_mode, signature, lists[command]); | 327 lists[command] = new MethodMatcher(class_name, c_mode, method_name, m_mode, signature, lists[command]); |
259 return lists[command]; | 328 return lists[command]; |
260 } | 329 } |
261 | 330 |
262 | 331 template<typename T> |
263 | |
264 static MethodMatcher* add_option_string(Symbol* class_name, MethodMatcher::Mode c_mode, | 332 static MethodMatcher* add_option_string(Symbol* class_name, MethodMatcher::Mode c_mode, |
265 Symbol* method_name, MethodMatcher::Mode m_mode, | 333 Symbol* method_name, MethodMatcher::Mode m_mode, |
266 Symbol* signature, | 334 Symbol* signature, |
267 const char* option) { | 335 const char* option, |
268 lists[OptionCommand] = new MethodOptionMatcher(class_name, c_mode, method_name, m_mode, | 336 T value) { |
269 signature, option, lists[OptionCommand]); | 337 lists[OptionCommand] = new TypedMethodOptionMatcher<T>(class_name, c_mode, method_name, m_mode, |
338 signature, option, value, lists[OptionCommand]); | |
270 return lists[OptionCommand]; | 339 return lists[OptionCommand]; |
271 } | 340 } |
272 | 341 |
342 template<typename T> | |
343 static bool get_option_value(methodHandle method, const char* option, T& value) { | |
344 TypedMethodOptionMatcher<T>* m; | |
345 if (lists[OptionCommand] != NULL | |
346 && (m = ((TypedMethodOptionMatcher<T>*)lists[OptionCommand])->match(method, option)) != NULL | |
347 && m->get_type() == get_type_for<T>()) { | |
348 value = m->value(); | |
349 return true; | |
350 } else { | |
351 return false; | |
352 } | |
353 } | |
273 | 354 |
274 bool CompilerOracle::has_option_string(methodHandle method, const char* option) { | 355 bool CompilerOracle::has_option_string(methodHandle method, const char* option) { |
275 return lists[OptionCommand] != NULL && | 356 bool value = false; |
276 ((MethodOptionMatcher*)lists[OptionCommand])->match(method, option); | 357 get_option_value(method, option, value); |
277 } | 358 return value; |
278 | 359 } |
360 | |
361 template<typename T> | |
362 bool CompilerOracle::has_option_value(methodHandle method, const char* option, T& value) { | |
363 return get_option_value(method, option, value); | |
364 } | |
365 | |
366 // Explicit instantiation for all OptionTypes supported. | |
367 template bool CompilerOracle::has_option_value<intx>(methodHandle method, const char* option, intx& value); | |
368 template bool CompilerOracle::has_option_value<uintx>(methodHandle method, const char* option, uintx& value); | |
369 template bool CompilerOracle::has_option_value<bool>(methodHandle method, const char* option, bool& value); | |
279 | 370 |
280 bool CompilerOracle::should_exclude(methodHandle method, bool& quietly) { | 371 bool CompilerOracle::should_exclude(methodHandle method, bool& quietly) { |
281 quietly = true; | 372 quietly = true; |
282 if (lists[ExcludeCommand] != NULL) { | 373 if (lists[ExcludeCommand] != NULL) { |
283 if (lists[ExcludeCommand]->match(method)) { | 374 if (lists[ExcludeCommand]->match(method)) { |
431 return false; | 522 return false; |
432 } | 523 } |
433 | 524 |
434 | 525 |
435 | 526 |
527 // Scan next flag and value in line, return MethodMatcher object on success, NULL on failure. | |
528 // On failure, error_msg contains description for the first error. | |
529 // For future extensions: set error_msg on first error. | |
530 static MethodMatcher* scan_flag_and_value(const char* type, const char* line, int& total_bytes_read, | |
531 Symbol* c_name, MethodMatcher::Mode c_match, | |
532 Symbol* m_name, MethodMatcher::Mode m_match, | |
533 Symbol* signature, | |
534 char* errorbuf, const int buf_size) { | |
535 total_bytes_read = 0; | |
536 int bytes_read = 0; | |
537 char flag[256]; | |
538 | |
539 // Read flag name. | |
540 if (sscanf(line, "%*[ \t]%255[a-zA-Z0-9]%n", flag, &bytes_read) == 1) { | |
541 line += bytes_read; | |
542 total_bytes_read += bytes_read; | |
543 | |
544 // Read value. | |
545 if (strcmp(type, "intx") == 0) { | |
546 intx value; | |
547 if (sscanf(line, "%*[ \t]" INTX_FORMAT "%n", &value, &bytes_read) == 1) { | |
548 total_bytes_read += bytes_read; | |
549 return add_option_string(c_name, c_match, m_name, m_match, signature, flag, value); | |
550 } else { | |
551 jio_snprintf(errorbuf, buf_size, " Value cannot be read for flag %s of type %s ", flag, type); | |
552 } | |
553 } else if (strcmp(type, "uintx") == 0) { | |
554 uintx value; | |
555 if (sscanf(line, "%*[ \t]" UINTX_FORMAT "%n", &value, &bytes_read) == 1) { | |
556 total_bytes_read += bytes_read; | |
557 return add_option_string(c_name, c_match, m_name, m_match, signature, flag, value); | |
558 } else { | |
559 jio_snprintf(errorbuf, buf_size, " Value cannot be read for flag %s of type %s", flag, type); | |
560 } | |
561 } else if (strcmp(type, "bool") == 0) { | |
562 char value[256]; | |
563 if (sscanf(line, "%*[ \t]%255[a-zA-Z]%n", value, &bytes_read) == 1) { | |
564 if (strcmp(value, "true") == 0) { | |
565 total_bytes_read += bytes_read; | |
566 return add_option_string(c_name, c_match, m_name, m_match, signature, flag, true); | |
567 } else { | |
568 jio_snprintf(errorbuf, buf_size, " Value cannot be read for flag %s of type %s", flag, type); | |
569 } | |
570 } else { | |
571 jio_snprintf(errorbuf, sizeof(errorbuf), " Value cannot be read for flag %s of type %s", flag, type); | |
572 } | |
573 } else { | |
574 jio_snprintf(errorbuf, sizeof(errorbuf), " Type %s not supported ", type); | |
575 } | |
576 } else { | |
577 jio_snprintf(errorbuf, sizeof(errorbuf), " Flag name for type %s should be alphanumeric ", type); | |
578 } | |
579 return NULL; | |
580 } | |
581 | |
436 void CompilerOracle::parse_from_line(char* line) { | 582 void CompilerOracle::parse_from_line(char* line) { |
437 if (line[0] == '\0') return; | 583 if (line[0] == '\0') return; |
438 if (line[0] == '#') return; | 584 if (line[0] == '#') return; |
439 | 585 |
440 bool have_colon = (strstr(line, "::") != NULL); | 586 bool have_colon = (strstr(line, "::") != NULL); |
460 | 606 |
461 char* original_line = line; | 607 char* original_line = line; |
462 int bytes_read; | 608 int bytes_read; |
463 OracleCommand command = parse_command_name(line, &bytes_read); | 609 OracleCommand command = parse_command_name(line, &bytes_read); |
464 line += bytes_read; | 610 line += bytes_read; |
611 ResourceMark rm; | |
465 | 612 |
466 if (command == UnknownCommand) { | 613 if (command == UnknownCommand) { |
614 ttyLocker ttyl; | |
467 tty->print_cr("CompilerOracle: unrecognized line"); | 615 tty->print_cr("CompilerOracle: unrecognized line"); |
468 tty->print_cr(" \"%s\"", original_line); | 616 tty->print_cr(" \"%s\"", original_line); |
469 return; | 617 return; |
470 } | 618 } |
471 | 619 |
483 MethodMatcher::Mode m_match = MethodMatcher::Exact; | 631 MethodMatcher::Mode m_match = MethodMatcher::Exact; |
484 char class_name[256]; | 632 char class_name[256]; |
485 char method_name[256]; | 633 char method_name[256]; |
486 char sig[1024]; | 634 char sig[1024]; |
487 char errorbuf[1024]; | 635 char errorbuf[1024]; |
488 const char* error_msg = NULL; | 636 const char* error_msg = NULL; // description of first error that appears |
489 MethodMatcher* match = NULL; | 637 MethodMatcher* match = NULL; |
490 | 638 |
491 if (scan_line(line, class_name, &c_match, method_name, &m_match, &bytes_read, error_msg)) { | 639 if (scan_line(line, class_name, &c_match, method_name, &m_match, &bytes_read, error_msg)) { |
492 EXCEPTION_MARK; | 640 EXCEPTION_MARK; |
493 Symbol* c_name = SymbolTable::new_symbol(class_name, CHECK); | 641 Symbol* c_name = SymbolTable::new_symbol(class_name, CHECK); |
502 line += bytes_read; | 650 line += bytes_read; |
503 signature = SymbolTable::new_symbol(sig, CHECK); | 651 signature = SymbolTable::new_symbol(sig, CHECK); |
504 } | 652 } |
505 | 653 |
506 if (command == OptionCommand) { | 654 if (command == OptionCommand) { |
507 // Look for trailing options to support | 655 // Look for trailing options. |
508 // ciMethod::has_option("string") to control features in the | 656 // |
509 // compiler. Multiple options may follow the method name. | 657 // Two types of trailing options are |
510 char option[256]; | 658 // supported: |
659 // | |
660 // (1) CompileCommand=option,Klass::method,flag | |
661 // (2) CompileCommand=option,Klass::method,type,flag,value | |
662 // | |
663 // Type (1) is used to support ciMethod::has_option("someflag") | |
664 // (i.e., to check if a flag "someflag" is enabled for a method). | |
665 // | |
666 // Type (2) is used to support options with a value. Values can have the | |
667 // the following types: intx, uintx, bool, ccstr, and ccstrlist. Currently, | |
668 // values of type intx, uintx, and bool are supported. | |
669 // | |
670 // For future extensions: extend scan_flag_and_value() | |
671 char option[256]; // stores flag for Type (1) and type of Type (2) | |
511 while (sscanf(line, "%*[ \t]%255[a-zA-Z0-9]%n", option, &bytes_read) == 1) { | 672 while (sscanf(line, "%*[ \t]%255[a-zA-Z0-9]%n", option, &bytes_read) == 1) { |
512 if (match != NULL && !_quiet) { | 673 if (match != NULL && !_quiet) { |
513 // Print out the last match added | 674 // Print out the last match added |
675 ttyLocker ttyl; | |
514 tty->print("CompilerOracle: %s ", command_names[command]); | 676 tty->print("CompilerOracle: %s ", command_names[command]); |
515 match->print(); | 677 match->print(); |
516 } | 678 } |
517 match = add_option_string(c_name, c_match, m_name, m_match, signature, strdup(option)); | |
518 line += bytes_read; | 679 line += bytes_read; |
519 } | 680 |
681 if (strcmp(option, "intx") == 0 | |
682 || strcmp(option, "uintx") == 0 | |
683 || strcmp(option, "bool") == 0 | |
684 || strcmp(option, "ccstr") == 0 | |
685 || strcmp(option, "ccstrlist") == 0 | |
686 ) { | |
687 | |
688 // Type (2) option: parse flag name and value. | |
689 match = scan_flag_and_value(option, line, bytes_read, | |
690 c_name, c_match, m_name, m_match, signature, | |
691 errorbuf, sizeof(errorbuf)); | |
692 if (match == NULL) { | |
693 error_msg = errorbuf; | |
694 break; | |
695 } | |
696 line += bytes_read; | |
697 } else { | |
698 // Type (1) option | |
699 match = add_option_string(c_name, c_match, m_name, m_match, signature, option, true); | |
700 } | |
701 } // while( | |
520 } else { | 702 } else { |
521 bytes_read = 0; | 703 match = add_predicate(command, c_name, c_match, m_name, m_match, signature); |
522 sscanf(line, "%*[ \t]%n", &bytes_read); | 704 } |
523 if (line[bytes_read] != '\0') { | 705 } |
524 jio_snprintf(errorbuf, sizeof(errorbuf), " Unrecognized text after command: %s", line); | 706 |
525 error_msg = errorbuf; | 707 ttyLocker ttyl; |
526 } else { | 708 if (error_msg != NULL) { |
527 match = add_predicate(command, c_name, c_match, m_name, m_match, signature); | 709 // an error has happened |
528 } | |
529 } | |
530 } | |
531 | |
532 if (match != NULL) { | |
533 if (!_quiet) { | |
534 ResourceMark rm; | |
535 tty->print("CompilerOracle: %s ", command_names[command]); | |
536 match->print(); | |
537 } | |
538 } else { | |
539 tty->print_cr("CompilerOracle: unrecognized line"); | 710 tty->print_cr("CompilerOracle: unrecognized line"); |
540 tty->print_cr(" \"%s\"", original_line); | 711 tty->print_cr(" \"%s\"", original_line); |
541 if (error_msg != NULL) { | 712 if (error_msg != NULL) { |
542 tty->print_cr("%s", error_msg); | 713 tty->print_cr("%s", error_msg); |
714 } | |
715 } else { | |
716 // check for remaining characters | |
717 bytes_read = 0; | |
718 sscanf(line, "%*[ \t]%n", &bytes_read); | |
719 if (line[bytes_read] != '\0') { | |
720 tty->print_cr("CompilerOracle: unrecognized line"); | |
721 tty->print_cr(" \"%s\"", original_line); | |
722 tty->print_cr(" Unrecognized text %s after command ", line); | |
723 } else if (match != NULL && !_quiet) { | |
724 tty->print("CompilerOracle: %s ", command_names[command]); | |
725 match->print(); | |
543 } | 726 } |
544 } | 727 } |
545 } | 728 } |
546 | 729 |
547 static const char* default_cc_file = ".hotspot_compiler"; | 730 static const char* default_cc_file = ".hotspot_compiler"; |