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";